Fix a bug where it was possible for the player to collide with an exploding bug and then die. Change explosions so they are drawn using background colours which do not result in player collisions.

This commit is contained in:
Jeremy Rand 2021-01-18 00:18:31 -05:00
parent 678a9ee104
commit 1b7d2e240b
6 changed files with 172 additions and 163 deletions

View File

@ -4,12 +4,16 @@ BUGS
This is a list of the software bugs (as opposed to the bugs in the game that you shoot) that still need attention: This is a list of the software bugs (as opposed to the bugs in the game that you shoot) that still need attention:
* The sound is muddy at times on real HW. Especially when lots of stuff is going on, the sound ends up coming out garbled. This isn't happening on emulators where everything is always quite clear. Perhaps I am reaching some limit of the Ensoniq. Do I need to reduce some sampling frequencies perhaps? * The sound is muddy at times on real HW. Especially when lots of stuff is going on, the sound ends up coming out garbled. This isn't happening on emulators where everything is always quite clear. Perhaps I am reaching some limit of the Ensoniq. Do I need to reduce some sampling frequencies perhaps?
* It seems to be possible to both shoot and be killed by the spider in a single frame. Either the spider should be killed by the shot or the spider should kill the player but not both. * I tried reducing the sampling frequency from 11025 for most of the samples to 5513 and I didn't notice any improvement in the quality of the sound on real HW. Nor did I notice any real degredation on real HW or on an emulator.
FIXED FIXED
======= =======
* It seems to be possible to both shoot and be killed by the spider in a single frame. Either the spider should be killed by the shot or the spider should kill the player but not both.
* Based on the code, I don't think it is possible that this happened in a single frame. Instead, I think what is happening is that the spider is being shot and then goes through a small number of explosion frames. The colour used in those explosion frames were detected as a collision to the player.
* I have changed the colours of the explosion to no longer be detected as a collision for the player.
* It is possible to shoot between two segments of a centipede. The problem is that there are black pixels between the segments and if things are timed just right (or just wrong), the shot can slot in at those black pixels and end up missing both segments. * It is possible to shoot between two segments of a centipede. The problem is that there are black pixels between the segments and if things are timed just right (or just wrong), the shot can slot in at those black pixels and end up missing both segments.
* I am not sure how much can be done about this given how collisions are detected. * I am not sure how much can be done about this given how collisions are detected.
* I have implemented a fix which I believe solves this problem. The shot is a single pixel wide which allows it to slot in between a segment. I have changed the collision code to detect a collision if it is also if there is any pixel on in the byte (ie two pixels wide). That should ensure that the shot cannot pass through a centipede. Note it also makes things slightly easier to hit where before it might have passed right next to. * I have implemented a fix which I believe solves this problem. The shot is a single pixel wide which allows it to slot in between a segment. I have changed the collision code to detect a collision if it is also if there is any pixel on in the byte (ie two pixels wide). That should ensure that the shot cannot pass through a centipede. Note it also makes things slightly easier to hit where before it might have passed right next to.

View File

@ -57,12 +57,8 @@ initPlayer_loop2 anop
bne initPlayer_loop2 bne initPlayer_loop2
initPlayer_done anop initPlayer_done anop
jmp playerSwitch jmp scoreSwitchPlayer
playerSwitch entry
jsl scoreSwitchPlayer
rtl
playerLevelStart entry playerLevelStart entry
stz playerIgnoreFirstPoll stz playerIgnoreFirstPoll

View File

@ -149,8 +149,8 @@ updateShot_collision anop
bge updateShot_onScreen bge updateShot_onScreen
rtl rtl
updateShot_onScreen anop updateShot_onScreen anop
and #$3333 and #$cccc
bne updateShot_maybeMushroom beq updateShot_maybeMushroom
txy txy
txa txa

View File

@ -16,9 +16,9 @@ explosions start spriteSeg
explosion1 entry explosion1 entry
_spriteHeader _spriteHeader
; $c - Green ; $1 - Green (c)
; $4 - Red ; $2 - Red (4)
; $8 - Off-white ; $3 - Off-white (8)
; ;
; ..RR|.R.. ; ..RR|.R..
; .OGR|G... ; .OGR|G...
@ -32,22 +32,22 @@ explosion1 entry
lda $0,s lda $0,s
and #$00ff and #$00ff
ora #$4400 ora #$2200
sta $0,s sta $0,s
lda $2,s lda $2,s
and #$fff0 and #$fff0
ora #$0004 ora #$0002
sta $2,s sta $2,s
lda $a0,s lda $a0,s
and #$00f0 and #$00f0
ora #$c408 ora #$1203
sta $a0,s sta $a0,s
lda $a2,s lda $a2,s
; and #$ff0f not necessary with pure green and #$ff0f
ora #$00c0 ora #$0010
sta $a2,s sta $a2,s
tsc tsc
@ -55,22 +55,21 @@ explosion1 entry
tcs tcs
lda $0,s lda $0,s
; and #$ff0f not necessary with pure green and #$ff0f
ora #$cc0c ora #$1101
sta $0,s sta $0,s
lda $2,s lda $2,s
and #$0f00 and #$0f00
ora #$40cc ora #$2011
sta $2,s sta $2,s
lda #$1121
lda #$cc4c
sta $a0,s sta $a0,s
lda $a2,s lda $a2,s
and #$0f00 and #$0f00
ora #$80cc ora #$3011
sta $a2,s sta $a2,s
tsc tsc
@ -79,18 +78,18 @@ explosion1 entry
lda $0,s lda $0,s
and #$0f00 and #$0f00
ora #$c04c ora #$1021
sta $0,s sta $0,s
lda $2,s lda $2,s
; and #$fff0 not necessary with pure green and #$fff0
ora #$c0cc ora #$1011
sta $2,s sta $2,s
lda #$cc8c lda #$1131
sta $a0,s sta $a0,s
lda #$8ccc lda #$3111
sta $a0,s sta $a0,s
tsc tsc
@ -99,22 +98,22 @@ explosion1 entry
lda $0,s lda $0,s
and #$00f0 and #$00f0
ora #$cc08 ora #$1103
sta $0,s sta $0,s
lda $2,s lda $2,s
and #$0f00 and #$0f00
ora #$804c ora #$3021
sta $2,s sta $2,s
lda $a0,s lda $a0,s
and #$00f0 and #$00f0
ora #$8404 ora #$3202
sta $a0,s sta $a0,s
lda $a2,s lda $a2,s
and #$f0f0 and #$f0f0
ora #$0c04 ora #$0102
sta $a2,s sta $a2,s
_spriteFooter _spriteFooter
@ -124,9 +123,9 @@ explosion1 entry
explosion2 entry explosion2 entry
_spriteHeader _spriteHeader
; $c - Green ; $1 - Green
; $4 - Red ; $2 - Red
; $8 - Off-white ; $3 - Off-white
; ;
; ..GR|G.R. ; ..GR|G.R.
; .GGG|GGRG ; .GGG|GGRG
@ -140,61 +139,61 @@ explosion2 entry
lda $0,s lda $0,s
and #$00ff and #$00ff
ora #$c400 ora #$1200
sta $0,s sta $0,s
lda $2,s lda $2,s
and #$0f0f and #$0f0f
ora #$40c0 ora #$2010
sta $2,s sta $2,s
lda $a0,s lda $a0,s
; and #$00f0 not necessary with pure green and #$00f0
ora #$cc0c ora #$1101
sta $a0,s sta $a0,s
lda #$4ccc lda #$2111
sta $a2,s sta $a2,s
tsc tsc
adc #$143 adc #$143
tcs tcs
pea $c8cc pea $1311
pea $cc8c pea $1131
adc #$a0 adc #$a0
tcs tcs
pea $cc8c pea $1131
pea $c88c pea $1331
adc #$a0 adc #$a0
tcs tcs
pea $c88c pea $1331
pea $c88c pea $1331
adc #$a0 adc #$a0
tcs tcs
pea $cccc pea $1111
pea $cc8c pea $1131
adc #$a0 adc #$a0
tcs tcs
pea $c8cc pea $1311
pea $c48c pea $1231
lda $a1,s lda $a1,s
and #$f0f0 and #$f0f0
ora #$040c ora #$0201
sta $a1,s sta $a1,s
lda $a3,s lda $a3,s
; and #$f0f0 not necessary for pure green and #$f0f0
ora #$000c ora #$0001
sta $a3,s sta $a3,s
_spriteFooter _spriteFooter
@ -204,9 +203,9 @@ explosion2 entry
explosion3 entry explosion3 entry
_spriteHeader _spriteHeader
; $c - Green ; $1 - Green
; $4 - Red ; $2 - Red
; $8 - Off-white ; $3 - Off-white
; ;
; .GOG|RG.. ; .GOG|RG..
; G.GG|GGGR ; G.GG|GGGR
@ -219,43 +218,43 @@ explosion3 entry
lda $0,s lda $0,s
and #$00f0 and #$00f0
ora #$8c0c ora #$3101
sta $0,s sta $0,s
lda $2,s lda $2,s
and #$ff00 and #$ff00
ora #$004c ora #$0021
sta $2,s sta $2,s
lda $a0,s lda $a0,s
; and #$000f not necessary with pure green and #$000f
ora #$ccc0 ora #$1110
sta $a0,s sta $a0,s
lda #$c4cc lda #$1211
sta $a2,s sta $a2,s
tsc tsc
adc #$140 adc #$140
tcs tcs
lda #$c8cc lda #$1311
sta $0,s sta $0,s
lda $2,s lda $2,s
and #$0f00 and #$0f00
ora #$c0c8 ora #$1013
sta $2,s sta $2,s
lda $a0,s lda $a0,s
and #$0f00 and #$0f00
ora #$804c ora #$3021
sta $a0,s sta $a0,s
lda $a2,s lda $a2,s
; and #$00f0 not necessary with pure green and #$00f0
ora #$cc0c ora #$1101
sta $a2,s sta $a2,s
tsc tsc
@ -263,41 +262,41 @@ explosion3 entry
tcs tcs
lda $0,s lda $0,s
; and #$ff00 not necessary with pure green and #$ff00
ora #$00cc ora #$0011
sta $0,s sta $0,s
lda $2,s lda $2,s
; and #$fff0 not necessary with pure green and #$fff0
ora #$000c ora #$0001
sta $2,s sta $2,s
lda #$4cc4 lda #$2112
sta $a0,s sta $a0,s
lda #$cc4c lda #$1121
sta $a2,s sta $a2,s
tsc tsc
adc #$140 adc #$140
tcs tcs
lda #$cc4c lda #$1121
sta $0,s sta $0,s
lda $2,s lda $2,s
; and #$0f00 not necessary with pure green and #$0f00
ora #$c0cc ora #$1011
sta $2,s sta $2,s
lda $a0,s lda $a0,s
and #$0ff0 and #$0ff0
ora #$c008 ora #$1003
sta $a0,s sta $a0,s
lda $a2,s lda $a2,s
and #$f0f0 and #$f0f0
ora #$080c ora #$0301
sta $a2,s sta $a2,s
_spriteFooter _spriteFooter
@ -323,22 +322,22 @@ explosion4 entry
lda $0,s lda $0,s
and #$000f and #$000f
ora #$c8c0 ora #$1310
sta $0,s sta $0,s
lda $2,s lda $2,s
and #$f0f0 and #$f0f0
ora #$0c04 ora #$0102
sta $2,s sta $2,s
lda $a0,s lda $a0,s
and #$f0f0 and #$f0f0
ora #$0c08 ora #$0103
sta $a0,s sta $a0,s
lda $a2,s lda $a2,s
; and #$0f0f not necessary with pure green and #$0f0f
ora #$c0c0 ora #$1010
sta $a2,s sta $a2,s
tsc tsc
@ -347,22 +346,22 @@ explosion4 entry
lda $0,s lda $0,s
and #$f000 and #$f000
ora #$044c ora #$0221
sta $0,s sta $0,s
lda $2,s lda $2,s
and #$f0f0 and #$f0f0
ora #$0408 ora #$0203
sta $2,s sta $2,s
lda $a0,s lda $a0,s
and #$0f0f and #$0f0f
ora #$40c0 ora #$2010
sta $a0,s sta $a0,s
lda $a2,s lda $a2,s
; and #$0fff not necessary with pure green and #$0fff
ora #$c000 ora #$1000
sta $a2,s sta $a2,s
tsc tsc
@ -370,23 +369,23 @@ explosion4 entry
tcs tcs
lda $0,s lda $0,s
; and #$ff00 not necessary with pure green and #$ff00
ora #$00cc ora #$0011
sta $0,s sta $0,s
lda $2,s lda $2,s
and #$f0ff and #$f0ff
ora #$0800 ora #$0300
sta $2,s sta $2,s
lda $a0,s lda $a0,s
and #$f0f0 and #$f0f0
ora #$0404 ora #$0202
sta $a0,s sta $a0,s
lda $a2,s lda $a2,s
and #$00f0 and #$00f0
ora #$c804 ora #$1302
sta $a2,s sta $a2,s
tsc tsc
@ -395,22 +394,22 @@ explosion4 entry
lda $0,s lda $0,s
and #$0f0f and #$0f0f
ora #$4080 ora #$2030
sta $0,s sta $0,s
lda $2,s lda $2,s
and #$000f and #$000f
ora #$c440 ora #$1220
sta $2,s sta $2,s
lda $a0,s lda $a0,s
and #$f000 and #$f000
ora #$0c4c ora #$0121
sta $a0,s sta $a0,s
lda $a2,s lda $a2,s
and #$0f00 and #$0f00
ora #$80cc ora #$3011
sta $a2,s sta $a2,s
_spriteFooter _spriteFooter
@ -435,23 +434,23 @@ explosion5 entry
; ;
lda $0,s lda $0,s
; and #$000f not necessary with pure green and #$000f
ora #$000c ora #$0001
sta $0,s sta $0,s
lda $2,s lda $2,s
; and #$f0f0 not necessary with pure green and #$f0f0
ora #$c0c0 ora #$1010
sta $2,s sta $2,s
lda $a0,s lda $a0,s
and #$00f0 and #$00f0
ora #$8c04 ora #$3102
sta $a0,s sta $a0,s
lda $a2,s lda $a2,s
and #$0ff0 and #$0ff0
ora #$c004 ora #$1002
sta $a2,s sta $a2,s
tsc tsc
@ -460,22 +459,22 @@ explosion5 entry
lda $0,s lda $0,s
and #$ff00 and #$ff00
ora #$00c8 ora #$0013
sta $0,s sta $0,s
lda $2,s lda $2,s
and #$f00f and #$f00f
ora #$08c0 ora #$0310
sta $2,s sta $2,s
lda $a0,s lda $a0,s
and #$fff0 and #$fff0
ora #$0004 ora #$0002
sta $a0,s sta $a0,s
lda $a2,s lda $a2,s
and #$0fff and #$0fff
ora #$4000 ora #$2000
sta $a2,s sta $a2,s
tsc tsc
@ -484,22 +483,22 @@ explosion5 entry
lda $0,s lda $0,s
and #$0f0f and #$0f0f
ora #$40c0 ora #$2010
sta $0,s sta $0,s
lda $2,s lda $2,s
and #$f0f0 and #$f0f0
ora #$0404 ora #$0202
sta $2,s sta $2,s
lda $a0,s lda $a0,s
and #$f0f0 and #$f0f0
ora #$0c08 ora #$0103
sta $a0,s sta $a0,s
lda $a2,s lda $a2,s
and #$0ff0 and #$0ff0
ora #$800c ora #$3001
sta $a2,s sta $a2,s
tsc tsc
@ -508,22 +507,22 @@ explosion5 entry
lda $0,s lda $0,s
and #$0f00 and #$0f00
ora #$404c ora #$2021
sta $0,s sta $0,s
lda $2,s lda $2,s
; and #$0fff not necessary with pure green and #$0fff
ora #$c000 ora #$1000
sta $2,s sta $2,s
lda $a0,s lda $a0,s
; and #$f0f0 not necessary with pure green and #$f0f0
ora #$0c0c ora #$0101
sta $a0,s sta $a0,s
lda $a2,s lda $a2,s
and #$ff00 and #$ff00
ora #$0084 ora #$0032
sta $a2,s sta $a2,s
_spriteFooter _spriteFooter
@ -549,22 +548,22 @@ explosion6 entry
lda $0,s lda $0,s
and #$f0f0 and #$f0f0
ora #$0c08 ora #$0103
sta $0,s sta $0,s
lda $2,s lda $2,s
; and #$0fff not necessary with pure green and #$0fff
ora #$c000 ora #$1000
sta $2,s sta $2,s
lda $a0,s lda $a0,s
and #$0f0f and #$0f0f
ora #$c040 ora #$1020
sta $a0,s sta $a0,s
lda $a2,s lda $a2,s
and #$f000 and #$f000
ora #$0484 ora #$0232
sta $a2,s sta $a2,s
tsc tsc
@ -572,37 +571,37 @@ explosion6 entry
tcs tcs
lda $a0,s lda $a0,s
; and #$ff0f not necessary with pure green and #$ff0f
ora #$00c0 ora #$0010
sta $a0,s
lda $a2,s
; and #$0fff not necessary with pure green
ora #$c000
sta $a2,s
tsc
adc #$140
tcs
lda $0,s
and #$fff0
ora #$0008
sta $0,s
lda $2,s
; and #$f0ff not necessary with pure green
ora #$0c00
sta $2,s
lda $a0,s
and #$fff0
ora #$0008
sta $a0,s sta $a0,s
lda $a2,s lda $a2,s
and #$0fff and #$0fff
ora #$8000 ora #$1000
sta $a2,s
tsc
adc #$140
tcs
lda $0,s
and #$fff0
ora #$0003
sta $0,s
lda $2,s
and #$f0ff
ora #$0100
sta $2,s
lda $a0,s
and #$fff0
ora #$0003
sta $a0,s
lda $a2,s
and #$0fff
ora #$3000
sta $a2,s sta $a2,s
tsc tsc
@ -611,22 +610,22 @@ explosion6 entry
lda $0,s lda $0,s
and #$0f0f and #$0f0f
ora #$c040 ora #$1020
sta $0,s sta $0,s
lda $2,s lda $2,s
; and #$f0ff not necessary with pure green and #$f0ff
ora #$0c00 ora #$0100
sta $2,s sta $2,s
lda $a0,s lda $a0,s
and #$f0f0 and #$f0f0
ora #$0808 ora #$0303
sta $a0,s sta $a0,s
lda $a2,s lda $a2,s
and #$0f0f and #$0f0f
ora #$4040 ora #$2020
sta $a2,s sta $a2,s
_spriteFooter _spriteFooter

View File

@ -16,9 +16,9 @@ scores start spriteSeg
score300 entry score300 entry
_spriteHeader _spriteHeader
; $c - Green ; $1 - Green
; $4 - Red ; $2 - Red
; $8 - Off-white ; $3 - Off-white
; ;
; ....|....|.... ; ....|....|....
; ....|....|.... ; ....|....|....
@ -123,9 +123,9 @@ score300 entry
score600 entry score600 entry
_spriteHeader _spriteHeader
; $c - Green ; $1 - Green
; $4 - Red ; $2 - Red
; $8 - Off-white ; $3 - Off-white
; ;
; ....|....|.... ; ....|....|....
; ....|....|.... ; ....|....|....
@ -231,9 +231,9 @@ score600 entry
score900 entry score900 entry
_spriteHeader _spriteHeader
; $c - Green ; $1 - Green
; $4 - Red ; $2 - Red
; $8 - Off-white ; $3 - Off-white
; ;
; ....|....|.... ; ....|....|....
; ....|....|.... ; ....|....|....

View File

@ -40,10 +40,14 @@ Each colour is 4 bits wide. All zeros is always black in all the different pall
* numbers * numbers
* letters * letters
* symbols * symbols
* spider scores (300, 600 and 900)
* bug explosions
* solid squares (primarily the all black square) * solid squares (primarily the all black square)
These sprites generally draw first and overwrite what may have been there before. After the background layer is drawn, other things are drawn in this order: These sprites generally draw first and overwrite what may have been there before. There are exceptions though. Spider scores and bug explosions do generally layer on top of the background but these things still use the "background colours" when drawn. The reason for this is that these background colours are not considered to be a collision if present when the player is drawn. We do not want the player to be considered dead just because it touched a spider score or bug explosion.
* spiders/scores
After the background layer is drawn, other things are drawn in this order:
* spiders
* scorpions * scorpions
* fleas * fleas
* centipede segments * centipede segments
@ -63,3 +67,9 @@ An exception to the "background is drawn first" rule though is the non-playable
We also need to clip a flea which is dropping down from the top. The solution there is that the game allocates memory before the SHR page, enough for an extra unseen tile above the screen. A partially obscured flea is drawn offscreen into that part of memory before the SHR page. We also need to clip a flea which is dropping down from the top. The solution there is that the game allocates memory before the SHR page, enough for an extra unseen tile above the screen. A partially obscured flea is drawn offscreen into that part of memory before the SHR page.
There is a similar problem when the flea reaches the bottom of the screen. I have decided to just not handle it. The flea disappears once it reaches the bottom of the screen. It does not scroll off the bottom. There is a similar problem when the flea reaches the bottom of the screen. I have decided to just not handle it. The flea disappears once it reaches the bottom of the screen. It does not scroll off the bottom.
## Collisions
There are two sprites which need to detect collisions. We need to detect if the player has collided with a bug when we draw the player. The way that is done is that any pixel that the player will draw, we check to see if anding that pixel with $c results in a non-zero value. At least one of those two high bits will be set if the pixel has been drawn by a bug. Background sprites never set those bits. From there, we need to figure out if the bug that was collided with is a spider, flea of centipede segment. The player cannot collide with a scorpion because the are always in different parts of the screen. Once we know there is a collision, the code looks for tile overlap between the player and the spider, flea or centipede segment in order to figure out what collided.
The player's shot also collides with these things but also collides with mushrooms which are a background sprite. So, in this case, any non-zero value in a pixel being drawn to by the shot is considered to be a collision. In fact, the shot is only one pixel wide but a collision is said to occur if either nibble in the byte is non-zero. Once we have the data from the collision, that is anded with $c and if that is zero, that indicates that a mushroom collision may have occurred. Based on the address of the collision, that turns into a tile lookup. Otherwise, that may be a bug collision. As with player collisions, a check for tile overlap is what is used to figure out what kind of bug caused the collision.