Explode a bug when it crashes into the player. When the last segment collides with the player, go onto the next level.

This commit is contained in:
Jeremy Rand 2020-11-18 23:36:01 -05:00
parent 7d64340b5d
commit fd40c12d31
9 changed files with 184 additions and 38 deletions

17
BUGS.md Normal file
View File

@ -0,0 +1,17 @@
BUGS
=======
This is a list of the software bugs (as opposed to the bugs in the game that you shoot) that still need attention:
* When a centipede segment is added on the right, if there is a mushroom either right at the edge or maybe on tile from the edge (not sure which), the segment seems to turn around and travel up along the edge of the screen. Not sure if this can happen on the left side also. This is likely a problem with the mushroom collision detection and a segment which is mostly off-screen should probably ignore blocking mushrooms until on-screen.
* Sometimes centipede segments seem to be stacked one on top of another. You think there is just one left but you shoot it and there is one underneath it. This should not happen.
* A spider moving left to right went off screen and left garbage on the RHS as it exited. I have only seen this once. I think it coincided with the player dying.
* Sometimes when the player dies, the "you can shoot" indicator is left behind as garbage on-screen.
* I have seen a couple of crashes. I think an off-screen centipede segment is getting "shot" at the beginning of a level leading to a crash. Almost definitely related to collision and shot handling.
* I am seeing other crashes where the PC ends up in bank 22 or so. Need to dig into the stack to figure out where it is coming from.
FIXED
=======
* A shot is able to pass through an almost gone mushroom if lined up just right. Best to change the sprite code for the shot to scan the two pixels below for a collision.

View File

@ -78,9 +78,10 @@
9D33970024AEFBF2003222B3 /* segments.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = segments.s; sourceTree = "<group>"; }; 9D33970024AEFBF2003222B3 /* segments.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = segments.s; sourceTree = "<group>"; };
9D33970124AF9D55003222B3 /* sprites.macros */ = {isa = PBXFileReference; lastKnownFileType = text; path = sprites.macros; sourceTree = "<group>"; }; 9D33970124AF9D55003222B3 /* sprites.macros */ = {isa = PBXFileReference; lastKnownFileType = text; path = sprites.macros; sourceTree = "<group>"; };
9D47CBE02547BEDB00CDA5CB /* gameMushroom.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = gameMushroom.s; sourceTree = "<group>"; }; 9D47CBE02547BEDB00CDA5CB /* gameMushroom.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = gameMushroom.s; sourceTree = "<group>"; };
9D47CC14254A698900CDA5CB /* gamePlayer.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = gamePlayer.s; sourceTree = "<group>"; }; 9D47CC14254A698900CDA5CB /* gamePlayer.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = gamePlayer.s; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.asm.orcam; };
9D47CCBA25525C1A00CDA5CB /* tileData.pl */ = {isa = PBXFileReference; lastKnownFileType = text.script.perl; path = tileData.pl; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.perl; }; 9D47CCBA25525C1A00CDA5CB /* tileData.pl */ = {isa = PBXFileReference; lastKnownFileType = text.script.perl; path = tileData.pl; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.perl; };
9D53E5B32562320300E10169 /* gameShot.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = gameShot.s; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.asm.orcam; }; 9D53E5B32562320300E10169 /* gameShot.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = gameShot.s; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.asm.orcam; };
9D53E6472565939300E10169 /* BUGS.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = BUGS.md; sourceTree = "<group>"; };
9D62AF3B249871A300348F45 /* colour.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = colour.s; sourceTree = "<group>"; }; 9D62AF3B249871A300348F45 /* colour.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = colour.s; sourceTree = "<group>"; };
9D62AF3F2499CD1E00348F45 /* LICENSE */ = {isa = PBXFileReference; lastKnownFileType = text; path = LICENSE; sourceTree = "<group>"; }; 9D62AF3F2499CD1E00348F45 /* LICENSE */ = {isa = PBXFileReference; lastKnownFileType = text; path = LICENSE; sourceTree = "<group>"; };
9D62AF402499CD3A00348F45 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; }; 9D62AF402499CD3A00348F45 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; };
@ -116,6 +117,7 @@
9D62AF3F2499CD1E00348F45 /* LICENSE */, 9D62AF3F2499CD1E00348F45 /* LICENSE */,
9D62AF402499CD3A00348F45 /* README.md */, 9D62AF402499CD3A00348F45 /* README.md */,
9D9F07F92553AB3800875B29 /* TODO.md */, 9D9F07F92553AB3800875B29 /* TODO.md */,
9D53E6472565939300E10169 /* BUGS.md */,
9D17168D2491C49300C83148 /* BuGS */, 9D17168D2491C49300C83148 /* BuGS */,
9D1716852491C49300C83148 /* Products */, 9D1716852491C49300C83148 /* Products */,
); );

View File

@ -206,8 +206,15 @@ nextWord anop
cli cli
rtl rtl
; The accumulator has a 0 in it when starting a one player game, 1 when
; starting a two player game.
startGame entry startGame entry
ldx gameRunning
bne startGame_notRunning
rtl
startGame_notRunning anop
stz gameRunning stz gameRunning
jsl addRandomMushrooms jsl addRandomMushrooms
jsl scoreStartGame jsl scoreStartGame
@ -225,6 +232,11 @@ startLevel entry
jmp levelStart jmp levelStart
pauseGame entry
; TODO - Write this code...
rtl
gameOver entry gameOver entry
lda #1 lda #1
sta gameRunning sta gameRunning
@ -262,20 +274,33 @@ checkKey_loop2 anop
beq checkKey_quit beq checkKey_quit
cmp #'Q' cmp #'Q'
beq checkKey_quit beq checkKey_quit
cmp #'p'
beq checkKey_pause
cmp #'P'
beq checkKey_pause
cmp #$001b cmp #$001b
beq checkKey_quit beq checkKey_pause
cmp #'g' cmp #'1'
beq checkKey_game
cmp #'2'
beq checkKey_game beq checkKey_game
checkKey_done anop checkKey_done anop
rtl rtl
checkKey_pause anop
jmp pauseGame
checkKey_quit anop checkKey_quit anop
stz shouldQuit stz shouldQuit
rtl rtl
checkKey_game anop checkKey_game anop
sec
sbc #'1'
jmp startGame jmp startGame

View File

@ -70,6 +70,9 @@ updateFlea entry
lda playerState lda playerState
cmp #PLAYER_STATE_ONSCREEN cmp #PLAYER_STATE_ONSCREEN
beq updateFlea_playerOnscreen beq updateFlea_playerOnscreen
lda fleaState
cmp #FLEA_STATE_EXPLODING
beq updateFlea_playerOnscreen
rtl rtl
updateFlea_playerOnscreen anop updateFlea_playerOnscreen anop
@ -284,11 +287,7 @@ shootFlea entry
cmp #FLEA_SCREEN_SPEED_SLOW cmp #FLEA_SCREEN_SPEED_SLOW
beq shootFlea_faster beq shootFlea_faster
lda #FLEA_STATE_EXPLODING jsl explodeFlea
sta fleaState
lda #EXPLOSION_LAST_OFFSET
sta fleaSprite
jmp scoreAddTwoHundred jmp scoreAddTwoHundred
@ -307,7 +306,16 @@ shootFlea_faster anop
shootFlea_done anop shootFlea_done anop
rtl rtl
explodeFlea entry
lda #FLEA_STATE_EXPLODING
sta fleaState
lda #EXPLOSION_LAST_OFFSET
sta fleaSprite
rtl
fleaState dc i2'FLEA_STATE_NONE' fleaState dc i2'FLEA_STATE_NONE'
fleaScreenOffset dc i2'0' fleaScreenOffset dc i2'0'

View File

@ -84,6 +84,10 @@ updatePlayer_gameRunning anop
bne updatePlayer_wait bne updatePlayer_wait
lda numLives lda numLives
beq updatePlayer_gameOver beq updatePlayer_gameOver
lda numSegments
bne updatePlayer_notNextLevel
jsl levelNext
updatePlayer_notNextLevel anop
jmp startLevel jmp startLevel
updatePlayer_gameOver anop updatePlayer_gameOver anop
jmp gameOver jmp gameOver
@ -264,9 +268,36 @@ updatePlayer_shift anop
bra updatePlayer_dirty bra updatePlayer_dirty
updatePlayer_dirty anop updatePlayer_dirty anop
beq updatePlayer_noCollision bne updatePlayer_collision
jmp updatePlayer_noCollision
updatePlayer_collision anop
lda #PLAYER_STATE_EXPLODING lda #PLAYER_STATE_EXPLODING
sta playerState sta playerState
; Figure out which kind of bug collided with the player and cause it to
; explode.
txa
sec
sbc #SCREEN_ADDRESS
and #$fffc
tax
lda >screenToTileOffset,x
jsl isSpiderCollision
bcc updatePlayer_notSpiderCollision
jsl explodeSpider
bra updatePlayer_explode
updatePlayer_notSpiderCollision anop
jsl isFleaCollision
bcc updatePlayer_notFleaCollision
jsl explodeFlea
bra updatePlayer_explode
updatePlayer_notFleaCollision anop
jsl isSegmentCollision
bcc updatePlayer_explode
jsl explodeSegment
updatePlayer_explode anop
lda mouseAddress lda mouseAddress
sec sec
sbc #TILE_BYTE_WIDTH/2 sbc #TILE_BYTE_WIDTH/2

View File

@ -193,7 +193,28 @@ updateSegments entry
lda playerState lda playerState
cmp #PLAYER_STATE_ONSCREEN cmp #PLAYER_STATE_ONSCREEN
beq updateSegments_playerOnscreen beq updateSegments_playerOnscreen
; Even when the player is offscreen, we need to update any segments which are exploding
ldx #SEGMENT_MAX_OFFSET
updateSegments_explodeOnlyLoop anop
lda segmentStates,x
cmp #SEGMENT_STATE_EXPLODING
bne updateSegments_explodeOnlyNext
ldy segmentPosOffset,x
lda segmentFacing,y
beq updateSegments_explodeOnlyDone
sec
sbc #$4
sta segmentFacing,y
bra updateSegments_explodeOnlyNext
updateSegments_explodeOnlyDone anop
lda #SEGMENT_STATE_NONE
sta segmentStates,x
updateSegments_explodeOnlyNext anop
dex
dex
bpl updateSegments_explodeOnlyLoop
rtl rtl
updateSegments_playerOnscreen anop updateSegments_playerOnscreen anop
; Clear the segment mask to start. ; Clear the segment mask to start.
stz segmentTileMask+0 stz segmentTileMask+0
@ -1719,7 +1740,7 @@ isSegmentCollision_returnTrue anop
; Call this with the segment num * 2 in the X register ; Call this with the segment num * 2 in the X register
shootSegment entry shootSegment entry
dec numSegments jsl explodeSegment
phx phx
lda segmentStates,x lda segmentStates,x
cmp #SEGMENT_STATE_BODY cmp #SEGMENT_STATE_BODY
@ -1730,17 +1751,11 @@ shootSegment_body anop
jsl scoreAddTen jsl scoreAddTen
shootSegment_doneScore anop shootSegment_doneScore anop
plx plx
lda #SEGMENT_STATE_EXPLODING
sta segmentStates,x
ldy segmentPosOffset,x ldy segmentPosOffset,x
; We take over the segmentFacing value when exploding to be an explosion sprite offset
lda #EXPLOSION_LAST_OFFSET
sta segmentFacing,y
lda segmentCurrentTile,y lda segmentCurrentTile,y
cmp #(NUM_GAME_TILES-GAME_NUM_TILES_WIDE)*SIZEOF_TILE_INFO cmp #(NUM_GAME_TILES-GAME_NUM_TILES_WIDE)*SIZEOF_TILE_INFO
bge shootSegment_skipMushroom bge shootSegment_done
tay tay
lda tileType,y lda tileType,y
beq shootSegment_noMushroom beq shootSegment_noMushroom
@ -1758,18 +1773,32 @@ shootSegment_dirtyTile anop
sta tileType,y sta tileType,y
lda #TILE_STATE_DIRTY lda #TILE_STATE_DIRTY
sta tileDirty,y sta tileDirty,y
shootSegment_skipMushroom anop shootSegment_done anop
rtl
; Call this with the segment num * 2 in the X register
explodeSegment entry
dec numSegments
lda #SEGMENT_STATE_EXPLODING
sta segmentStates,x
ldy segmentPosOffset,x
; We take over the segmentFacing value when exploding to be an explosion sprite offset
lda #EXPLOSION_LAST_OFFSET
sta segmentFacing,y
; If this is the last segment, then do not look for a following body segment ; If this is the last segment, then do not look for a following body segment
cpx #22 cpx #22
bge shootSegment_done bge shootSegment_done
; If the segment after this is a body segment, then it is now a head segment ; If the segment after this is a body segment, then it is now a head segment
lda segmentStates+2,x lda segmentStates+2,x
cmp #SEGMENT_STATE_BODY cmp #SEGMENT_STATE_BODY
bne shootSegment_done bne explodeSegment_done
lda #SEGMENT_STATE_HEAD lda #SEGMENT_STATE_HEAD
sta segmentStates+2,x sta segmentStates+2,x
shootSegment_done anop explodeSegment_done anop
rtl rtl
segmentsAddEnabled dc i2'1' segmentsAddEnabled dc i2'1'

View File

@ -42,9 +42,10 @@ SPIDER_SPRITE_REFRESH_COUNT equ 4
SPIDER_SCORE_NUM_FRAMES equ 120 SPIDER_SCORE_NUM_FRAMES equ 120
SPIDER_SCORE_300 equ 0 SPIDER_SCORE_300 equ 0
SPIDER_SCORE_600 equ 4 SPIDER_SCORE_600 equ 4
SPIDER_SCORE_900 equ 8 SPIDER_SCORE_900 equ 8
SPIDER_SCORE_NONE equ $ffff
SPIDER_VERT_SPEED_SLOW equ SCREEN_BYTES_PER_ROW SPIDER_VERT_SPEED_SLOW equ SCREEN_BYTES_PER_ROW
SPIDER_VERT_SPEED_FAST equ SCREEN_BYTES_PER_ROW*2 SPIDER_VERT_SPEED_FAST equ SCREEN_BYTES_PER_ROW*2
@ -141,6 +142,9 @@ updateSpider entry
lda playerState lda playerState
cmp #PLAYER_STATE_ONSCREEN cmp #PLAYER_STATE_ONSCREEN
beq updateSpider_cont beq updateSpider_cont
ldx spiderState
cmp #SPIDER_STATE_EXPLODING
beq updateSpider_testState
rtl rtl
updateSpider_cont anop updateSpider_cont anop
ldx spiderState ldx spiderState
@ -182,6 +186,10 @@ updateSpider_exploding anop
rtl rtl
updateSpider_explosionDone anop updateSpider_explosionDone anop
lda spiderScoreType
bmi updateSpider_scoreDone
updateSpider_explosionShowScore anop
lda #SPIDER_STATE_SCORE lda #SPIDER_STATE_SCORE
sta spiderState sta spiderState
@ -802,15 +810,7 @@ shootSpider entry
cmp #SPIDER_STATE_LEFT_DIAG_DOWN cmp #SPIDER_STATE_LEFT_DIAG_DOWN
blt shootSpider_done blt shootSpider_done
lda #SPIDER_STATE_EXPLODING jsl explodeSpider
sta spiderState
lda #EXPLOSION_LAST_OFFSET
sta spiderSprite
lda spiderScreenOffset
inc a
sta spiderScreenOffset
cmp mouseAddress cmp mouseAddress
blt shootSpider_playerBelow blt shootSpider_playerBelow
sec sec
@ -843,7 +843,27 @@ shootSpider_900 anop
shootSpider_done anop shootSpider_done anop
rtl rtl
explodeSpider entry
lda #SPIDER_SCORE_NONE
sta spiderScoreType
lda spiderState
cmp #SPIDER_STATE_LEFT_DIAG_DOWN
blt explodeSpider_done
lda #SPIDER_STATE_EXPLODING
sta spiderState
lda #EXPLOSION_LAST_OFFSET
sta spiderSprite
lda spiderScreenOffset
inc a
sta spiderScreenOffset
explodeSpider_done anop
rtl
spiderState dc i2'SPIDER_STATE_NONE' spiderState dc i2'SPIDER_STATE_NONE'
spiderSpeed dc i2'SPRITE_SPEED_SLOW' spiderSpeed dc i2'SPRITE_SPEED_SLOW'

View File

@ -94,6 +94,8 @@ drawShot entry
; .R.. ; .R..
; .R.. ; .R..
; .R.. ; .R..
; ....
; ....
stz collision stz collision
@ -161,6 +163,8 @@ drawShotShift entry
; R... ; R...
; R... ; R...
; R... ; R...
; ....
; ....
stz collision stz collision
@ -207,6 +211,16 @@ drawShotShift entry
and #$ff0f and #$ff0f
ora #$0040 ora #$0040
sta $a0,s sta $a0,s
tsc
adc #$140
tcs
lda $0,s
_collision #$00f0,#$0
lda $a0,s
_collision #$00f0,#$a0
_spriteFooter _spriteFooter

View File

@ -1,9 +1,9 @@
TODO TODO
======= =======
* When a centipede segment is added on the right, if there is a mushroom either right at the edge or maybe on tile from the edge (not sure which), the segment seems to turn around and travel up along the edge of the screen. Not sure if this can happen on the left side also. This is likely a problem with the mushroom collision detection and a segment which is mostly off-screen should probably ignore blocking mushrooms until on-screen.
* At the end of the game, the score should be compared to the high score. If larger, store the high score. * At the end of the game, the score should be compared to the high score. If larger, store the high score.
* When a collision is detected with the player, the thing collided with should explode. That also means that the bugs in general do not update when the player has died, unless they are exploding in which case they do.
* When the player dies, the mushrooms need to be reset and the score incremented for damaged and poisoned mushrooms. * When the player dies, the mushrooms need to be reset and the score incremented for damaged and poisoned mushrooms.
* Implement the code to support pausing the game
* Implement the code for supporting a two player game
* So much more. * So much more.
* Why is there no sound? Because I haven't coded any... * Why is there no sound? Because I haven't coded any...