Moving Sprites Around

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
Moving Sprites Around
by on (#73789)
Hey all,

got a sprite question. I would to move a sprite back a few tiles, but I can't figure out how to move it. I've set write breakpoints for $2003 and $4014 and gone up and down the code a bit, but I haven't found what I'm looking for. Is there a register that determines where a sprite is displayed on-screen?

by on (#73791)
When you code sets the sprite pointer to $0 and then $02 ($0200) for the data, you have to subtract/add to make the sprites move a direction from there. $4014 and $2003 do nothing but send the sprites to the PPU RAM. :)


Hope this helps.

by on (#73792)
You re-generate all sprites in the sprite table every frame, based on your array of game objects or another metasprite list. You shouldn't be doing noob stuff like responding to joystick input by incrementing or decrement values in your sprite memory, some awful tutorials suggest doing that.

by on (#73796)
Dwedit wrote:
You re-generate all sprites in the sprite table every frame, based on your array of game objects or another metasprite list.

Yes, this is the professional way to do it.

Quote:
You shouldn't be doing noob stuff like responding to joystick input by incrementing or decrement values in your sprite memory, some awful tutorials suggest doing that.

I believe ALL tutorials suggest that, and because of that an insane amount of people here actually do it that way.

by on (#73851)
To play with sprite memory, usually you will reserve $0200 for sprite ram. Then, you will want to play with the memory at $0200 to get a feel for how sprites work. every 4 bytes is a sprite. The first byte is the Y coordinate, the second byte is which tile to use from your nametable, the third byte consists of attributes (flip is all I've used in my own game so far), the fourth byte is the X coordinate. Once you've put in some test values into the first 4-byte entry at $0200, call the below function "sprite_update_all" to stuff the $0200 page into sprite OAM. In the below code, the "sprite" label is equal to $0200. Make sure when you call sprite_update_all you do it either while drawing is turned off, or during vblank. You may also want to call sprite_clear_all before you play with your sprite page, to hide any garbage sprites that may already be in RAM.

Code:
;note this is CA65 syntax, your anonymous labels in your preferred assembler may be slightly different.

sprite_update_all:
  lda #>(sprite)
  sta $4014
  rts

sprite_clear_all:
  lda #$ff
  ldx #$00
: sta sprite, x
  inx
  bne :-
  rts


Good luck!

Later on once you're used to the basics---the above advice concerning meta sprites and updating the entire sprite page will become more useful if you move on to a game engine. But for learning, twiddling with a few bytes is a good way to proceed.

*edit* I forgot an important detail. The "attributes" byte of each sprite contains not only information such as how to flip the sprite, but also its color attribute. I believe the low 2 bits are the color attribute. Probably when you're first testing this stuff that won't matter, just write 0 to this byte for now (use the first 4 colors in your sprite palette, do not flip, do not hide behind background).