Working with Sprites

In this example we'll learn how to display a sprite on the screen, then increment through its frames and move it around.

Displaying Sprites

This is the sprite (and frames) we are going to show.

To start we need to use the following directives for HuCC to load and process our sprite. Do this at the beginning of the file.

#incspr(logo, "logo.png", 0, 0, 2, 12)
#incpal(logo_pal, "logo.png")

Because our sprite is 32pixels wide and has 6 frames, it is a 'double sprite', so the values 2, and 12 are important here.

Set up our main function to load sprite into VRAM, and the palette.

void main() {
    load_palette(16, logo_pal, 1);
    load_vram(0x5000, logo, 0x800);
}

With that done, let's break this down because it can get complicated the first time.

Inside the main function, first we have to initialise the Sprite Attribute Table (SATB). We need to do this before we can do anything with displaying sprites.

init_satb();

Next we set which sprite we want to modify, 0 in this case as it is the first.

spr_set(0);  

Now set the default position of where we want the sprite to be displayed.

spr_x(0);
spr_y(0);

For the attributes of the sprite we need to set its data that loaded into VRAM at address 0x5000 .

Then the spr_ctrl that defines the sprite size, in this case 32x32, and not not flipped.

spr_pattern(0x5000);
spr_ctrl(FLIP_MAS|SIZE_MAS, NO_FLIP|SZ_32x32);

Set the palette we want to use, again 0 as it is the first, and the priority also to 0 for now.

spr_pal(0);
spr_pri(0);

Finally we need to tell the SATB to update.

satb_update();

With all that done you should now see the sprite on the screen:

If you need to check, here is the complete code for showing the sprite up to this point:

Complete code for displaying a sprite
#include <huc.h>

#incspr(logo, "logo.png", 0, 0, 2, 12)
#incpal(logo_pal, "logo.png")

void main() {

    load_palette(16, logo_pal, 1);
    load_vram(0x5000, logo, 0x800);

    init_satb();

    spr_set(0);
    spr_x(0);
    spr_y(0);
    spr_pattern(0x5000);
    spr_ctrl(FLIP_MAS|SIZE_MAS, NO_FLIP|SZ_32x32);
    spr_pal(0);
    spr_pri(0);

    satb_update();
}

Animating a Sprite

With our sprite displayed on screen, let's have some fun with it.

We'll want to make it bounce around the screen and change frame when it hits a side of the screen.

Let's add some constants and variables in our main above where we draw the sprite:

#define SCREEN_WIDTH 232
#define SCREEN_HEIGHT 184

int speedx = 1;  // X velocity
int speedy = 1;  // Y velocity
int logox = 100; // Starting x position
int logoy = 100; // Starting y position
int frame = 0;   // Current animation frame

Following the last line of drawing the sprite we need a while loop and some conditions:

    while(1) {
        // Update position
        logox += speedx;
        logoy += speedy;

        // Bounce off screen edges
        if(logox <= 0 || logox >= SCREEN_WIDTH-8) {
            speedx = -speedx;
            frame = (frame + 1) % 6;
        }
        if(logoy <= 0 || logoy >= SCREEN_HEIGHT+8) {
            speedy = -speedy;
            frame = (frame + 1) % 6;
        }

        // Update sprite
    }

This is fairly basic stuff that adds the velocity to the position of the sprite so that it moves , then checks if it has collided with the bounds of the screen.

We're adjusting the screen height and width by 8, to account for the sprite.

This line is how we update the frame of the animation, using a modulo to ensure that the number never exceeds the maximum number of frames, 6 in this case.

frame = (frame + 1) % 6;

Now in the while loop we need to pass this to update the sprite.

First, again we need to say which sprite we are updating:

spr_set(0);

Then set the x and y positions of the sprite again:

spr_x(logox);
spr_y(logoy);

Here we update the data in the sprite pattern based on the frame, from the data in VRAM.

spr_pattern(0x5000 + (frame * 0x100));

Now update the sprite:

satb_update();

Finally, we need to add a vsync() so that we lock the rendering to 60fps.

Compile and run:

And there we have our sprite moving, bouncing and changing colour!

You can download the sprite used in this example here
Complete code for this example
#include <huc.h>

#incspr(logo, "logo.png", 0, 0, 2, 12)
#incpal(logo_pal, "logo.png")

void main() {
    #define SCREEN_WIDTH 232
    #define SCREEN_HEIGHT 184

    int speedx = 1;  // X velocity
    int speedy = 1;  // Y velocity
    int logox = 100; // Starting x position
    int logoy = 100; // Starting y position
    int frame = 0;   // Current animation frame

    init_satb();

    // Initialize sprite 0
    spr_set(0);
    spr_x(logox);
    spr_y(logoy);
    spr_pattern(0x5000);
    spr_ctrl(FLIP_MAS|SIZE_MAS, NO_FLIP|SZ_32x32);
    spr_pal(0);
    spr_pri(1);

    // Load sprite data and palette
    load_palette(16, logo_pal, 1);
    load_vram(0x5000, logo, 0x800);
    satb_update();

    while(1) {
        // Update position
        logox += speedx;
        logoy += speedy;

        // Bounce off screen edges
        if(logox <= 0 || logox >= SCREEN_WIDTH-8) {
            speedx = -speedx;
            frame = (frame + 1) % 6;
        }
        if(logoy <= 0 || logoy >= SCREEN_HEIGHT+8) {
            speedy = -speedy;
            frame = (frame + 1) % 6;
        }

        // Update sprite
        spr_set(0);
        spr_x(logox);
        spr_y(logoy);
        spr_pattern(0x5000 + (frame * 0x100));

        satb_update();
        vsync();
    }
}

Last updated