Download Tutorial C Files H Files

Tutorial : animate

You are following a tutorial that teach you the animation with LIBDRAGON. You'll learn how to create an animator and use it.

Use a spritesheet

With LIBDRAGON, load a spritesheet is really easy.

typedef struct data {
    dg_spritesheet_t *ss;
} data_t;

void *dg_init(dg_window_t *w)
{
    data_t *data = malloc(sizeof(data_t));

    data->ss = dg_spritesheet_create("res/bat.png", 32, 32);
    return data;
}

Here are the parameters :

  1. "res/bat.png" : the path to the spritesheet (.png, .jpeg, .bmp)
  2. 32 : width of a tile, in pixels
  3. 32 : height of a tile, in pixels
Now let's use your spritesheet :

int dg_loop(dg_window_t *w, void *data, sfTime dt)
{
    data_t *d = (data_t *)(data);
    sfSprite *sprite = sfSprite_create();

    sfRenderWindow_clear(w->window, sfBlack);
    dg_spritesheet_to_sprite(d->ss, sprite, 0);
    sfRenderWindow_drawSprite(w->window, sprite, NULL);
    sfSprite_destroy(sprite);
    return 0;
}

How does it works :

  1. d->ss : the spritesheet
  2. sprite : the sprtie wich take the texture
  3. 0 : the id of your tile
You should see your tile appear. Note that the id of your tile is defined as :
This way the spritesheet is really easy to use but need to be done correctly and every tiles need to have the same size.

Finally, let's destroy the spritesheet :

void dg_end(void *data, int id)
{
    data_t *d = (data_t *)(data);

    dg_spritesheet_free(d->ss);
    free(data);
}

Animation

Now let's combine the tiles to make an animation.
First, you'll need to create the animation.

typedef struct data {
    dg_spritesheet_t *ss;
    dg_animation_t *animation;
} data_t;

void *dg_init(dg_window_t *w)
{
    data_t *data = malloc(sizeof(data_t));

    data->ss = dg_spritesheet_create("res/bat.png", 32, 32);
    data->animation = dg_animation_create(data->ss, 10);
    dg_animation_add(data->animation, 1);
    dg_animation_add(data->animation, 2);
    dg_animation_add(data->animation, 3);
    return data;
}

parameters of dg_animation_create:

  1. data->ss : the spritesheet to use
  2. 10 : speed of the animation (the highter, the faster)
parameters of dg_animation_add:
  1. data->animation : the animation to change
  2. 1 / 2 / 3 : the id of the tile used for the animation
It's easy ! First you create an animation by choosing the spritesheet and the speed, then you add the frames of your animation !

Now let's use our new animation. First we need a float to manage the time (called i here) :

typedef struct data {
    dg_spritesheet_t *ss;
    dg_animation_t *animation;
    float i;
} data_t;

void *dg_init(dg_window_t *w)
{
    data_t *data = malloc(sizeof(data_t));

    data->ss = dg_spritesheet_create("res/bat.png", 32, 32);
    data->animation = dg_animation_create(data->ss, 10);
    dg_animation_add(data->animation, 1);
    dg_animation_add(data->animation, 2);
    dg_animation_add(data->animation, 3);
    data->i = 0;
    return data;
}

Now, let's animate !

int dg_loop(dg_window_t *w, void *data, sfTime dt)
{
    data_t *d = (data_t *)(data);

    sfSprite *sprite = sfSprite_create();

    sfRenderWindow_clear(w->window, sfBlack);
    dg_animation_update_sprite(d->animation, sprite, ((int)(d->i)));
    sfRenderWindow_drawSprite(w->window, sprite, NULL);
    d->i += dt.microseconds / 1000000.0 * d->animation->speed;
    sfSprite_destroy(sprite);
    return 0;
}

parameters of dg_animation_update_sprite:

  1. d->animation : the animation to use
  2. sprite : sprite to apply the animation to
  3. ((int)(d->i)) : time, in int
As you can see, the time is not managed by the animation. But we will now see a structure that, not only does manage the time himself, but also manage more than one animation !

Animator

Let's add an animation to use the animator.

typedef struct data {
    dg_spritesheet_t *ss;
    dg_animation_t *animation;
    dg_animation_t *animation2;
    float i;
} data_t;

void *dg_init(dg_window_t *w)
{
    data_t *data = malloc(sizeof(data_t));

    data->ss = dg_spritesheet_create("res/bat.png", 32, 32);
    data->animation = dg_animation_create(data->ss, 10);
    data->animation2 = dg_animation_create(data->ss, 10);

    dg_animation_add(data->animation, 1);
    dg_animation_add(data->animation, 2);
    dg_animation_add(data->animation, 3);

    dg_animation_add(data->animation, 5);
    dg_animation_add(data->animation, 6);
    dg_animation_add(data->animation, 7);

    data->i = 0;
    return data;
}

Now, let's manage them with an animator :

typedef struct data {
    dg_spritesheet_t *ss;
    dg_animation_t *animation;
    dg_animation_t *animation2;
    dg_animator_t *animator;
    float i;
} data_t;

void *dg_init(dg_window_t *w)
{
    data_t *data = malloc(sizeof(data_t));

    data->ss = dg_spritesheet_create("res/bat.png", 32, 32);
    data->animation = dg_animation_create(data->ss, 10);
    data->animation2 = dg_animation_create(data->ss, 10);
    data->animator = dg_animator_create();

    dg_animation_add(data->animation, 1);
    dg_animation_add(data->animation, 2);
    dg_animation_add(data->animation, 3);

    dg_animation_add(data->animation, 5);
    dg_animation_add(data->animation, 6);
    dg_animation_add(data->animation, 7);

    dg_animator_add(data->animator, "first", data->animation);
    dg_animator_add(data->animator, "second", data->animation2);

    data->i = 0;
    return data;
}

parameters of dg_animation_add:

  1. data->animator : the animator to change
  2. "first" / "second" : the key of the animation to differentiate from others
  3. data->animation : the animation to add
You can add as many animation as you want.
Now, let's animate !

int dg_loop(dg_window_t *w, void *data, sfTime dt)
{
    data_t *d = (data_t *)(data);

    sfSprite *sprite = sfSprite_create();

    sfRenderWindow_clear(w->window, sfBlack);
    dg_animator_update_sprite(d->animator, sprite, dt.microseconds);
    sfRenderWindow_drawSprite(w->window, sprite, NULL);
    d->i += dt.microseconds / 100000.0;
    if (d->i > 50)
        dg_animator_set_animation(d->animator, "second");
    sfSprite_destroy(sprite);
    return 0;
}

parameters of dg_animator_update_sprite:

  1. d->animator : the animator to use
  2. sprite : sprite to apply the animation to
  3. dt.microseconds : timelapse, or deltatime
parameters of dg_animator_set_animation:
  1. d->animator : the animator to change
  2. "second" : key/name of the animation

Now you know how to animate with LIBDRAGON !

Full code

#include 
#include "libdragon.h"

typedef struct data {
    dg_spritesheet_t *ss;
    dg_animation_t *animation;
    dg_animation_t *animation2;
    dg_animator_t *animator;
    float i;
} data_t;

void *dg_init(dg_window_t *w)
{
    data_t *data = malloc(sizeof(data_t));

    data->ss = dg_spritesheet_create("res/bat.png", 32, 32);
    data->animation = dg_animation_create(data->ss, 10);
    data->animation2 = dg_animation_create(data->ss, 10);
    data->animator = dg_animator_create();

    dg_animation_add(data->animation, 1);
    dg_animation_add(data->animation, 2);
    dg_animation_add(data->animation, 3);

    dg_animation_add(data->animation2, 5);
    dg_animation_add(data->animation2, 6);
    dg_animation_add(data->animation2, 7);

    dg_animator_add(data->animator, "first", data->animation);
    dg_animator_add(data->animator, "second", data->animation2);

    data->i = 0;
    return data;
}

int dg_loop(dg_window_t *w, void *data, sfTime dt)
{
    data_t *d = (data_t *)(data);

    sfSprite *sprite = sfSprite_create();

    sfRenderWindow_clear(w->window, sfBlack);
    dg_animator_update_sprite(d->animator, sprite, dt.microseconds);
    sfRenderWindow_drawSprite(w->window, sprite, NULL);
    d->i += dt.microseconds / 100000.0;
    if (d->i > 50)
        dg_animator_set_animation(d->animator, "second");
    sfSprite_destroy(sprite);
    return 0;
}

void dg_end(void *data, int id)
{
    data_t *d = (data_t *)(data);

    dg_spritesheet_free(d->ss);
    dg_animator_free(d->animator);
    free(data);
}

int main(int argc, char **argv)
{
    dg_play(1920, 1080, "LibDragon", 200);
    return 0;
}