Hey everybody! A while back i came here asking for help to separate game logic from the NMI so i could try my hand on collision detection for a platformer, and now here i am asking for help to make said platformer.
The way i'm doing it is on my code there's a label which points to the name table used on my game like so:
Then i start treating this as a 2 dimensional array, using the X and Y position of the player's sprite (which is on left-top most pixel, trying to replicate the SFML/SDL way of doing things here). Of course i can't just use X and Y for the indexing as that would go way outside of the boundaries from the name table, so i divide both by 8 (size of a single tile on screen).
Then to finally finish it all of i would do x + y * 32 (32 being the size of a whole line of tiles on one screen), since there's no multiplying instruction for the 6502, i had to improvise a little:
LDA #<nameTable
STA playerTileLow
LDA #>nameTable
STA playerTileHigh
LoopY:
CLC
LDA playerTileLow
ADC #$20
STA playerTileLow
LDA playerTileHigh
ADC #$00
STA playerTileHigh
DEY
BNE LoopY
LoopX:
CLC
LDA playerTileLow
ADC #$01
STA playerTileLow
LDA playerTileHigh
ADC #$00
STA playerTileHigh
DEX
BNE LoopX
Then i would just proceed to see if there's a tile different to $#24(Nothing on spritesheet i am using) for every direction of each sprite.
For the most part it works, but then this some times happens when walking left or right towards a wall:
I think it is because of the way i did the indexing (x+y*32), does somebody know a possible reason for this? Or maybe a better way to handle collision on the NES?
Edit
Movement code when moving right:
The way i'm doing it is on my code there's a label which points to the name table used on my game like so:
Code:
nameTable:
.incbin "mapa.nam"
.byte $FF ; The nametable does not have byte $FF, just a way to know when
; it should stop reading data, think of it as a \0 on a C-string.
.incbin "mapa.nam"
.byte $FF ; The nametable does not have byte $FF, just a way to know when
; it should stop reading data, think of it as a \0 on a C-string.
Then i start treating this as a 2 dimensional array, using the X and Y position of the player's sprite (which is on left-top most pixel, trying to replicate the SFML/SDL way of doing things here). Of course i can't just use X and Y for the indexing as that would go way outside of the boundaries from the name table, so i divide both by 8 (size of a single tile on screen).
Code:
LDA $0203
LSR A
LSR A
LSR A
TAX
LDA $0200
LSR A
LSR A
LSR A
TAY
LSR A
LSR A
LSR A
TAX
LDA $0200
LSR A
LSR A
LSR A
TAY
Then to finally finish it all of i would do x + y * 32 (32 being the size of a whole line of tiles on one screen), since there's no multiplying instruction for the 6502, i had to improvise a little:
Code:
LDA #<nameTable
STA playerTileLow
LDA #>nameTable
STA playerTileHigh
LoopY:
CLC
LDA playerTileLow
ADC #$20
STA playerTileLow
LDA playerTileHigh
ADC #$00
STA playerTileHigh
DEY
BNE LoopY
LoopX:
CLC
LDA playerTileLow
ADC #$01
STA playerTileLow
LDA playerTileHigh
ADC #$00
STA playerTileHigh
DEX
BNE LoopX
Then i would just proceed to see if there's a tile different to $#24(Nothing on spritesheet i am using) for every direction of each sprite.
Code:
;This is just for checking collision on the right side of the sprite, but it's basically the same for the remaining directions
;Also, X is 0 here
LDY #$02
LDA (playerTileLow), y
CMP #$24
BEQ @didntColideRight
STX canColideRight
JMP @EndRight
@didntColideRight:
LDY #$22
LDA (playerTileLow), y
CMP #$24
BEQ @didntColideRight2
STX canColideRight
@didntColideRight2:
;Also, X is 0 here
LDY #$02
LDA (playerTileLow), y
CMP #$24
BEQ @didntColideRight
STX canColideRight
JMP @EndRight
@didntColideRight:
LDY #$22
LDA (playerTileLow), y
CMP #$24
BEQ @didntColideRight2
STX canColideRight
@didntColideRight2:
For the most part it works, but then this some times happens when walking left or right towards a wall:
I think it is because of the way i did the indexing (x+y*32), does somebody know a possible reason for this? Or maybe a better way to handle collision on the NES?
Edit
Movement code when moving right:
Code:
LDA control
AND #%00000001
BEQ endRight
LDA canColideRigt
CMP #$01
BEQ @dontNeedToCheckColision
LDA $020b
AND #%00000111 ; Stop only when right side of the sprite will hit something
BEQ endRight
@dontNeedToCheckColision:
LDX #$00
@LoopSprites:
INC $0203, x
INX
INX
INX
INX
CPX #$10
BNE @LoopSprites
endRight:
AND #%00000001
BEQ endRight
LDA canColideRigt
CMP #$01
BEQ @dontNeedToCheckColision
LDA $020b
AND #%00000111 ; Stop only when right side of the sprite will hit something
BEQ endRight
@dontNeedToCheckColision:
LDX #$00
@LoopSprites:
INC $0203, x
INX
INX
INX
INX
CPX #$10
BNE @LoopSprites
endRight: