It is currently Tue Oct 17, 2017 2:36 am

All times are UTC - 7 hours





Post new topic Reply to topic  [ 24 posts ]  Go to page 1, 2  Next
Author Message
PostPosted: Mon Aug 15, 2005 1:10 pm 
Offline
User avatar

Joined: Fri Nov 12, 2004 2:49 pm
Posts: 7224
Location: Chexbres, VD, Switzerland
Well, I'm trying to do decent thing to have an engine that handle some objects as sprites, that can come with various frames and positions. I've the idea to have a RAM buffer, where all parameters such as X/Y positions would be stored for every sprites, along with an "enable" flag that would simply tells if the sprites does exist or not, and if it exist the non-zero number in it tells wich kind of monster/projectile the sprite is, along with some others variables that would be customizable in function of the sprite type itself.
Now, the problem is when I want to draw them to the screen. They have to come in various sizes, and all of them would surely have different frames/positions, so that would need to write different data to the tile index and the flipping registers. I simply have no idea of how to pass from just knowing the number of the sprite ID and the number of it's frame to actual data to write to the sprite buffer. The only idea I had is to make a jump table that would jump to different code for each possible sprite object, that can be a monster or a projectile, but, heh I don't know if this is good at all.
Also, there should be some more flexibility in it, so a sprite ID as a monster could also show an "explositon" instead, if the monster is just defeated or something.
Any ideas ?

_________________
Life is complex: it has both real and imaginary components.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Aug 15, 2005 2:35 pm 
Offline
Site Admin
User avatar

Joined: Mon Sep 20, 2004 6:04 am
Posts: 3470
Location: Indianapolis
I have an animation routine, I wrote it for a game I was working on and also used it for moving the sprites in the Garage Cart intro. I can upload it if you want to use it, it's probably my favorite NES code I've written. :)

My code however totally ignores the problem of creating/destroying sprites. It just assumes each object is hardcoded to use certain sprites.

It's actually fairly complex. Creating the data manually can be kind of tedious, but it gives good results for me. I have the data set up like this:

These are pointers to the animations.
anim_index:
.addr squidmove
.addr littlerunner

This is the actual animation.
First 2 bytes are a pointer to the frame data, the second is the (fixed point) time length for the frame.

littlerunner:
.addr run0
.byte 68
.addr run1
.byte 68
.addr run2
..etc..
.addr anim_loop

Here's the actual frame data:

run0:
.byte 4
.byte $c0,$00,$00,$23
.byte $c1,$00,$08,$23
.byte $d0,$08,$00,$23
.byte $d1,$08,$08,$23
run1:
.byte 4
.byte $c2,$00,$00,$23
.byte $c3,$00,$08,$23
.byte $d2,$08,$00,$23
.byte $d3,$08,$08,$23

The first byte simply says how many sprites are used in this frame. The next bytes are tile #, Y offset, X offset, and attribute. The good part is that the X/Y offsets are treated as relative to the first sprite of the object.

I hope this gives you some ideas maybe.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Aug 16, 2005 1:26 am 
Offline
User avatar

Joined: Fri Nov 12, 2004 2:49 pm
Posts: 7224
Location: Chexbres, VD, Switzerland
Memblers wrote:
I hope this gives you some ideas maybe.

It did. Well, I was just writing a post to tell you that it wasn't what I was looking for, when I just read it again and understood :wink:

Well, the thing to have tile # relative to the first is extremely good. Well, so I'll do it relative to where the object is into the collision RAM aera. It has a lot of flexibility, so it can have different palette on the same sofware sprite done with different hadware sprites, and so on. Thanks.

_________________
Life is complex: it has both real and imaginary components.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Aug 16, 2005 8:24 pm 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10046
Location: Rio de Janeiro - Brazil
I'm designing a sprite/object engine myself, and maybe I can tell you what I came up with so far.

>I don't want to waste RAM with the objects, as I have a huge list of 512 or maybe 1024 objects per level, and they can't be all loaded at the same time;
>All of them are defined in ROM, using 2 bytes each (X and Y -packed together since I'm using block coordinates, not pixel ones-, and object type);
>A secondary list, wich I call "object state list", holds the initial states of all objects, using 4 bits per object. This list is not very big, and is copied to RAM when the level starts;
>The list of objects is sorted based on the screens they belong to, and there is a list of pointers (with as many entries as there are screens) that point to the first object belonging to that particular screen;
>When the player enters a screen, all objects of that screen are copied to a temporary RAM location, where they can be manipulated and have more room for its details: X and Y coords as separate bytes, current frame of animation, etc, etc;
>Note that objects are only loaded when their state bits tell it is not dead/inactive/destroyed;
>When the player leaves a screen behind, the objects of that screen are unloaded and their state bits are updated;
>State bits are used to tell if a door object is opened or closed, if an enemy is dead (and should never be loaded again), and many other object specific information, that must be kept in case you go back and see those objects again;
>I don't think that keeping their position is relevant, as I wait for a full screen to go by before unloading objects from RAM, and for me that is enough to not find strange if something isn't at the exact position when I saw it last time;
>Loaded objects can move between screens if you clear it's state bits (so that you don't load the same object twice!) when loading, and set them again when unloading;
>To have an explosion effect when you kill an enemy, just have the enemy routine kill the guy (take it off the active objects list and set its state to dead) and them place a new object directly in the active objects list, the explosion object, wich will kill itself once the animation is over.

It may sound a bit complicated right now, but it really isn't. Some of the stuff here may be ignored in a 2-way scroller, but I'm doing a 4-way one.

Also, I didn't focus on the actual animation (as Memblers already did, in a very nice way), but rather on general object handling.

This is still a work in progress, and I might have forgotten to include something, as I took this off my head. I always like to read about object engines, because this always seem to trigger something in our heads! =)


Top
 Profile  
 
 Post subject:
PostPosted: Wed Aug 17, 2005 1:12 pm 
Offline
User avatar

Joined: Fri Nov 12, 2004 2:49 pm
Posts: 7224
Location: Chexbres, VD, Switzerland
Thanks a lot, I'm of course also designing something to handle the main object in a whole stage, and I'm a bit confused and I don't know where to start. I'm doing a 4-way scrooling too, but to simplify games algorithms it only load a screen a once, in a Final Fantasy Adventure style (is that exactly what you're doing, if I undestand well ?). I had in mind to care only about one screen at time, and if the player leaves the screen and then comes back, all monsters would be still there. It's a bit lazy, but it adds more challenge. For example the player can't walk trough the whole stage when it's just behind the level boss/end without fighting monsters agian. Still, I found that can be a bit frustrating for the palyer, so I ask myself what is the best. I unfortunataly didn't understand your thing well, that would be cool to clarify it a bit. Thanks in (Game Boy) advance.

_________________
Life is complex: it has both real and imaginary components.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Aug 17, 2005 1:34 pm 
Hey!
Well, mine is a 4-way platformer. Yours seems to be a Zelda style game? I have four screens loaded at all times (virtually loaded, I didn't use any extra vram), since the player has a lot of freedom, and there will tipically be 4 screens showing at all times, unless the player is perfectly aligned to a screen, wich is rare.

In my case, I need to remember if the enemies died. It is very annoing when enemies keep comming back in platformers, in your game it works well.

I'd like to discuss the object engine thing further, I find it fun! But I'm leaving work now (or i'll miss my bus!). So we can talk later!


Top
  
 
 Post subject:
PostPosted: Wed Aug 17, 2005 1:52 pm 
Offline
User avatar

Joined: Fri Nov 12, 2004 2:49 pm
Posts: 7224
Location: Chexbres, VD, Switzerland
-tokumaru wrote:
Hey!
Well, mine is a 4-way platformer. Yours seems to be a Zelda style game?

Yeah, just like Legend of Zelda (I hope I'll be able to make much better control than this one, with annonyed me a lot, so I prefer taking reference on Final Fantasy Adventure), but not like Zelda-Adventure of Link at all.

Quote:
I have four screens loaded at all times (virtually loaded, I didn't use any extra vram), since the player has a lot of freedom, and there will tipically be 4 screens showing at all times, unless the player is perfectly aligned to a screen, wich is rare.

Didn't got it. You're scrooling directly and not trough "screens" like me, but have a huge maze of "screen" that have the size of the NES's screen ?

Quote:
In my case, I need to remember if the enemies died. It is very annoing when enemies keep comming back in platformers, in your game it works well.

Well, it depends on how you handle that. If you do it like Ninja Gaiden, so you just come back a pixel and the monster re-appear, it's extremely annoing. I think the best would be just to take care of the screen where the player is, and the screen where the player was just before. So, if he's just coming back, monsters won't reapear. I don't know if it's worth the programming, trough. I may care about this when I'll handle my sprites better.

Quote:
I'd like to discuss the object engine thing further, I find it fun! But I'm leaving work now (or i'll miss my bus!). So we can talk later!

Funny, I'm just going to bed :wink:
Well, I have a lot of trouble with my engine, to hande "detailed" enemies, I'd also like to have swapped palettes in later stages, but it will look bad if only one type of "palettes" are here in a single stage. Also, I'd like to have decent effects such as explosion and stuff, and also have "healing" items the monster may leave when defeated.

_________________
Life is complex: it has both real and imaginary components.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Aug 17, 2005 5:24 pm 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10046
Location: Rio de Janeiro - Brazil
Bregalad wrote:
Didn't got it. You're scrooling directly and not trough "screens" like me, but have a huge maze of "screen" that have the size of the NES's screen?


Well, my level is composed by many interconnected screens, but unlike in your game, they scroll around. Or better: the "camera" travels through the maze of screens, following the player. My screens are a bit larger than the NES' one. Mine are square, 256x256 pixels.

Quote:
Well, it depends on how you handle that. If you do it like Ninja Gaiden, so you just come back a pixel and the monster re-appear, it's extremely annoing. I think the best would be just to take care of the screen where the player is, and the screen where the player was just before. So, if he's just coming back, monsters won't reapear. I don't know if it's worth the programming, trough. I may care about this when I'll handle my sprites better.


Yeah, I don't like much games that keep restoring dead enemies. I keep track of 4 screens at a time, and have info in RAM for ALL the objects, telling me if they are dead or not. If they die they are never loaded again.

Quote:
Well, I have a lot of trouble with my engine, to hande "detailed" enemies, I'd also like to have swapped palettes in later stages, but it will look bad if only one type of "palettes" are here in a single stage. Also, I'd like to have decent effects such as explosion and stuff, and also have "healing" items the monster may leave when defeated.


I'm still working on my palette stuff, But i think I'll build a table of all the palettes the level uses (at max 32). And keep in RAM 8 pointers to the ones currently being used, so that objects can modify this list as much as they want, for effects. And them I copy the right palettes to vram at vblank.

As for explosion and items, I think you should have a code for EVERY object in your game. Enemies, items, potions, explosions, splashes, etc. Each of them has it's own code. The enemy code does the following: "if the player hits me, I'll clear myself from memory and place an explosion object in my place", and then the explosion object code will go like: "I'll show my first frame" and next "I'll show my second frame" until it shows the last one when it goes like "ok, this was my last frame. I'll just remove myself from memory now". And it goes something like this. That's how I'm doing, at least.

Talk yo you later!


Top
 Profile  
 
 Post subject:
PostPosted: Wed Aug 17, 2005 5:50 pm 
Offline
User avatar

Joined: Mon Sep 27, 2004 8:33 am
Posts: 3715
Location: Central Texas, USA
Regarding ways to avoid regenerating enemies, you could assign a single bit in memory to each one and set it when the enemy has been defeated. This way you only keep the full enemy data when it's within a screen or so of the player, rather than for all enemies in the area. As an example, if you had at most 256 enemies per area these bits would take only 32 bytes of RAM and each enemy object would have an 8-bit index into these bits.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Aug 17, 2005 9:47 pm 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10046
Location: Rio de Janeiro - Brazil
blargg wrote:
Regarding ways to avoid regenerating enemies, you could assign a single bit in memory to each one and set it when the enemy has been defeated. This way you only keep the full enemy data when it's within a screen or so of the player, rather than for all enemies in the area. As an example, if you had at most 256 enemies per area these bits would take only 32 bytes of RAM and each enemy object would have an 8-bit index into these bits.


That's exactly what I've been saying. Only I'd like to reserve a few more bits to each object, so they could store a bit more info than if they are dead or alive. I proposed 4 bits for 512 objects, wich results in 256 bytes, not much. a value of 0 means they are dead and are not supposed to be loaded.
In my case, object number 0 is associated with the first 4 bits in the "state page". Object 1 uses the next 4 bits for it's state, and so on. Each object in the level is associated to 4 bits in RAM.

In my initial design I assigned 2 bits for each object, but I ended up deciding on 4, as I may need to define more possible states.

1 bit is fine for simple enemies, but I'm handling all kinds of objects like this, not just enemies.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Aug 18, 2005 8:46 am 
Offline
User avatar

Joined: Fri Nov 12, 2004 2:49 pm
Posts: 7224
Location: Chexbres, VD, Switzerland
Well, well. I didn't get your palette stuff right. You're gonna to have a "palette number" for each ennemy/explosion/item, that will point to actual colors, then they will be written to the PPU "dynamicly", so when another monster with a different pallets comes, the palette will automatically swap right ? And if more than 4 palettes are loaded at the same time, what will happen ? Just Breed does this, and it halso sometimes have the more-than-4-palettes bug sometimes.
I don't know if I'll do this at all. I'll have palette 0 for explosions/fire stuff (a red-organge-white scale), palette 1 for player and palette 2/3 for monsters. Pretty much copied from Megaman, but that's a fine system. I may be able to do this special "system" only for palette 2 and 3, but I'm not agains monster that will also use the explosion or player palette. I'll also probabily make the player swaping its colors when it gets hurts, or is invincible, or something. Then 2 solutions comes in mind. Simply uses another palette for the player sprites, or always have an "hard-wired" palette 1 for player, but change the actual colors in it. I don't know the best one and can't determine it until I've determined how monsters would be handled. I think the palette pointer is good stuff, it doesn't make programming easyer, but is better for designing levels and stuff.

Quote:
As for explosion and items, I think you should have a code for EVERY object in your game. Enemies, items, potions, explosions, splashes, etc. Each of them has it's own code. The enemy code does the following: "if the player hits me, I'll clear myself from memory and place an explosion object in my place", and then the explosion object code will go like: "I'll show my first frame" and next "I'll show my second frame" until it shows the last one when it goes like "ok, this was my last frame. I'll just remove myself from memory now". And it goes something like this. That's how I'm doing, at least
.
Well, that's sure for AI, but what about for drawing it on the screen ? Do you think it's better to mix such AI and drawing routines or not ? Membler's thing waste pretty much ROM space, but this will do the same, after all.

_________________
Life is complex: it has both real and imaginary components.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Aug 18, 2005 9:08 am 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10046
Location: Rio de Janeiro - Brazil
Bregalad wrote:
Well, well. I didn't get your palette stuff right. You're gonna to have a "palette number" for each ennemy/explosion/item, that will point to actual colors, then they will be written to the PPU "dynamicly", so when another monster with a different pallets comes, the palette will automatically swap right ? And if more than 4 palettes are loaded at the same time, what will happen ? Just Breed does this, and it halso sometimes have the more-than-4-palettes bug sometimes.


Not quite what I said... I said (man I'm really bad explaining stuff, specially in english!) you should have all the palettes you're going to use define in one big list (four color entries for each palette), so you have them all ordered. And also have in RAM 8 pointers (4 for sprites and 4 for the BG) that point to the palettes currently being used. That's for when my player blinks brighter when he is hit, for example. I have its palette defined (as entry number 2, maybe) and loaded (mainly composed of reds, for example), and them my player gets hit, and it's AI routine changes the respective pointer to, say, 12 (palette composed of brighter values). Then copy the new palette to vram during vblank. And the player's AI keeps changing the palette for as long as it has to.

Quote:
I don't know if I'll do this at all. I'll have palette 0 for explosions/fire stuff (a red-organge-white scale), palette 1 for player and palette 2/3 for monsters. Pretty much copied from Megaman, but that's a fine system. I may be able to do this special "system" only for palette 2 and 3, but I'm not agains monster that will also use the explosion or player palette. I'll also probabily make the player swaping its colors when it gets hurts, or is invincible, or something. Then 2 solutions comes in mind. Simply uses another palette for the player sprites, or always have an "hard-wired" palette 1 for player, but change the actual colors in it. I don't know the best one and can't determine it until I've determined how monsters would be handled. I think the palette pointer is good stuff, it doesn't make programming easyer, but is better for designing levels and stuff.


I'm also using a similar system... my player uses 2 palettes, and 1 of those is also used for effects. The other 2 ones are used for enemies. And then I design my enemies so that they only use those 2 palettes in that level or section. Since you are working with static screens, you could maybe define what palettes each screen uses, so that you can have only two colors of enemies in 1 screen, but change them from screen to screen if you want.

Quote:
Well, that's sure for AI, but what about for drawing it on the screen ? Do you think it's better to mix such AI and drawing routines or not ? Membler's thing waste pretty much ROM space, but this will do the same, after all.


What I suggested was this mixed with what Memblers said. This is the AI part, but surely all objects will have an attribute stating the frame of animation they are currently supposed to be in. Based on that, you do what memblers said. I know it can take a lot of ROM space, but can't think of a more clean/professional way of doing this...


Top
 Profile  
 
 Post subject:
PostPosted: Thu Aug 18, 2005 9:49 am 
Offline
User avatar

Joined: Fri Nov 12, 2004 2:49 pm
Posts: 7224
Location: Chexbres, VD, Switzerland
tokumaru wrote:
Not quite what I said... I said (man I'm really bad explaining stuff, specially in english!) you should have all the palettes you're going to use define in one big list (four color entries for each palette), so you have them all ordered. And also have in RAM 8 pointers (4 for sprites and 4 for the BG) that point to the palettes currently being used. That's for when my player blinks brighter when he is hit, for example. I have its palette defined (as entry number 2, maybe) and loaded (mainly composed of reds, for example), and them my player gets hit, and it's AI routine changes the respective pointer to, say, 12 (palette composed of brighter values). Then copy the new palette to vram during vblank. And the player's AI keeps changing the palette for as long as it has to.

Yeah, that would be useless for BG, but pretty good for sprites. Myself, I'll probabily have just one hardwired BG palette per stage.

Quote:
I'm also using a similar system... my player uses 2 palettes, and 1 of those is also used for effects. The other 2 ones are used for enemies. And then I design my enemies so that they only use those 2 palettes in that level or section. Since you are working with static screens, you could maybe define what palettes each screen uses, so that you can have only two colors of enemies in 1 screen, but change them from screen to screen if you want.

Yeah, nothing beats Megaman. The only differences is that my player doesn't use the explosion palette at all, but some of his weapons may do this. Swapping palettes while changing screens would definitely be godd, but I don't know much how to handle that with the sprite drawing routine.
Quote:
What I suggested was this mixed with what Memblers said. This is the AI part, but surely all objects will have an attribute stating the frame of animation they are currently supposed to be in. Based on that, you do what memblers said. I know it can take a lot of ROM space, but can't think of a more clean/professional way of doing this...

Well, another way to do this would be to merge the AI and the drawing part together. So each monster wouldn't be draw from a fixed data system, but a routine for each separate monster would be set (exept for alternate swapped monsters, that would have common routine from their neighboors). Well, I'm still a bit confused overall.

_________________
Life is complex: it has both real and imaginary components.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Aug 18, 2005 11:52 am 
Bregalad wrote:
Yeah, that would be useless for BG, but pretty good for sprites. Myself, I'll probabily have just one hardwired BG palette per stage.

Well, not really. You could use it if you wanted to do a lightning effect on the background, for example. You would make your BG palette point to another one with a brighter sky a few times to achieve this effect. Many other effects could be done like this. Like in some megaman game, I can't remember wich one, it changes one of the background palettes to make it seem like the objects in the background are moving.

I also plan to have triggers during the levels, so I can include palette changing commands in the middle of a lavel (as well as CHR switching commands), so that different parts of it can use diferrent colors and graphics, resulting in more beautiful and colorful levels.

Quote:
Yeah, nothing beats Megaman. The only differences is that my player doesn't use the explosion palette at all, but some of his weapons may do this. Swapping palettes while changing screens would definitely be godd, but I don't know much how to handle that with the sprite drawing routine.

Just be sure to not include a combination of objects wich use more than two palettes in the same screen when you're designing your levels... I suggest you make some kind of header for every screen, describing the palettes it uses, so you can set them when drawing the BG.

Quote:
Well, another way to do this would be to merge the AI and the drawing part together. So each monster wouldn't be draw from a fixed data system, but a routine for each separate monster would be set (exept for alternate swapped monsters, that would have common routine from their neighboors). Well, I'm still a bit confused overall.

I thought about mixing them too, it was my first idea. But now I believe the best way is to have separate drawing and AI routines. After I run the AI for all objects, I'll have one general drawing routine going through all the active (loaded) objects, checking if they are visible and rendering the appropriate frame of every one of them to the temp sprite page.


Top
  
 
 Post subject:
PostPosted: Fri Aug 19, 2005 11:43 am 
Offline
User avatar

Joined: Fri Nov 12, 2004 2:49 pm
Posts: 7224
Location: Chexbres, VD, Switzerland
-tokumaru- wrote:
Well, not really. You could use it if you wanted to do a lightning effect on the background, for example. You would make your BG palette point to another one with a brighter sky a few times to achieve this effect. Many other effects could be done like this. Like in some megaman game, I can't remember wich one, it changes one of the background palettes to make it seem like the objects in the background are moving.


It should be MetalMan's stage, and Doctor Willy #2 (in MegaMan 2). It's pretty cool, but I'm not going to do this at all. I'll just have one fixed palette per level. For lightening effects, why is $2001.0 for ? It may not be as good, but way simpler.

Quote:
I also plan to have triggers during the levels, so I can include palette changing commands in the middle of a lavel (as well as CHR switching commands), so that different parts of it can use diferrent colors and graphics, resulting in more beautiful and colorful levels.


That's needed only for "advanced" games. I'm going to do a such simple one, to train myself at programming games, but I still want it to be good. I'm just using a CNROM or maybe UNROM mapper, and actually I'm surprised about how much the brightness tones counts a lot more than color in NES graphics. I mean, have a picture of a tree with a red-scale instead of a green-scale, it still looks a tree. If you change the green-scale per random colours, it looks just gabrage. That's it. I could even design the whole game with only two palettes per stages, letting 2 for the status bar. I'm still gonna to use 3 for the BG, I think.


Just be sure to not include a combination of objects wich use more than two palettes in the same screen when you're designing your levels... I suggest you make some kind of header for every screen, describing the palettes it uses, so you can set them when drawing the BG.

Quote:
I thought about mixing them too, it was my first idea. But now I believe the best way is to have separate drawing and AI routines. After I run the AI for all objects, I'll have one general drawing routine going through all the active (loaded) objects, checking if they are visible and rendering the appropriate frame of every one of them to the temp sprite page.

Okay, if you say it so, I think it's better. It's a cool think to take advantage of experiance from other people, I usually have to discover all myself.

_________________
Life is complex: it has both real and imaginary components.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 24 posts ]  Go to page 1, 2  Next

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