Hi all! So have been into Arduino for 8 months now, and decided to get an Arduboy. I made this simple game and would like some feedback from you guys. The project can be downloaded here. Enjoy! (P.S. I might add new features like high scores but when I do I will update GitHub.)
This is awesome for only only being into it for a short time! The game runs a little fast, I might slow it down a little but maybe that is just how it plays on the emulator?
Also it seems like you might want to add a debounce to the pause button? I kept pressing pause and it would pause and upause very fast getting me stuck in the pause screen!
Actually, after revisiting my game and playing it on my actual Arduboy, it doesnât seem to have a debounce problem. It may have to do with the fact that I have so many variables being checked and modified each time the loop is run. I noticed that when I added more commands (like drawing the background bitmap) to my loop, the loop was slower(ships moved way slower). It may affect the frequency at which the button is being checked, thus reducing the debounce issue. If you have an Arduboy, maybe you might want to download my game onto that and try it for yourself. It may be a good idea to add debounce anyway just so that it can be played on the emulator.
You should be controlling the speed by running at a constant frame rate. You should be using nextFrame() at the beginning of loop().
void loop() {
if (!arduboy.nextFrame()) {
return;
}
The default rate is 60FPS. If you want something different add setFrameRate() or setFrameDuration() in setup().
If you want to make sure that your loop is executing within a frameâs duration, temporarily change nextFrame to nextFrameDEV. The USB TX LED will then light if you canât keep up to the rate youâve set.
For things like a pause button, you can use justPressed(), which will only detect a single press of a button, regardless of how long itâs held pressed. It gives you a natural debounce. For justPressed() to work, you need a call to pollButtons() in your loop. This can go right after the nextFrame() test.
void loop() {
if (!arduboy.nextFrame()) {
return;
}
arduboy.pollButtons();
@MLXXXp is right about the lack of framerate regulation.
I suspected this would be the case because I remember another game doing the exact same thing fairly recently.
Not bad for a first attempt.
For future reference, youâre not supposed to .zip the source code before uploading it to GitHub.
GitHub automatically packs the code into a .zip file when you download it, so people will end up downloading a .zip within a .zip.
Also if you upload it as-is, you can read the source directly from GitHub without having to download it.
Would it be possible for the stars to move left to right?
Some code I stole from another game (on another platform).
Call initStarField() from your setup.
Call updateStarField() from your gameâs main loop.
Render the stars before you draw your players / enemies.
#DEFINE STAR_COUNT 50
int16_t stars[STAR_COUNT];
// ----------------------------------------------------------------------------
// Update star field ..
//
void BaseState::updateStarField() {
for (uint8_t x=0; x < STAR_COUNT; x++) {
this->stars[x]++;
if (this->stars[x] < 0) this->stars[x] = rand() % 50 + 128; // a random distance past 128
}
}
// ----------------------------------------------------------------------------
// Update star field ..
//
void BaseState::initStarField() {
// Populate star field ..
for (uint8_t x = 0; x < STAR_COUNT; x++) {
this->stars[x] = rand() % 180;
}
}
// Render star field ..
for (uint8_t x = 0; x < STAR_COUNT; x++) {
arduboy.drawPixel(x * 5, this->stars[x]);
}
Actually thatâs not a bad idea. I could make another identical bitmap of the stars and have both of them move left until the one on the left reaches the left edge of the screen. Then it could go to the right side off of the screen and the cycle can just repeat. If space ships are not going insanely fast, then the stars wonât move that much because they are probably light years away, though.
Strange, I was sure the Arduboy already had a game that did this.
I certainly remember writing something like this at one point to demonstrate the idea.
(Edit:I think I found what I was thinking of, and it actually generated a front-facing field of stars rather than horizontally scrolling stars, so not quite the same.)
Either way this seems to be mixing up the x and the y.
If you want to move the stars left and right then the loop counter should be the y coordinate and the array should be holding the x values rather than the other way around.
Mmm ⌠maybe my code was a bit inappropriate as it is for a game with a starfield that falls from top to bottom (not left to right).
The idea with an array and random star placement is that it is exactly that - random. Otherwise you get that âFlintstonesâ effect where the same scenery keeps going past. Anyhow, the code can be easily adapted.
You donât need the first arduboy.nextFrame();
statement on line 65 immediately after loop(). Itâs not doing anything.
I would move the arduboy.pollButtons() statement on line 390 to the top of loop(), immediately after the nextFrame() test, as I previously suggested. It makes it easier to see that youâre using it.
You should have a break; statement and the end of each of your case blocks. Otherwise, the execution will âfall throughâ from the end of one case to the start of the next. Itâs not causing a problem now but it may bite you in the future.
So I have edited the game so that the stars are different, and they scroll by (thanks for the idea, filmote). I also did what MLXXXp suggested. I am going to post it in GitHub and post the emulator again but running the updated code.
While weâre handing out advice, you donât actually need your whilee variable.
Instead of:
whilee = 1;
while (whilee == 1) {
if (arduboy.pressed(UP_BUTTON)) {
arduboy.audio.on();
whilee = 0;
}
if (arduboy.pressed(DOWN_BUTTON)) {
arduboy.audio.off();
whilee = 0;
}
}
You can do:
while (true) {
if (arduboy.pressed(UP_BUTTON)) {
arduboy.audio.on();
break;
}
if (arduboy.pressed(DOWN_BUTTON)) {
arduboy.audio.off();
break;
}
}
(There is actually a better way to structure your program than using delays and whiles, but it would mean quite a big architectural change, so you might want to wait until youâre more comfortable with C++ before attempting that.)
That sounds like you accidentally put it before gamestate = 1;.
One thing that might make it easier to manage your game states (and prevent those sorts of mistakes) is to have the code for each game state in a separate function, that way itâs easier to see when/where the code for a state begins and ends.
Nice game. If you increase the number of enemies and maybe make them smaller it would add quite some action. Maybe also make the enemies appear in waves so the player can get some rest between epic shooting battles.