Jono Shields

Animation, Movement and Backgrounds

[gamejam][gbagamejam2021]

GBAGameJam - Day 3

Animation

Today I am tackling animation, not for any specific purpose, but just because I have the assets for them already.

We can use Butano's create_sprite_animate_action_forever to kick off the animation.

Also just note that throughout using Butano you will see the use of Actions, they allow you to do transformations to a sprite over time. Read more here.

So getting the animation working is pretty simple...

#include "bn_sprite_animate_actions.h"

bn::sprite_animate_action<9> action = bn::create_sprite_animate_action_forever(
                    cat_sprite, 6, bn::sprite_items::cat.tiles_item(), 1, 2, 3, 4, 5, 6, 7, 8, 9);

Here I am using my cat sprite...

So we can call bn::create_sprite_animate_action_forever and pass in the cat_sprite sprite, the 6 delay between frames, the bn::sprite_items::cat.tiles_item() tiles item and a 1, 2, 3, 4.. list of frames to use.

Docs for this here.

Note that my cat sprite has 10 frames, but the above code only uses 9 of them, we skip frame[0] because it is an idle frame and I just wanted to make the cat run.

So now we have the cutest running cat...

Let's keep going!

Movement

The thing that immediately sprung to mind was "okay now we have to make it move".

So I had a quick look at the keypad example in Butano and made the following in my loop...

#include "bn_keypad.h"

if(bn::keypad::left_held())
{
    cat_sprite.set_x(cat_sprite.x() - 1);
}
else if(bn::keypad::right_held())
{
    cat_sprite.set_x(cat_sprite.x() + 1);
}

if(bn::keypad::up_held())
{
    cat_sprite.set_y(cat_sprite.y() - 1);
}
else if(bn::keypad::down_held())
{
    cat_sprite.set_y(cat_sprite.y() + 1);
}

I am trying to add the header files that you need too, but the best way to use these examples is probably to look for the tag for today.. day-3

Yay! It moves!

Background

Now to add a background image so our cat can explore something...

#include "bn_affine_bg_ptr.h"
#include "bn_affine_bg_item.h"

#include "bn_affine_bg_items_map.h"

bn::affine_bg_ptr map_bg = bn::affine_bg_items::map.create_bg(0, 0);

Okay, so I don't know if it is working or not. I am guessing most of the image would be off the screen anyway because it is 512x512 but I only use a very small area of it.

Let's jump straight into the camera so we can move it around and find our background.

Camera

So I just finished trying to implement it, but I still don't really know how it works. Let's go through this together!

I added the following...

#include "bn_camera_actions.h"

bn::camera_ptr camera = bn::camera_ptr::create(0, 0);

while(true)
{
    if(bn::keypad::right_held())
    {
        cat_sprite.set_x(cat_sprite.x() + 1);
        camera.set_x(camera.x() + 1);
    }
    ...
    
    // Below is what confuses me, the docs say 'Sets the camera_ptr attached to this sprite', but why would we need it on the bg and the sprite? Because we do, it won't move otherwise. Any ideas?
    cat_sprite.set_camera(camera);
    map_bg.set_camera(camera);
}

This way, when the cat moves, then the camera follows.

Ah! There is my background.

Logging

Okay I don't understand this co-ordinate system. Lets try to figure that out.

Luckily logging is pretty simple with Butano.. BN_LOG("Hello World!");

#include "bn_log.h"
BN_LOG("sprite-x");
BN_LOG(cat_sprite.x());
BN_LOG("sprite-y");
BN_LOG(cat_sprite.y());

Have I figured out how to concatenate ints and strings in c++ yet? No! So lots of lines of logging it is.

If you are using mgba you can set the log level when you run by commandline. I use the following to build and launch my .gba at the same time.

make -j4 && mgba feline.gba -l 4

  • -j4 is telling the compiler that I have 4 cores it can utilise
  • -l 4 sets mgba to log level 4 so that you can see the logging we added.

Background Part 2

Okay, so now I can move the BG to the right place..

bn::affine_bg_ptr map_bg = bn::affine_bg_items::map.create_bg(128, -176);

Looking good.

Want to get notified next time I post?