random name
random name

Reputation: 1

Smooth sprite movement

I am a beginner at nes development and i have created a simple sprite movement code. It's working fine, but not smooth: It just teleports between pixels. I heard something about subpixels, can I make a smoother code? Here it is:

ldy #$00

loop:
iny

cpy #$ff
bne loop

inc $0005
ldy $0005
cpy #$30
bne loop

inc $0200
inc $0203
inc $0204
inc $0207
inc $0208
inc $020b
inc $020c
inc $020f

ldy #$00
    JMP loop

Thanks ;)

Upvotes: 0

Views: 142

Answers (1)

puppydrum64
puppydrum64

Reputation: 1688

Well, for one thing, your character isn't moving consistently the way you designed your loop.

loop:
iny
cpy #$ff ;you don't need this line, nearly all operations on 6502 auto compare to 0 anyway
bne loop

inc $05
ldy $05
cpy #$30
bne loop

; inc x and y coords of each sprite

LDY #0
;$05 was never reset to zero so it will be #$31 next time we inc $05
JMP loop

Since you didn't reset memory location $0005 to its starting value, it's not going to loop the same amount of time every time. That might be an issue for smooth looping, since it creates variance in how often you increment your x and y coordinates. Other than that, it seems you're doing everything fine (I'm assuming that you do sprite DMA during NMI using $0200 as the source of your sprite cache.)

Generally speaking, it's much better to use a vblank wait to more accurately time your character movement. That way the character can only move one pixel per frame at most. The easiest way to do that is to set aside a zero-page memory location (say for example $007F, but it can be wherever you want) and then do a loop to wait for the NMI to fire. As long as the only sections of code that write to that memory location are your wait loop and the NMI, you've created a "starting pistol" that can tell your program when to continue. (While you can use bit $2002 to poll vblank, it's not a good idea to do this except when the PPU is warming up during your startup sequence.)

VBlankWait:
pha
LDA #0
STA $7F
Again:
LDA $7F
BEQ Again  ;loop until next NMI
PLA
RTS

And then modify your NMI to alter the value.

NMI:
PHA
TXA
PHA
TYA
PHA

;nmi code goes here

LDA #1
STA $7F ;this will cause the "Again" loop to exit when we return to it.
PLA
TAY
PLA
TAX
PLA
RTI

Once you've done all that, you can modify your code like so:

loop:

jsr VBlankWait

; modify sprite x and y here

jmp loop

Upvotes: 0

Related Questions