Examples of good adaptive code for animated sprites

Hi

I’m struggling to come up with a sensible design for how to deal with animated sprites and I was wondering if any more experienced game programmers had any source code examples of solutions they had created. I want to be able to pick a sprite out from a sprite factory for use with a game object and im struggling to come up with sensible ways to deal with things like…

say I want an object that flies across the screen and destroys any objects it collides with, but the collision box won’t match the draw box for a number of reasons, including that the draw box will have to draw a fireball sprite with a long tail with no collision.

any ideas? I guess I’m just looking for examples of collision detection and animated sprites in games. really struggling to wrap my head around how to solve these problems. I keep thinking of weird hacks that tie the animations to the objects they represent a little too closely and its annoying me.

I guess I’m just having a crisis of imagination due to lack of experience.

help?

I think you need to separate out the two things (animation and physicality) for this to work. In the game I’m currently making, my objects and entities have scripts they can run that define constructors. In those, I tell the object what the spritesheet is going to look like, where special animations lie, etc. Then, my script also defines physical constraints for the objects and sprites (how large they actually are, whether they have collision or not). This lets me have spritesheets of varying sizes for entities and objects of varying sizes, and allows me to control their sizes in the game itself.

I’ve not done an entity framework and wouldn’t even know where to begin. I’m not a super beginner because I have a degree in games programming but I’ve not actually taken on a project like this by myself before. I’m just getting bogged down and looking for concrete examples of how other people have done things

I was going to have my sprites loaded in with data from text files on what is actually in the spritesheet and then loaded into an animation class, as for where to actually put the thing in relation to the object is another matter. then there is scaling. I’m just confused and wanted to see an example. my head is so fried from stressing out about how to structure the damn thing

I see what you’re saying. I can show you some of my code handling entity collisions, but I’m not sure how useful it will be for your particular case. What I would suggest before that, though, is keeping your animation data and your object data separate (aka, the Rectangle2D you use for collision is not the same one you use for drawing).

In my game, my entities are treated as circles, so here’s how I solve my collisions between entities themselves:

public void SolveEntityCollisions(List<Entity> entities)
{
    foreach (Entity entity in entities)
    {
        if (entity != this && entity.Health > 0 && entity.Collides)
        {
            Vector2 diff = entity.Position.ToVector2() - (this.Position.ToVector2() + motion + NetForce);
            float motionLength = motion.Length();
            float forceLength= NetForce.Length();

            for (int i = 0; i < 10 && diff.Length() < (this.Size / 2 + entity.size / 2); i++)
            {
                Vector2 dir = diff;
                dir.Normalize();

                motion -= dir * motionLength / 10.0f;
                NetForce -= dir * forceLength / 10.0f;

                diff = entity.Position.ToVector2() - (this.Position.ToVector2() + motion + NetForce);
            }
        }
    }
}

I check through my list of all entities and see which ones are too close to the current entity, then push them apart a little bit. Since they’re treated as circular, I just have a radius to them in .Size, but that parameter is kept completely separate, and is not used for drawing or animation, only collision.

I think the most important thing is just to make sure you keep this stuff separate. You can have your game object class have an animation object and a collision object, for example. Don’t overthink it too much, if this is your first game *alone the most important thing is to try something and then learn what to not do.

the animation and collision objects are technically already separate, although the collision object contains an animation (or rather a sprite, as not all sprites need to be animated) on the basis that they need to share some position data, although not all.

My opinion is that you should have a …

Sprite Class
SpriteBoundry Class
AnimationSet Class

then within a

AnimatedSprite Class

should be a

AnimationSet List

each object of the above list of objects should contain a

Sprite List
SpriteBoundry List

You should build a editing tool that lets you build a AnimatedSprite file.
Particularly to handle setting the collision areas for each frame of a sprite animation to name the outputed file or read one in. To define the name of a set of sprite animations in a sheet then defines were each sprite is and which frame it belongs to in the spritesheet as well as some way to manually define the bounding areas for that sprite frame by the user.

You should have a AnimatedSpriteReader Class that reads in a animated sprite file. Personally i would allow for the loading of images into the editor swapping of images into another spritesheet and allow for you to manually place boxes or polyhedron points per sprite in a animation for collision detection.

For the Animated sprite class proper it should have methods that check a animation for collisions at a specific frame fluidly, against a point, a list of points, a rectangle or sphere. It should have methods for large boundry checks, ones that surround the entire sprite, for quick collision culling and for more precise checks.
The class itself should contain methods for reading a file or writing a currently loaded file.

The editor should test the save methods against the application that reads them and both should use the AnimatedSprite class to either build or read sprites and there collisions.

The AnimatedSprite Class should hold all the method for accessing manipulating reading and writing a Animated Sprite.

This would be the proper way the way i see it. However this would also consume quite a bit of time and effort.

I’ve actually just created the animation for what I want to do, and for the time being I’m using the position and origin parameters of SpriteBatch.Draw to determine the draw position, and then I will use the resulting bounding box for collision detection.

Can you expand on your class structure a little more?

This is the rough organizational hierarchy which comes to mind.

Class AnimatedSprite 
{
 //
 // The methods to save load a file. 
 // These may vary depending on needs but should be accessible from this class level
 // things such as.
 // Get a texture its source rectangle by its animation name and frame.
 // Get the destination bounding rectangle or polyhedrons for the frame based off the source.
 // Save load a set or a group of animations ect...
 // This may include a texture list for sets of animations.
 //
 //
 List <AnimationSet> animation = new List<AnimationSet>();
 public class AnimationSet
 {
  //
  // The name given to this animation and all its frames.
  //
  public string animationName = "";
  //
  // The time that is to elapse between frames.
  //
  float timeBetweenFramesInSeconds = .32f;
  //
  // the disk file name that the images for this set can be found within.
  //
  public string pngFileName = "";
  //
  // The disk file name if one exists that defines the collision rectangles circles or polyhedrons
  // that correspond to the sprites in the png.
  //
  public string setsBoundryDescriptorFileName = "";
  //
  // A list of sprite objects. 
  // Where index's correspond to the frames of a animation.
  // Responsibility's.
  // Each sprite object describes were a sprite is within a sheet.
  // Its rectangular bounding area as a spritebatch drawing source rectangle.
  //
  List <Sprite> spriteFrames = new List<Sprite>();
  //
  // A list of objects that define for each sprite.
  // All its bounding rectangles circles or polyhedron points.
  // It should have accessor's that act on return these or store them, 
  // in origin corrected coordinates for the destination.
  // (a object of this type may have lists of points rectangles lines or circles).
  //
  List <SpriteBoundry> spriteFramesBoundrys = new List<SpriteBoundry>();

  //
  // Methods that allow retreival of a frame's source rectangle.
  // that allow for collision checks on the drawing destination that 
  // correspond to a frames collision areas.
  // that allow for drawing a frame number to a rectangle destination.
  // Methods that basically act on a spritesheets sprite to simplify things called from the parent class.
  // ect...
  //
  }
}

I would then make a editor that allows one to load a spritesheet and define by draging or clicking the collision rectangles or polyhedrons for each sprite directly working over the sprite sheet viewed.
This would add frames, sprites, boundry’s via the Animation class accessors itself.
The animation class itself should be capable of saving that as a file to disk using the editor and then loading it from disk in game.

If you are interested in the functions used for 2d polyhedron collision detection i can post them.
To me polyhedron collision is simple, efficient, fast and as accurate as desired, that it is imho the best choice between efficiency, (nearly as fast as rectangle circle detection) and cheaper accuracy comparable to (per pixel) for collisions.

It’s a tile based puzzle game so I will just be using rectangles for now, nice and simple. Thanks though :slight_smile:

Reasoning is very important for me.

I’ve noticed one of you has coupled bounding boxes and animation quite strongly, and the other has recommended decoupling the two.

Would either of you embellish on the reasons why you made the decisions that you did?

A quick look through that example and I’ve noticed that my own implementation isn’t actually that far off yours, although I have just used Rectangle[] for source rectangles and bounding boxes, rather than a list of objects.

Another quick question:

How would you go about creating a temporary sprite?

Ie, one that only lasts until it completes and is then deleted?

My reasoning for decoupling these kinds of things is that my sprite animations sometimes reach “out of frame” for things like attacking. My frames are larger than my entities are (hitting my body should count as a collision, hitting my sword should not). If you’re doing a tile based puzzle game, I would imagine this isn’t the case for you.

I decouple images from game objects so that they are interchangeable.
I couple the collision to the sprite because i use polyhedrons and points or lines for collisions with 2d but mainly for the way i would want to call it when using it.
A collision file is tied to a sprite sheet or image that describes in relative coordinates the collision polygons (this could be a custom content loaded file or some type of xml or even just a text file). Thus the call to a animation object should be usable in a simple way for example in my code i would probably want to make simple calls like below.

if( true == animator.CheckCollision( objA.animation, objA.frame, objB.animation, objB.frame) )
{
}

animator.Draw( objA.animation, objA.frame, objA.position, objA.color);

Or possibly even simpler were i might make a spacial grid that interacts with this class to simply flag a bool when a collision occurs like its a event, then deal with it. In that way the initial set up is most of the work and the class’s and editor could be reused in or for other projects.