If you had the code to show and the error messages it gave then there are plenty of people who could have helped debug it.
Without that it’s impossible to know what went wrong, but if I had to guess I’d say there were syntax rules you weren’t following (e.g. you missed a semicolon). C++ has lots of rules and generally stricter syntax than more modern languages.
When programming for the Arduboy it’s important to get a balance of OO and procedural. Too much OO and you chew up memory because OO features generally cost memory (especially virtual functions), but equally not using OO features results in much messier code.
Normally I’d say don’t have a sprite class because it would need its own x and y coordinate, which would most likely lead to duplication because your player/entity will probably already have an x and y, but I’ll give an example anyway.
Also note that you don’t have to have both a .cpp
and a .h
, you can get away with just a .h
in most cases.
// Sprite.h
class Sprite
{
public:
// Up to you whether you getter+setter these
// It probably won't have a performance cost either way
const uint8_t * bitmap;
uint8_t frame;
// I'm using int16_t because I assume you might want to go off the side of the screen
int16_t x;
int16_t y;
public:
Sprite(const uint8_t * bitmap);
Sprite(const uint8_t * bitmap, int16_t x, int16_t y);
Sprite(const uint8_t * bitmap, uint8_t frame, int16_t x, int16_t y);
void draw(void); // void in the brackets is optional
}; // Note the semicolon, this is mandatory
// Sprite.cpp
// Required
#include <Sprite.h>
// Note the scoping
Sprite::Sprite(const uint8_t * bitmap)
: bitmap(bitmap), frame(0), x(0), y(0) // C++11 field initialisers
{
}
Sprite::Sprite(const uint8_t * bitmap, int16_t x, int16_t y)
: bitmap(bitmap), frame(0), x(x), y(y)
{
}
Sprite::Sprite(const uint8_t * bitmap, uint8_t frame, int16_t x, int16_t y)
: bitmap(bitmap), frame(frame), x(x), y(y)
{
}
// Again, note the scoping operator
void Sprite::draw(void)
{
Sprites::drawOverwrite(this->x, this->y, this->bitmap, this->frame);
}
I’d like to reiterate though that this is wasteful for several reasons.
On top of the potentially duplicated state, you’re left with the issue that there are many different ways to draw a sprite, so you’re forced to either have multiple classes for each case (in which case the object is no more than a glorified functor) or to incorporate a mechanism for choosing a drawing function (which means yet more RAM usage).
To someone used to everything being classes it probably seems backwards to think that an object might not be the recommended solution, but OO comes at a cost and that cost is sometimes too much for the embedded world. You have to know when to use an object and when to just use functions even if it’s not as flexable or doesn’t look as clean.