How do you design YOUR 2D sprite class?

Started by
22 comments, last by ravyne2001 19 years, 7 months ago
I am intent on writing my own sprite class from scratch, without any tutorials, but I thought I would cheat a bit and maybe ask around and see how others are doing is so that I can learn from their experiences. The problem I have is that there are so many types of animations! There are looping animations (walking, etc.), animations that play once and stop (explosions). A big part of animations is not only about flashing different pictures in a certain order, but also moving the entire sprites! Some sprites move back and forth, they fly in the air in circles and figure-8's, and so I figure I need a sprite class that encapsulates all of these properties. My basic idea so far is this. I have a class called cSprite that has the following properties: * A pointer to a surface where the frames are stored (all on one bitmap). * A "cells[]" array which contains the x,y,w,h of each animation cell on the bitmap. * An "animations[]" array that stores each of the animations that the sprite will do. * Member data to hold the x and y position of the sprite, r for rotation, v.x and v.y for velocity, and a.x and a.y for accelleration. * Functions to update the velocity (based on the current accelleration and time lapsed since last frame), and position (based on the current velocity and time lapsed since last frame). The cells[] array is an array of objects from my cCells class, the properties of which are simply x,y for the upper-left corner of the cell and w,h for the width and height of that animation cell. The animations class contains a frames[] array which basical is there to list the cells being used in the animation, and what order they should be in. The animations class also contains member variables to define whether the animation loops continuously, a fixed number of times, or not at all. The frames[] array is an array of objects of a cFrames class, and it basically has two main properties: a) which cell to display, and b) how long to display it. GASP! That's a lot of work. I haven't even written the code yet and so I don't know how it will work out. One thing I haven't quite figured out yet is how to make the animations themselves affect the position, velocity, and/or acceleration of the sprite. If I want to have a boss character that flies in a figure 8 pattern during one if its animations, I need a way for the animation itself to update the sprite movement information. I'm thinking of adding some more arrays to the Animations class, like velocity[] and position[] and acceleration[], that each define what changes (if any) in these properties need to take place, and when. I fear I'm making this way too complicated though, especially for my first sprite class. Has anyone tackled a sprite class before? And if so, what do you think? Even if you haven't tackled a sprite class before, I'm sure you have some great ideas too. :o)
Advertisement
heh, I was just happy to get a single image rendered to the screen.

Anyways, back to the question:

I don't. Anything that modifies the position, velocity, acceleration, content, or anything else of a sprite doesn't belong in the class. [in my design of course, my next design might be different, and your milage may vary...] Any modifications like that are done in my particle system class, not the simple image class.
I would personally leave the animations out of the sprite class (the animations that involve moving the entire sprite, not the ones that just flip through frames). The overall movement of a sprite is going to be very dependent upon your specific game, and thus the functionality should be handled by your game, not by a general purpose sprite class. The movement of the sprite could be a prerecorded movement, could be based on AI code, could be based on physics code, could be based on user input, etc. 'Tis not the sprite's personal responsibility. All the sprite really needs to know is how to display a certain frame at a specified location on the screen.

Otherwise, at a glance, it looks good.

[edit]Telastyn beat me, but yeah, I [obviously] agree with him.[/edit]
"We should have a great fewer disputes in the world if words were taken for what they are, the signs of our ideas only, and not for things themselves." - John Locke
Ah, ok good insight. Thanks.

I tend to be to literal when designing classes (for example, "sprites move therefore movement should be part of the sprite class!") and so often I overlook things like this.
i agree... i personally feel that a sprite should only care about what images it has and how to render those images and what images to render at a given time. movement and things like this should be seperate, at least in my opnion. a sprite is really just a graphic, not an actual moving entity. the moving thing should be a Player, Enemy, Npc, etc, which could have a Sprite object as a member of the class which controlled which frame to draw. the class could also have other members which took care of movement and things. thats just my opinion
FTA, my 2D futuristic action MMORPG
I designed a system very much like gimbal_lock's. I store the animation and frame information in the individual sprite class. I also have the sprite's position, velocity, and other attributes stored there as well. Personally I don't see a problem storing these inside of the sprite class. It's more of a mangement issue than anything else.

Take the sprite's position for example. By storing the position in the individual sprite object, drawing them at the right location becomes trivial. As you loop through each sprite, you get the position and draw. The alternative is to store the sprite's position elsewhere, say, an another array or data structure. If you have a large number of sprites, that may become hard to handle.

By encapsulating this type of data, each sprite object knows where is should be drawn, how fast is should move, which animation should be displayed, etc... Making management of the objects quite easy. It all depends on what you define as a "Sprite". If a "Sprite" to you is just an image, then this type of design is overkill. But, if a "Sprite" is a player-controllable object, then this design is a good place to start.
-----------------------------kevin@mayday-anime.comhttp://www.mayday-anime.com
Quote:Original post by grasshopa55
Take the sprite's position for example. By storing the position in the individual sprite object, drawing them at the right location becomes trivial. As you loop through each sprite, you get the position and draw. The alternative is to store the sprite's position elsewhere, say, an another array or data structure. If you have a large number of sprites, that may become hard to handle.


If you do go down this road, though, it is best to ensure that the actual image is stored in a manager or external source to the sprite so that you don't have several copies of the same image floating around in memory. Personally, I keep position and movement and such outside of the sprite so that all entities using that sprite can use the same instance (via a Sprite Manager of course) and do the necessary calls to render itself (by calling a Draw() method on the Sprite with the according values).
Jason Olson - Software Developer[ Managed World ]
My sprite class has different phases of animation, but it lets whatever class is using it set the frame of animation.
I definately agree with what's been said here. A Sprite class should just be responsible for managing the actual image data.

Think about it like this: If your sprite class does more than that, you'll have to duplicate image data for each instance of an enemy. have 10 baddies? you'll need 10 sprite classes if it stores things like position, velocity, etc and that means duplicating the images 10 times, thats a ton of memory wasted. Its only the position, velocity, frame, etc that change so it makes sense to to have that in some sort of entity class which references a sprite class.

My sprite class does nothing more than return a pointer to a frame of an animation as well as allocate/free the resources it used.

throw table_exception("(? ???)? ? ???");

and actually, I don't even keep velocity, or the image the sprite renders in the sprite either...

in basic terms:

sprite{    rect;    color;    *image;}


Anything more complex then builds upon this [adding a velocity for instance]. The image is actually handled by my resource manager. No need to have 20 billion copies of 'armyman.png' in memory...

This topic is closed to new replies.

Advertisement