Name your .ino file Pyoro.ino instead of Project.ino so people compiling using the Arduino IDE don’t have to rename it or put it in a folder named Project.
It would be a good idea to include arduboy.flashlight() after arduboy.boot(), to allow recovery if a version of the game ever causes the “bootloader magic key” problem.
Forcing audio on in setup() may annoy some people who wish to play the game with sound muted. You should use arduboy.audio.begin() instead of arduboy.audio.on().
Along with the previous suggestion; since the game has no way for the user to toggle sound on and off, you could include arduboy.systemButtons() before arduboy.audio.begin() so the mute state can be set during startup.
Or, instead of all the extra function calls in setup, you could just use arduboy.begin() instead of arduboy.boot()
The first 16 bytes of EEPROM are reserved for system use (such as saving the mute state). Sketches must only use EEPROM locations starting at or after the defined value EEPROM_STORAGE_SPACE_START
Difficulty now increases for every 500 points you score. Beans go faster, spawn more often and Pyoro goes faster too.
Save magic changed since the difficulty and gameplay are different, so you will lose your high score.
You don’t have to use itoa. arduboy.print can print integers, arduboy.print(score); would be fine. Because of this, scorebuf is essentially redundant.
aHeld looks like it could be replaced with using justPressed instead of pressed
sizeof(unsigned int) returns the size of unsigned int in bytes, not its maximum value, so when you call add(&val2u, margin, sizeof(unsigned int)) you’re actually doing add(val2u, margin, 2). That might be intentional, but it doesn’t seem to be.
You don’t need struct in front of bean and angel except for when they’re first declared. I.e. beans[i] = (struct bean){0,0,0,0} is redundant, you could just write beans[i] = (bean){0,0,0,0} or in fact beans[i] = {0,0,0,0} should work too
@Pharap Here are answers to your respective comments in order:
I’m using itoa because using the print(int) overload is super laggy. My code only calls itoa when score updates, instead of on every single frame. If I don’t redraw the score, it can get hidden by beans falling through.
aHeld works differently in that it uses aPressed's previous value, which goes through the validation of the A press (leading to the tongue having extended) which justPressed() does not do. I did try swapping out but it didn’t work.
Didn’t notice because req() was only used for small amounts
Nope. As per C convention, struct types can only be referred to by prefixing them with struct, unless typedef'd. And omitting the cast can create confusion for whoever reads the code afterwards.
This isn’t C, this is C++. In C++, the struct is optional.
(If this was C, you wouldn’t be able to do arduboy.display() because C doesn’t have a concept of member functions.)
The reason you are getting an error is because you named one of your images bean as well (i.e. PROGMEM const unsigned char bean[]), so the compiler can’t figure out whether you mean the struct bean or the array bean.
A simple fix would be to capitalise the type names to Bean and Angel.
That’s one of the reasons C++ tends to prefer constructors over C-style brace initialisation.
Personally I don’t think omitting the cast is particularly confusing, the array name is quite clear about what it contains, but fair enough.
I usually just code in C style, so I think I’ll stick with my (struct bean) cast, should it only be for aesthetic purposes. It doesn’t cause any problems AFAIK. (plus it allows me to have an image called bean[] next to it )
Oh and print(int) might be superfast, but still, converting only on change leaves more cycles per frame, so more room for improvement.