Author Topic: Interesting Collision Detection problem  (Read 3774 times)

0 Members and 1 Guest are viewing this topic.

Offline Hot_Dog

  • CoT Emeritus
  • LV12 Extreme Poster (Next: 5000)
  • *
  • Posts: 3006
  • Rating: +445/-10
    • View Profile
Interesting Collision Detection problem
« on: October 29, 2011, 07:29:33 pm »
In the game Gemini (and thus Elimination as well), every enemy has an X position and a Y position.  I'm pretty sure that the X position and Y position are governed by the left side of the enemy when you are facing it.  In other words, if an enemy is at X = 1200 and Y = 1300 in one possible situation, this is the left of the enemy, and the middle of the enemy will be at approximately X = 1215 and Y = 1315 in some cases.

Also, every enemy position takes two bytes.  If the X position is stored in HL, H will contain the tile from a row of 32 tiles, and L will contain the location to the nearest 1/256 of that particular tile.  If the Y position is stored in HL, H will contain the tile from a COLUMN of 32 tiles, and so on.

Collision detection in Gemini checks the X and Y position to see if the tile an enemy is on is occupied by a wall.  Register B contains the tile number out of the 32 tiles in a row, and register C contains the tile number of 32 tiles in a column.  If C * 32 + B points to a tile that is occupied by a wall, the enemy is told not to move to that direction, and a new direction is calculated.

So here's my problem.  Registers B and C will, like I said at the top, pertain to the LEFT of the sprite.  So the left side of the sprite never, ever runs into a wall.  However, the right side often does.  Considering the code below, what's a good way to fix that?

EDIT: Part of my problem is the enemy always faces toward you, no matter at what angle you are facing in the map.

Code: [Select]
objectsEnemyCalm:

; --------------------- ;
; Update enemy movement ;
; --------------------- ;

ld hl, (object)
ld de, 14
add hl, de
ld a, (hl) ;This is how many units the enemy will move in the current direction
or a
jr nz, objectsEnemyMove

dec hl
ld a, r
srl a
srl a
ld (hl), a ;Store a direction, from 1 - 32
inc hl
ld a, r
srl a
srl a
ld (hl), a ;Store how many units the enemy will move in the direction

objectsEnemyMove:

dec (hl)
dec hl
ld a, (hl)

; Get trigs
ld hl, movtbl
ld b, 0
ld c, a
add hl, bc
ld e, (hl)
ld c, 8
add hl, bc
ld d, (hl)

; Speed depends on enemy
ld hl, (object)
ld a, (hl)
and %00111111
or a
jr z, objectsHandgunSpeed
dec a
jr z, objectsShotgunSpeed
dec a
jr z, objectsChaingunSpeed

; Plasma-rifle enemy, move swiftly
jp objectsSpeedDone

objectsHandgunSpeed:
sra d
sra e
jp objectsSpeedDone

objectsShotgunSpeed:
sra d
sra e
jp objectsSpeedDone

objectsChaingunSpeed:
sra d
sra e
sra d
sra e

objectsSpeedDone:

; New X
ld bc, (objectX)

ld h, 0
ld l, d
ld a, l
and $80
jr z, objectsPosCos
dec h

objectsPosCos:

add hl, bc
ld (ox), hl

; New Y
ld bc, (objectY)

ld h, 0
ld l, e
ld a, l
and $80
jr z, objectsPosSin
dec h

objectsPosSin:

add hl, bc
ld (oy), hl

ld a, (ox + 1)
ld b, a
ld a, (oy + 1)
ld c, a
call checkLevel
or a
jr nz, objectsEnemyWalkingWall


;;;CODE IS MISSING FROM HERE.  IT JUST SAYS "YES, THERE'S NO WALL, MOVE THE ENEMY."

objectsEnemyWalkingWall:

; Enemy was walking into a wall, new direction
ld hl, (object)
ld bc, 14
add hl, bc
xor a
ld (hl), a
jp objectsEnemyLocation

;;;;CODE IS MISSING FROM HERE, IT'S IRRELEVANT CODE.


; ========================== ;
; Check cell of level (b, c) ;
; ========================== ;
checkLevel:

ld a, b
ld b, 0
sla c
sla c
sla c
sla c
rl b
sla c
rl b
ld hl, level
add hl, bc
ld b, 0
ld c, a
add hl, bc
ld a, (hl)

ret


movtbl:
.db 0, 6, 12, 17, 22, 26, 29, 31, 32, 31, 29, 26, 22, 17, 12, 6
.db 0, -6, -12, -17, -22, -26, -29, -31, -32, -31, -29, -26, -22, -17, -12, -6
.db 0, 6, 12, 17, 22, 26, 29, 31,
« Last Edit: October 29, 2011, 07:53:45 pm by Hot_Dog »