Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

2d Sprite Animations without using XNA or other third-party libraries

I want to create a simple game, similar to what can be created with RPG Maker. What I am primarily looking for at the moment is a tutorial which can guide me on how to accomplish it without using XNA or any other specific library.

The ideal would be a step-by-step tutorial or a good, easy-to-understand example.

My goal is to do it on my own, and come to an understanding of how the overall process works with regards to animation elements relating to one another.

I've already built a simple snake game in the past using a simple tutorial, but there was no movement animation in it and that's the primary thing I'm wanting to learn next.

Edit:

All of the tutorials I have found so far use third-party libraries. I did come across this link, but I'm looking for something which doesn't include XNA.

like image 824
WiiMaxx Avatar asked Apr 19 '13 19:04

WiiMaxx


Video Answer


3 Answers

There are a number of ways to approach the topic you're describing. I'm going to give a bit of an overview, and then hopefully provide some resources which can give you examples to get you started.

Essentially, sprite-based animations revolve around having a series of similar images which, when displayed sequentially, create the appearance of motion, similar to a flip-book.

The trick is to understand when your sprite is moving (and therefore should be animated) - and when it is standing still (and therefore should not be animated). In other words - assuming that your game's character is only supposed to move while you hold , , or , you need to detect when one of those keys starts and stops being pressed, so that you can start/stop your animation accordingly.

Imagine that for simplicity, you only have 2 sprites. The first (left, below) represents your character standing still, and the second represents your character mid-step (right, below):

Mario

When the button is not pressed, you simply continually display the first image. When the button is pressed, you toggle between the two every x milliseconds (depending on how fast you want the animation to appear).

An animated .gif is one format in which you can contain a series of simple image frames, which are intended to be displayed as a series (and therefore create the illusion of animation). If you were to create your sprites using this format, you could use code similar to that found in this SO discussion, which provides some example code for how to use C# to animate an animated .gif and control its start/stop.

Alternatively, if you wanted to use a sprite file (like the one I included above), you could use something similar to this CodeProject code, which focuses on GDI interaction with the Windows environment in order to extract and paint a portion of the sprite onto a target canvas. By repainting every x milliseconds (as mentioned above), this can provide the same effect.

A few things to keep in mind:

You'll need to handle transparency in your sprites (the Mario sprite above, as an example, has a transparent background) - so that the background of your game environment shows through. If using GDI - this all has to do with how you call the painting methods. If using an animated .gif - the method to use depends on how you display it on your window.

For some additional resources / examples / references, check out the following resources:

  • Intermediate C# Game Making Tutorial - 2 - Sprites
  • 2D Game Primer (Visual C) - an older article which talks quite a bit about the concepts of sprite animation, timing and such - and gives some example code (some DirectX in examples)
  • Sprite.cs - an example of some C# manipulation code for dealing with sprites and sizing (uses OpenGL, so may not be applicable)

And for Sprite development:

  • SpritePad - a tool for creating Sprite Sheets
  • http://makeagif.com/ - a tool for creating animated gifs online
  • http://picasion.com/ - another animated gif creator
like image 142
Troy Alford Avatar answered Nov 15 '22 18:11

Troy Alford


I threw together than example of what I think it is that you were after. This example can be applied to buttons or picture boxes. I chose this way of out of simplicity.

Each instance of an animation holds a timer, and a list of images. Updating the image of the target control whenever the timer fires its event.

I have uploaded my project file here. http://mcspazzy.com/code/ParTest.zip

Hopefully it is enough to help. Just ask if you need more explanation.

The class

public class Animation
{
    readonly Timer _animtimer = new Timer();

    public List<Image> Frames;

    public int FrameIndex;

    private Button _target;
    private PictureBox _ptarget;

    public void Target(PictureBox target)
    {
        _ptarget = target;
    }

    public void Target(Button target)
    {
        _target = target;
    }

    public int FrameSpeed
    {
        get { return _animtimer.Interval; }
        set { _animtimer.Interval = value; }
    }

    public Animation()
    {
        Frames  = new List<Image>();
        _animtimer.Interval = 100;
        _animtimer.Tick += Update;
    }

    public void Play()
    {
        _animtimer.Start();
    }

    public void AddFrame(string file)
    {
        Frames.Add(Image.FromFile(file));
    }

    public void Stop()
    {
        _animtimer.Stop();
    }

    private void Update(object sender, EventArgs eventArgs)
    {
        FrameIndex++;

        if (FrameIndex == Frames.Count)
        {
            FrameIndex = 0;
        }
        _target.Image = Frames[FrameIndex];
        _ptarget.Image = Frames[FrameIndex];
    }

    public static implicit operator Image(Animation a)
    {
        return a.Frames[a.FrameIndex];
    }
}

This was in my Form load. Can really go anywhere that stuff is initialized.

    private void Form1Load(object sender, EventArgs e)
    {

        _testAnim.AddFrame(@"F:\Im\Black.png");
        _testAnim.AddFrame(@"F:\Im\Blue.png");
        _testAnim.AddFrame(@"F:\Im\Green.png");
        _testAnim.AddFrame(@"F:\Im\Orange.png");
        _testAnim.AddFrame(@"F:\Im\Red.png");



        _testAnim.Target(ButtonTest);
        _testAnim.Target(PicBox);


        _testAnim.Play();


    }
like image 39
Andy Avatar answered Nov 15 '22 16:11

Andy


On quick search I found this example. I'm not very experienced in c# graphics, but here are few points I have learned working with non-graphic oriented languages:

  • Declare where/what you want to draw
  • Create a loop to run until abort/event to end the loop (like object colliding with something)
  • In the loop: wait, clear the old drawing area, recalculate new position, draw in new position
  • If needed you can change the image to draw too, but then you need separate images for each "frame" you want to have
  • multithreading is a good idea, so you can separate running the graphics from other game logic
  • try keeping the time from clearing the drawing area and re-drawing as short as possible to prevent flickering
  • Keep track of the size of objects you draw, makes it easier to check for collision (like center of the sprite + radius, then you can easily calculate a circle area around it to check if two sprites are too close to each other)
like image 29
Sopuli Avatar answered Nov 15 '22 17:11

Sopuli