// Arne van Iterson 2019 // Include all the stuff #include #include // Setup instance of arduboy Arduboy2 arduboy; // Define all bitmaps //// Spacemania 2000 titlescreen const unsigned char PROGMEM titlescreen[] = { // width, height, 102, 22, 0x3f, 0x3f, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0xf3, 0xf3, 0x00, 0xff, 0xff, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x3f, 0x3f, 0x00, 0xff, 0xff, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0xff, 0xff, 0x00, 0xff, 0xff, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00, 0xff, 0xff, 0x33, 0x33, 0x33, 0x33, 0x03, 0x03, 0x03, 0x03, 0x00, 0xff, 0xff, 0x03, 0x03, 0xff, 0xff, 0x03, 0x03, 0xff, 0xff, 0x00, 0xff, 0xff, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0xff, 0xff, 0x00, 0xff, 0xff, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0xff, 0xff, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x33, 0x30, 0x33, 0x33, 0x33, 0x33, 0x33, 0xf3, 0xf3, 0x03, 0xf3, 0xf3, 0x30, 0x33, 0x33, 0x33, 0x33, 0x33, 0xf3, 0x03, 0x03, 0xf3, 0xf3, 0x30, 0x33, 0x33, 0x30, 0x30, 0x33, 0xf3, 0x00, 0x00, 0xf3, 0xf3, 0x30, 0x33, 0x33, 0x30, 0x30, 0x30, 0xf0, 0x00, 0x00, 0x03, 0x03, 0x00, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x03, 0x03, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x3f, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x3f, 0x3f, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3f, 0x00, 0x00, 0x3f, 0x3f, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3f, 0x00, 0x00, 0x3f, 0x3f, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; //// Gameover screen const unsigned char PROGMEM gameover[] = { // width, height, 102, 22, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xc0, 0xc0, 0xcc, 0xcc, 0xcc, 0xcc, 0xfc, 0xfc, 0x00, 0xff, 0xff, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0xcc, 0xcc, 0xcc, 0xcc, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xff, 0x00, 0x00, 0x0f, 0x0f, 0x30, 0x30, 0xc0, 0xc0, 0x30, 0x30, 0x0f, 0x00, 0x00, 0xff, 0xff, 0xcc, 0xcc, 0xcc, 0xcc, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0xff, 0xff, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c, 0x3c, 0xcf, 0xcf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; //// Player spaceship const unsigned char PROGMEM spaceship[] = { // width, height, 16, 16, 0x00, 0xfe, 0xfc, 0xf8, 0xfc, 0xfc, 0xfe, 0xfe, 0x80, 0xfe, 0x80, 0xfc, 0x80, 0xf0, 0x80, 0x00, 0x00, 0x43, 0x6f, 0x77, 0x7b, 0x3d, 0x5f, 0x6f, 0x77, 0x7b, 0x3d, 0x3f, 0x1f, 0x0f, 0x03, 0x00, }; //// Player bullets const unsigned char PROGMEM bullet[] = { // width, height, 8, 8, 0x00, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x3c, 0x00, }; //// Enemy spaceship const unsigned char PROGMEM baddie[] = { // width, height, 16, 16, 0xc0, 0xf0, 0xf8, 0xbc, 0xde, 0xce, 0xe7, 0xff, 0xff, 0xff, 0xfe, 0xfe, 0xfc, 0xfe, 0xf6, 0xc1, 0x03, 0x0f, 0x19, 0x3f, 0x61, 0x7f, 0xc1, 0xff, 0xff, 0xff, 0x7f, 0x7f, 0x3f, 0x7f, 0x6f, 0x83, }; // Define Variables //// System const int screen[] = { 128, 64 }; //// Timing float dt = 0; //// Game Setup const int framerate = 60; int gamestate = 0; bool reset = 0; int i; //// Game Variables float playerPos[] = { 0, ((screen[1] / 2) - (spaceship[1] / 2)) }; float playerSpeed = 1; float bulletSpeed = 1.5; const int bulletAmount = 5; float baddieSpeed = 0.8; const int baddieAmount = 16; // Setup code void setup() { // Random number generator arduboy.initRandomSeed(); // Start arduboy arduboy.begin(); // Set framerate arduboy.setFrameRate(framerate); // Clear screen arduboy.clear(); } // Game loop void loop() { // Only loop if it is time for the next frame if (!arduboy.nextFrame()) return; // Clear screen arduboy.clear(); // Keep track of buttons arduboy.pollButtons(); // Switch between gamestates switch (gamestate) { //// Titlescreen case 0: Sprites::drawOverwrite(((screen[0] - titlescreen[0]) / 2), ((screen[0] - titlescreen[0]) / 2), titlescreen, 0); arduboy.setCursor(16, 40); arduboy.print("Press A to start"); arduboy.setCursor(36, 57); arduboy.print("McArn 2019"); if (arduboy.justPressed(A_BUTTON)) { gamestate = 1; reset = true; } break; //// Game case 1: if ( arduboy.pressed(A_BUTTON) && arduboy.pressed(B_BUTTON) ) { gamestate = 0; } game(); break; //// Game over case 2: Sprites::drawOverwrite(((screen[0] - gameover[0]) / 2), ((screen[0] - gameover[0]) / 2), gameover, 0); arduboy.setCursor(12, 40); arduboy.print("Press A to restart"); if (arduboy.justPressed(A_BUTTON)) { gamestate = 1; reset = true; } break; } // Display everything arduboy.display(); } // Bullet class class Bullet { public: float pos[2]; bool dead = true; void update() { if (pos[0] >= (screen[0] + bullet[0])) { dead = true; pos[0] = 0 - bullet[0]; } else { pos[0] = pos[0] + (1 * bulletSpeed); } } }; // Max amount of bullets = 5; Bullet bullets[bulletAmount]; // Enemy class class Baddie { public: float pos[2]; bool dead = true; void update() { if (pos[0] <= (0 - baddie[0])) { dead = true; gamestate = 2; pos[0] = screen[0] + baddie[0]; } else { pos[0] = pos[0] - (1 * baddieSpeed); } } }; Baddie baddies[baddieAmount]; void game() { // Reset game if coming from title or gameover screen if (reset) { for (i = 0; i < (baddieAmount - 1); i++) { baddies[i].pos[0] = screen[0] + baddie[0]; baddies[i].pos[1] = random(screen[1] - baddie[1]); baddies[i].dead = true; } for (i = 0; i < (bulletAmount - 1); i++) { bullets[i].dead = true; } playerPos[0] = 0; playerPos[1] = (screen[1] / 2) - (spaceship[1] / 2); reset = false; } // Move Player if ( arduboy.pressed(UP_BUTTON) && !(playerPos[1] <= 0) ) { playerPos[1] = playerPos[1] - 1 * playerSpeed; } if ( arduboy.pressed(DOWN_BUTTON) && !(playerPos[1] >= (screen[1] - spaceship[1])) ) { playerPos[1] = playerPos[1] + 1 * playerSpeed; } if ( arduboy.pressed(LEFT_BUTTON) && !(playerPos[0] <= 0) ) { playerPos[0] = playerPos[0] - 1 * playerSpeed; } if ( arduboy.pressed(RIGHT_BUTTON) && !(playerPos[0] >= (screen[0] - spaceship[0])) ) { playerPos[0] = playerPos[0] + 1 * playerSpeed; } // Spawn Bullet if ( arduboy.justPressed(A_BUTTON)) { for (i = 0; i < (bulletAmount - 1); i++) { if (bullets[i].dead) { bullets[i].pos[0] = playerPos[0]; bullets[i].pos[1] = playerPos[1] + (spaceship[1] / 2) - (bullet[1] / 2); bullets[i].dead = false; break; } } } // Spawn baddie for debug if ( arduboy.justPressed(B_BUTTON)) { for (i = 0; i < (baddieAmount - 1); i++) { if (baddies[i].dead) { baddies[i].dead = false; break; } } } // Update and show non-dead bullets for (i = 0; i < (bulletAmount - 1); i++) { if (!bullets[i].dead) { bullets[i].update(); Sprites::drawSelfMasked(round(bullets[i].pos[0]), round(bullets[i].pos[1]), bullet, 0); } } // Update and show non-dead baddies for (i = 0; i < (baddieAmount - 1); i++) { if (!baddies[i].dead) { baddies[i].update(); Sprites::drawSelfMasked(round(baddies[i].pos[0]), round(baddies[i].pos[1]), baddie, 0); } } // Draw player Sprites::drawSelfMasked(round(playerPos[0]), round(playerPos[1]), spaceship, 0); checkCollision(); } // Variables for collision detection float distance = 0; float difference[2]; int a; // Check collisions void checkCollision() { for (i = 0; i < (baddieAmount - 1); i++) { // Collision baddie x bullet for (a = 0; a < (bulletAmount - 1); a++) { //// Difference x difference[0] = (baddies[i].pos[0] + (baddie[0] / 2)) - (bullets[a].pos[0] + (bullet[0] / 2)); //// Difference y difference[1] = (baddies[i].pos[1] + (baddie[1] / 2)) - (bullets[a].pos[1] + (bullet[1] / 2)); // Calculate diffence distance = sqrt(pow(difference[0], 2) + pow(difference[1], 2)); if (!baddies[i].dead && !bullets[a].dead && distance <= 11) { bullets[a].dead = true; baddies[i].dead = true; baddies[i].pos[0] = screen[0] + baddie[0]; baddies[i].pos[1] = random(screen[1] - baddie[1]); } } // Collision baddie x player //// Difference x difference[0] = (baddies[i].pos[0] + (baddie[0] / 2)) - (playerPos[0] + (spaceship[0] / 2)); //// Difference y difference[1] = (baddies[i].pos[1] + (baddie[1] / 2)) - (playerPos[1] + (spaceship[1] / 2)); // Calculate diffence distance = sqrt(pow(difference[0], 2) + pow(difference[1], 2)); if (!baddies[i].dead && distance <= 15) { gamestate = 2; } } }