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.
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,