Changing images [HELP] [SOLVED]

Hello Arduboy Community! I just got my hands on an Arduboy for Christmas and have started working on a remake of a game i made for Pico-8 called Space Delivery.

I’m storing sprites for moving left, right, up and down as separate still images in PROGMEM like so:

//Player Sprites
const unsigned char player_spr_l[] PROGMEM = {
  0x18, 0x3c, 0x3c, 0x3c, 0x7e, 0x7e, 0x66, 0x66
};

const unsigned char player_spr_r[] PROGMEM = {
  0x66, 0x66, 0x7e, 0x7e, 0x3c, 0x3c, 0x3c, 0x18
};

const unsigned char player_spr_u[] PROGMEM = {
  0x00, 0xf0, 0xfe, 0x3f, 0x3f, 0xfe, 0xf0, 0x00
};

const unsigned char player_spr_d[] PROGMEM = {
  0x00, 0xf, 0x7f, 0xfc, 0xfc, 0x7f, 0xf, 0x00
};

I want to be able to draw them using:

arduboy.drawBitmap(x,y, spr, 8,8, WHITE);

Where I can assign spr like:

if(right) {spr = player_spr_r;}

When I do this, however, the sprite comes out as a jumbled mess.
When I use ’ arduboy.drawBitmap(x,y, player_spr_r, 8,8, WHITE); ’ for example, the correct image is drawn to the screen.

Any help with this would be greatly appreciated and I can supply more info and source if needed.

2 Likes

What is the type of spr?

It should be a const uint8_t * (or const unsigned char *, on the Arduboy uint8_t is the same as unsigned char).
(i.e. declared as const uint8_t * spr = nullptr;)


As a side note, you can also use the Sprites class from Arduboy2 which encodes the width and height in the image and allows the image to have multiple frames.

So your images would look like:

const uint8_t playerSprite[] PROGMEM =
{
  // Dimensions
  8, 8,
  // Frame 0 - Left
  0x18, 0x3C, 0x3C, 0x3C, 0x7E, 0x7E, 0x66, 0x66,
  // Frame 1 - Left
  0x66, 0x66, 0x7E, 0x7E, 0x3C, 0x3C, 0x3C, 0x18,
  // Frame 2 - Up
  0x00, 0xF0, 0xFE, 0x3F, 0x3F, 0xFE, 0xF0, 0x00,
  // Frame 3 - Down
  0x00, 0xF, 0x7F, 0xFC, 0xFC, 0x7F, 0x0F, 0x00,
};

And then you could draw with:

// 0 for Left
Sprites::drawOverwrite(x, y, playerSprite, 0);
// 1 for Right
Sprites::drawOverwrite(x, y, playerSprite, 1);
// 2 for Up
Sprites::drawOverwrite(x, y, playerSprite, 2);
// 3 for Down
Sprites::drawOverwrite(x, y, playerSprite, 3);

Thanks for the reply!

I’ve managed to get changing sprites working by storing the images as ’ const unsigned char 's and using the ’ spr ’ variable as a pointer. Didn’t want to do anything too complicated for my first Arduino project / game but I’ll probably use the Sprite functions in the Arduboy2 library in the future.

I’ve only just started learning C++ and Arduboy’s API so I’m still getting used to how it all works.

No problem.

I just thought I’d mention it as an alternative since it’s generally easier (and slightly cheaper) to work with frame numbers instead of pointers.

Yup from what I’ve seen in other peoples sketches it looks like the best route for drawing sprites, I’ll have to give it a go at some point.

1 Like

Ugh… I was right in thinking uint_8_t was a data type.
Just unsigned char? :no_mouth:
Okay.

unsigned char is also a datatype.

And uint8_t isn’t always unsigned char, it depends on the system that’s being compiled for. The type uint8_t is only defined if the compiler supports C++11 and the target processor is capable of working on valyes of exactly 8 bits. If the smallest unit the processor could natively handle is 10 bits or 16 bits then uint8_t wouldn’t exist and any code using it wouldn’t compile.
(e.g. certain digital signal processors, like the TI C54x which can’t process anything smaller than 16-bit values.)

Essentially, using uint8_t is a way of telling people “this code assumes that this type is 8-bits, any other size might not work properly”
Using unsigned char instead means that your code could possibly compile for a system where char is 10-bits, but might not work properly.

For example:

unsigned char b = ~0; // ~0 is a value where all bits are 1
b >>= 8;
if(b == 0)
{
    // <= 8 bit system
}
else
{
    // > 8 bit system, e.g. 10-bit system
}
1 Like

Don’t see a right-shift and assignment operator too often …

2 Likes