I am working on a little dungeon game. I’m not a super experienced C++ programmer. I wrote a class for my Monsters, but I’m not exactly sure how I can attach a sprite declared as a const in progmem when I create an instance.
There’s a couple of options, but the easiest might just be to use a pointer to the sprite data.
Assuming your sprite is of the form uint8_t monsterSprite[]
You could add the field to your class
enemy(const char * name, const uint8_t * sprite, int lvl)
//whatever is in your construtor + * sprite
{
//rest of monster constructor
const * pointerToMySprite = sprite;
}
and you can just draw it with
arduboy.drawBitmap(x, y, monster.pointerToMySprite, xDimension, yDimension, WHITE);
You can also use the Sprites
class to draw it but I forget the syntax off the top of my head. I’m sure someone else will comment on that. Sprites is better overall but I think bitmap is a litter easier to work with if its your first game for the arduboy.
It would have to be a const uint8_t *
.
The way you’ve written it there you’re assigning it to a local uint8_t *
variable.
Something more like:
class Monster
{
private:
const uint8_t * sprite;
// Other fields
public:
Monster(const uint8_t * sprite, /* other parameters */) :
sprite(sprite), // etc
{
}
const uint8_t * getSprite() const
{
return this->sprite;
}
};
It’s:
Sprites::drawOverwrite(x, y, sprite, frame);
(As documented here.)
dropped the const. I always drop something.
I’m guessing @bridge2nowhere might not know about initialising lists though.
I don’t know which sprite drawing method @bridge2nowhere wants to use but Sprites::drawSelfMasked() is a better equivalent to Arduboy2Base::drawBitmap() than Sprites::drawOverwrite() is.
Fair enough, but they’re easy enough to understand.
Though if transparency is needed then using a proper mask is usually a better option than either.
Is there a benefit to using uint8_t over unsigned char as a datatype for the sprites?
Though you can use drawBitmap() to do proper masking. You use a bitmap for the pixels you want black and set the drawBitmap() color parameter to BLACK. You then use a bitmap for the pixels you want white and call drawBitmap() again with the color parameter set to WHITE, at the same coordinates. The pixels not set to 1 in either bitmap will then be transparent (left unchanged).
You can also do the same thing with a combination of Sprites::drawErase() and Sprites::drawSelfMasked().
That said, Sprites::drawPlusMask() or Sprites::drawExternalMask() are usually better options for this.
Something weird happened, my sprites no longer show up correctly. They show up as the right size, and still move around.
I’m sure I did something silly, but if any of you could take a look at this, I would appreciate it.
Your last commit didn’t actually change anything.
The version on GitHub seems to be drawing correctly.
If I remember right they’re actually the same thing.
It doesn’t matter though. Just make the pointer a char
I uploaded the wrong code, it’s been fixed (I uploaded the correct files, my issue hasn’t been fixed).
There’s no major benefit, on Arduboy at least unsigned char
and uint8_t
are the same type.
Although if someone were trying to port the code to a different system then using uint8_t
is probably a better indicator that you intend the type to be exactly 8 bits.
(On some systems unsigned char
might be larger than 8 bits, whereas uint8_t
will either be 8 bits or won’t exist.)
You remember rightly:
https://www.nongnu.org/avr-libc/user-manual/group__avr__stdint.html
The problem is here:
Monster::Monster(byte health, byte att, byte def, byte imgSize, const uint8_t * sprite)
{
hp = health;
attMod = att;
ac = def;
spriteSize = imgSize;
posnX = 8;
posnY = 8;
// This is assigning to a local variable
const uint8_t * pointerToMySprite = sprite;
};
You need to do this instead:
Monster::Monster(byte health, byte att, byte def, byte imgSize, const uint8_t * sprite)
{
hp = health;
attMod = att;
ac = def;
spriteSize = imgSize;
posnX = 8;
posnY = 8;
// This is assigning to a member variable
pointerToMySprite = sprite;
};
For future reference, to make sure you’re assigning to a member variable you can put this->
in front of the variable.
E.g.
Monster::Monster(byte health, byte att, byte def, byte imgSize, const uint8_t * sprite)
{
this->hp = health;
this->attMod = att;
this->ac = def;
this->spriteSize = imgSize;
this->posnX = 8;
this->posnY = 8;
this->pointerToMySprite = sprite;
};
If any of the names after this->
aren’t member variables you’ll get an error.
This approach also allows you to use the same name for both member variables and function parameters.
E.g.
Monster::Monster(byte hp, byte attMod, byte ac, byte spriteSize, const uint8_t * pointerToMySprite)
{
this->hp = hp;
this->attMod = attMod;
this->ac = ac;
this->spriteSize = spriteSize;
this->posnX = 8;
this->posnY = 8;
this->pointerToMySprite = pointerToMySprite;
};
Oh jeez you know I completely gapped on the local thing.
It’s because I had just written that uint8_t
part then went back and added the constructor around it to give more context. @bridge2nowhere my mistake leading you astray, I really should of caught that one. I’ve fixed it in my original post in-case someone else ever reads this.
No harm done.
猿も木から落ちる。
Or in English: even monkeys fall from trees.
(Sorry, couldn’t resist. I’ve been waiting at least a month to have an excuse to say that.)
Thank you, I’m all fixed now!
I just love that expression. Must memorise thato one!
If you want to know how to pronounce it, it’s “saru mo ki kara ochiru”.
- ‘saru’ (猿) means monkey (as in nihonzaru (ニホンザル, from 日本 and 猿).)
- ‘mo’ (も) means ‘even’ (or ‘as well as’, or ‘also’)
- ‘ki’ (木) means tree
- ‘kara’ (から) means ‘from’ (or ‘out of’),
- ‘ochiru’ (落ちる) is the verb meaning means ‘to fall’ (or ‘to drop’)
Though given your knowledge of たまごっち I wouldn’t be surprised if you already knew some of those words.
(I knew saru, mo and ki, but not kara and ochiru.)
If you want to know some more Japanese idioms/proverbs/kotowaza (ことわざ) then let me know.
(I’ve been collecting resources discussing them.)
But it’s probably best to do it in a PM or separate thread,
I think this thread has been derailed enough for now.