Quick one tonight.
I’ve been chewing over the thoughts I had last time about stuff on screen needing to do stuff at different speeds and keeping track of it all, so tonight I want to try out a proof of concept throwing things into struct
s and having each sprite keep track of whether it was time to do a thing or not as the run loop passed by.
I made a basic animation (a little orbiting thingy) and created three instances set to animate at different speeds.
The basic instance was the same, except each one tracked which sprite id it was assigned (necessary) and tallied up the number of run loops since it last animated. If the loop count was the same as its individually assigned number-of-loops-before-you-animate number, it updated its sprite and reset the count.
It worked!
Oh hey, would you like to see the code? 3 files: orbit.c
for the sprite data, Orbiter.c
for the struct, and varitrack.c
for the actual “game” code.
# orbit.c
unsigned char orbit[] =
{
0x00,0x02,0x00,0x07,0x18,0x1A,0x3C,0x3C,
0x3C,0x3C,0x18,0x18,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x04,0x10,0x1E,0x38,0x3C,
0x3C,0x3C,0x18,0x18,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x18,0x18,0x2C,0x3C,
0x04,0x3C,0x08,0x18,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x18,0x18,0x3C,0x3C,
0x1C,0x3C,0x08,0x78,0x00,0x20,0x00,0x00,
0x00,0x00,0x00,0x00,0x18,0x18,0x3C,0x3C,
0x3C,0x3C,0x18,0x58,0x00,0xE0,0x00,0x40,
0x00,0x00,0x00,0x00,0x18,0x18,0x3C,0x3C,
0x3C,0x3C,0x18,0x78,0x00,0x20,0x00,0x00,
0x00,0x00,0x00,0x00,0x18,0x18,0x3C,0x3C,
0x3C,0x3C,0x18,0x18,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x04,0x18,0x1E,0x3C,0x3C,
0x3C,0x3C,0x18,0x18,0x00,0x00,0x00,0x00
};
# Orbiter.c
#include <gb/gb.h>
struct Orbiter {
UINT8 spriteid;
UINT8 framessincelastanimation;
UINT8 animationspeed;
UINT8 currentanimationframe;
};
# varitrack.c
#include <gb/gb.h>
#include <gb/drawing.h>
#include "orbit.c" // Sprites
#include "Orbiter.c" // "Orbiter" struct
struct Orbiter orbiter_slow;
struct Orbiter orbiter_medium;
struct Orbiter orbiter_fast;
void setuporbiter(struct Orbiter* orbiter) {
orbiter->currentanimationframe = 0;
orbiter->framessincelastanimation = 0;
}
void animateorbiter(struct Orbiter* orbiter) {
if (orbiter->framessincelastanimation == orbiter->animationspeed) {
// animate!
orbiter->currentanimationframe += 1;
if (orbiter->currentanimationframe == 8) {
orbiter->currentanimationframe = 0;
}
orbiter->framessincelastanimation = 0;
} else {
// increment frame
orbiter->framessincelastanimation += 1;
}
set_sprite_tile(orbiter->spriteid, orbiter->currentanimationframe);
}
void main() {
// Load the sprite data
set_sprite_data(0, 8, orbit);
// Set the defaults for each orbiter
setuporbiter(&orbiter_slow);
setuporbiter(&orbiter_medium);
setuporbiter(&orbiter_fast);
// set up sprite references
orbiter_slow.spriteid = 0;
orbiter_medium.spriteid = 1;
orbiter_fast.spriteid = 2;
// Set up the different animation speeds
orbiter_slow.animationspeed = 20;
orbiter_medium.animationspeed = 10;
orbiter_fast.animationspeed = 5;
// Initial setup
set_sprite_tile(0, 0);
move_sprite(0, 20, 20);
set_sprite_tile(1, 0);
move_sprite(1, 30, 30);
set_sprite_tile(2, 0);
move_sprite(2, 40, 40);
SHOW_SPRITES;
while(1){
// Animate each of them
animateorbiter(&orbiter_slow);
animateorbiter(&orbiter_medium);
animateorbiter(&orbiter_fast);
wait_vbl_done();
}
}
I imagine that keeping the orbiter objects in some kind of array would simplify the code further. I’d also look to have them move about at different speeds. Largely though that’s just extrapolation of this proof of concept, which works! Hurrah!
Time Spent: 30 minutes. I’m getting quicker!