Variable speed tracking

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 structs 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!

The gif doesn’t loop properly, so download the ROM below!

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!

Leave a comment

Your email address will not be published. Required fields are marked *