# Working with Sprites

## Displaying Sprites

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

<figure><img src="/files/QP4zad2TyjiV0zKozWMw" alt=""><figcaption></figcaption></figure>

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.

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

{% hint style="info" %}
Because our sprite is 32pixels wide and has 6 frames, it is a 'double sprite', so the values 2, and 12 are important here.
{% endhint %}

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

```c
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.

```c
init_satb();
```

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

```c
spr_set(0);  
```

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

```c
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.

```c
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.

```c
spr_pal(0);
spr_pri(0);
```

Finally we need to tell the SATB to update.

```c
satb_update();
```

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

<figure><img src="/files/T7NShLVyyNaLchrBP0ud" alt=""><figcaption></figcaption></figure>

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

<details>

<summary>Complete code for displaying a sprite</summary>

<pre class="language-c"><code class="lang-c"><strong>#include &#x3C;huc.h>
</strong>
#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();
}
</code></pre>

</details>

## 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:

```c
#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:

```c
    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.

{% hint style="info" %}
We're adjusting the screen height and width by 8, to account for the sprite.
{% endhint %}

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.

```c
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:

```c
spr_set(0);
```

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

```c
spr_x(logox);
spr_y(logoy);
```

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

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

Now update the sprite:

```c
satb_update();
```

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

Compile and run:

<figure><img src="/files/PMJVG2QYNNi8Kq0r6BRo" alt=""><figcaption></figcaption></figure>

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

{% file src="/files/QP4zad2TyjiV0zKozWMw" %}
You can download the sprite used in this example here
{% endfile %}

<details>

<summary>Complete code for this example</summary>

```c
#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();
    }
}
```

</details>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://aeriform.gitbook.io/hucc/getting-started/working-with-sprites.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
