Tutorial on Game Objects/Sprites
Moderator: Moderators
Tutorial on Game Objects/Sprites
I'm having trouble grasping the concepts involved in keep track of game object and the sprites that represent them. Is anyone aware of a good 6502 asm tutorial on these topics?
-
- Posts: 1565
- Joined: Tue Feb 07, 2017 2:03 am
Re: Tutorial on Game Objects/Sprites
Can't really think of any, I guess this is more a generic how to make a game question. Objects you store what data you need in a struct of arrays. For the sprites they use, you don't generally as you build your OAM table fresh each frame from what frames you object needs so which sprites they use doesn't matter.
Re: Tutorial on Game Objects/Sprites
It's less of a game concepts question and more of an ASM implementation question.
-
- Posts: 1565
- Joined: Tue Feb 07, 2017 2:03 am
Re: Tutorial on Game Objects/Sprites
my Snes tutorials are not that advanced yet but I do have QWAK
The SNES version is very heavily commented https://github.com/oziphantom/QwakSNES
there is also the CommanderX16 version https://github.com/oziphantom/QwakCX16
and the original C64 https://github.com/oziphantom/Qwack64
I have a video where I do a walk through of the CX16 code a bit as well https://www.youtube.com/watch?v=cdpaEtIrpDE
while these are not NES, 6502 is 6502. In this game I do use static sprite allocation for the CX16 and SNES versions though. Since the sprites are mostly all 16x16 it would be pretty straightforward to port it to the NES.
The SNES version is very heavily commented https://github.com/oziphantom/QwakSNES
there is also the CommanderX16 version https://github.com/oziphantom/QwakCX16
and the original C64 https://github.com/oziphantom/Qwack64
I have a video where I do a walk through of the CX16 code a bit as well https://www.youtube.com/watch?v=cdpaEtIrpDE
while these are not NES, 6502 is 6502. In this game I do use static sprite allocation for the CX16 and SNES versions though. Since the sprites are mostly all 16x16 it would be pretty straightforward to port it to the NES.
Re: Tutorial on Game Objects/Sprites
Tutoriais about these general topics are very rare... After the basics of interacting with the hardware, people just assume you'll be able to apply concepts you'll learn elsewhere to your platform of choice.
Just to expand a bit on what Oziphantom said:
Structures of arrays are basically a bunch of separate arrays, one for each property that objects can have. Once you decide how many objects your engine will be able to handle at a time, you create several arrays of that size, one for each property. For example:
This way you can access all of an object's properties by having an index register (typically X) indicate which object slot you're using. This allows you to create subroutines to perform common object tasks (e.g. accelerate, collide, etc.) that take an object slot as an argument and can be used to manipulate any object.
As for drawing sprites, the normal thing to do is to use meta-sprites. A simple format for meta-sprites is just a list of sprites with the same fields that the OAM uses (X, Y, pattern and attributes), but the X and Y coordinates are not absolute values, they're signed values (-128 to 127) relative to an object's coordinates. You'd then need a subroutine that takes the index of an object slot and the address of a meta-sprite definition, and goes through each sprite entry adding the relative coordinates to the object's coordinates, generating the final absolute coordinates that you'll wrote to OAM. If the final coordinates are on screen, copy the remaining fields (pattern index and attributes) to OAM as well and move on to the next sprite. If the coordinates are off screen, just skip to the next sprite without outputting an OAM entry.
Things become a little more complex when you factor in scrolling (the camera's coordinates also play a role in defining the final sprite's coordinates), flipping (you need to invert the relative coordinates or duplicate the meta-sprite definitions) and sprite cycling (you have to a a little clever when selecting which OAM slots to use), but this is the general idea.
Feel free to ask for help if you needed to know more about any of these steps.
Just to expand a bit on what Oziphantom said:
Structures of arrays are basically a bunch of separate arrays, one for each property that objects can have. Once you decide how many objects your engine will be able to handle at a time, you create several arrays of that size, one for each property. For example:
Code: Select all
OBJECT_SLOTS = 16
.org $0400
ObjectX: .rs OBJECT_SLOTS
ObjectY: .rs OBJECT_SLOTS
ObjectVelocityX: .rs OBJECT_SLOTS
ObjectVelocityY: .rs OBJECT_SLOTS
ObjectHealth: .rs OBJECT_SLOTS
;(...)
As for drawing sprites, the normal thing to do is to use meta-sprites. A simple format for meta-sprites is just a list of sprites with the same fields that the OAM uses (X, Y, pattern and attributes), but the X and Y coordinates are not absolute values, they're signed values (-128 to 127) relative to an object's coordinates. You'd then need a subroutine that takes the index of an object slot and the address of a meta-sprite definition, and goes through each sprite entry adding the relative coordinates to the object's coordinates, generating the final absolute coordinates that you'll wrote to OAM. If the final coordinates are on screen, copy the remaining fields (pattern index and attributes) to OAM as well and move on to the next sprite. If the coordinates are off screen, just skip to the next sprite without outputting an OAM entry.
Things become a little more complex when you factor in scrolling (the camera's coordinates also play a role in defining the final sprite's coordinates), flipping (you need to invert the relative coordinates or duplicate the meta-sprite definitions) and sprite cycling (you have to a a little clever when selecting which OAM slots to use), but this is the general idea.
Feel free to ask for help if you needed to know more about any of these steps.
Re: Tutorial on Game Objects/Sprites
It appears some of the question arises from the paradigm mismatch between designs customary on desktop and laptop computers and the addressing modes available in 8-bit microprocessors. Whereas object-oriented languages targeting sufficiently PDP-11-like instruction sets (such as 68K and x86) encourage array of structures, 6502 encourages structure of arrays, as you described.
(For comparison, the Game Boy CPU's dearth of addressing modes tends to encourage one of two patterns. One involves planning the order of operations of every entity's move routine months in advance so that the move routine can step through the fields of an entity's struct sequentially. The other treats RAM as a 2D array with entities' state at a stride of $0100 bytes, with the level map or other bulk data in the gap between entities. I haven't seen good tooling for either approach.)