It is currently Mon Nov 20, 2017 11:38 pm

All times are UTC - 7 hours





Post new topic Reply to topic  [ 8 posts ] 
Author Message
 Post subject: Object/sprite animation
PostPosted: Tue Dec 28, 2010 5:40 am 
Offline
User avatar

Joined: Wed Nov 24, 2010 12:51 am
Posts: 44
Location: Finland
Hi, I have a question about animation of objects. In my simple one screen game I have a main character that consist of 4 sprites. I want him to walk across the screen. I'm also going to have more objects with some animation. I was thinking to make an engine for general handling of all objects animation.

How are you guys doing this sort of thing? what data do you have in ROM/RAM? what is the structure of the data in ROM? how are you handling objects generally?

The following is what I have come up with so far.

In ROM the tiles that make up the object needs to be defined:
Code:
WalkLeft:
;frame1
   .byte tile#, x-pos, y-pos, attr
   .byte tile#, x-pos, y-pos, attr
   .byte tile#, x-pos, y-pos, attr
   .byte tile#, x-pos, y-pos, attr
;frame2
   .byte tile#, x-pos, y-pos, attr
   .byte tile#, x-pos, y-pos, attr
   .byte tile#, x-pos, y-pos, attr
   .byte tile#, x-pos, y-pos, attr
;frame3
   .byte tile#, x-pos, y-pos, attr
   .byte tile#, x-pos, y-pos, attr
   .byte tile#, x-pos, y-pos, attr
   .byte tile#, x-pos, y-pos, attr

WalkRight:
;frame1-3
   ... and so on


Somewhere in RAM each object need to have a place where the object is represented with an ID, adress to the frames in ROM and so on...

Is what I have described a smart or good approach. Do you have something better or smarter or easier way of doing animations, please share.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Dec 28, 2010 8:25 am 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 19237
Location: NE Indiana, USA (NTSC)
Super Mario Bros. just assumes that all enemy critters' cels will be 16x24 pixels (a 2x3 grid) and stores one attribute and six tile numbers. (One of the tile numbers means "no tile here".)


Top
 Profile  
 
 Post subject:
PostPosted: Tue Dec 28, 2010 5:01 pm 
Offline
Site Admin
User avatar

Joined: Mon Sep 20, 2004 6:04 am
Posts: 3484
Location: Indianapolis
Tables like that are a decent way to do it, in fact I had released my code that does exactly that: http://www.parodius.com/~memblers/nes/animate.asm (edit: URL gone, attached below). The example has 2 different sized objects with their own animations.

The main addition to my tables is that I have it list the number of tiles used in each frame, and in the table of frame pointers I have a number between each pointer that is used a fixed-point delay value between each frame.

Also, since the tile placement is relative (from the first sprite), I also did some hackery that instead of using the usual offsets(0, 8, etc.), on some frames for the squid animation it adds 1 or 2, and that will make the animation itself propel the object forward by 1 or 2 pixels on those frames. That can be used to handle movement and animation at the same time, if it's appropriate. Otherwise, you just move the 'base' sprite with some code like normal before calling the animation.


Attachments:
animate.asm [7.51 KiB]
Downloaded 13 times
Top
 Profile  
 
 Post subject:
PostPosted: Wed Dec 29, 2010 12:06 am 
Offline
User avatar

Joined: Wed Nov 24, 2010 12:51 am
Posts: 44
Location: Finland
Okay, I will look at that code and try to understand it. It always takes alot of time to understand someone else's code when it's not very well documented, especially when you are a beginner like me. :D so if you have some documentation it would be great, but I'm sure I will learn more if I have to figure it out myself.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Dec 29, 2010 1:05 pm 
Offline
Site Admin
User avatar

Joined: Mon Sep 20, 2004 6:04 am
Posts: 3484
Location: Indianapolis
Nope, not any extra documentation other than what is in that source. The labels weren't named very well either. And yeah it is kinda confusing to follow that code. If you look at run_anim: though, that is the example of how it's called. explosion_follow is supposed to point to the 'base sprite' for the others to be placed around.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Dec 29, 2010 11:37 pm 
Offline
User avatar

Joined: Wed Nov 24, 2010 12:51 am
Posts: 44
Location: Finland
I don't get it, I mean I know that run_anim label is called first, then within that subroutine you check whether to run animation or not but then variable names get me confused, could you explain what these are?

anim_offset
animspr_offset
squidtime
anim_delay
anim_timer
anim_number
anim_addr

Maybe the code is too advanced for me at this point. It's only my first game, I mean I could implement animations later. But if you could explain these variables I could take another look and then decide what to do.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Dec 31, 2010 12:42 am 
Offline
Site Admin
User avatar

Joined: Mon Sep 20, 2004 6:04 am
Posts: 3484
Location: Indianapolis
anim_offset needs to be sized to one byte per (concurrent) animation. These bytes keep track of the current frame (to step through and index it in the table)

animspr_offset seems to be used like explosion_follow, it's the base sprite for the animation. Not sure why it's different from explosion_follow though.

squidtime appears to be a counter I used to retrigger the animation periodically. I could have used the loop function in the animation, but I probably did this to make it easier to tweak (since I did that weird thing of making the animation itself move the sprite). These 2 animations had one of them sorta chasing the other, but were moving in different ways, so some tweaking was needed.

anim_delay is the fixed-point counter that is used to make the delays between frames. The frame changes to the next when anim_delay rolls over (generates a carry, and partial value is kept). There is one of these per concurrent animation.

anim_timer is the value added to anim_delay every frame. This byte is in the data between the addresses that point to the frames. If you look at the squidmove table you can see it's used pretty stupidly - the value is 255 which will overflow the counter on almost every frame. As with the others, the size of this is 1 byte per animation.

anim_number is how you select which animation/object to process. This is used directly to index some of the previous bytes (that are arrays in RAM), so for concurrent 2 animations you'd set it to zero, call the animator, set it to one, call the animation, and so on.

anim_addr is what it uses to point to the actual frame data. Such as quid0: for example, where there is the size followed by the sprite data.

Hopefully that makes a little more sense, it did seem pretty complicated when I wrote it and I've managed to use it in a few projects since then. But if it's not directly usable hopefully some of the methods will help with whatever you do.


Top
 Profile  
 
 Post subject:
PostPosted: Sat Jan 01, 2011 8:59 am 
Offline
User avatar

Joined: Wed Nov 24, 2010 12:51 am
Posts: 44
Location: Finland
I have again tried to grasp the code with these variable explanations you gave me, and it makes a lot more sense now, thanks. I don't understand everything that is happening but it doesn't matter. Maybe I could get your code to play along, maybe not, but I have decided to write my own code instead of using code I don't fully understand. I will base it on your solution/idea though and the concept will be the same so let's see how it ends up... I thank you for your help.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 8 posts ] 

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 10 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group