![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
Minigame based on Nucleo F103RBSTM32F103RBT6 microcontroller with mBed Application shield
Dependencies: C12832 LM75B MMA7660 mbed
Fork of apps-shield-pots by
- One player - Apple to collect - Monster to avoid - 3 life - 5 ammo - Dynamic difficulty
Playability : Move with accelerometer Shoot with joystick Notifications with RBG LED/Speaker
4 applicatives view - Menu - Ingame - Pause (press fire 2 seconds) - Game over
Have fun
main.cpp
- Committer:
- Laphaze
- Date:
- 2016-07-04
- Revision:
- 5:f11bddc1baf0
- Parent:
- 4:f0eb984c583d
File content as of revision 5:f11bddc1baf0:
/* _ _ _____ _ _ / \ _ __ _ __ | | ___ | ___(_)_ __ __| | ___ _ __ / _ \ | '_ \| '_ \| |/ _ \ | |_ | | '_ \ / _` |/ _ \ '__| / ___ \| |_) | |_) | | __/ | _| | | | | | (_| | __/ | /_/ \_\ .__/| .__/|_|\___| |_| |_|_| |_|\__,_|\___|_| |_| |_| +-+-+-+-+-+ +-+-+-+-+-+-+ +-+-+-+-+-+ +-+-+-+-+-+-+ +-+-+-+-+-+ +-+-+-+-+-+-+ +-+-+-+-+-+ |Will you be able to get the most apple as possible before the monster hunt you down ?| |Tips| -> Shoot the monster with right/left joystick -> Each 5 apple ate you level up and 2 ammo are added to your stock -> Each 10 apple ate you gain 1 life -> Pause the game by pressing Fire joystick 3 seconds |Warning| -> The monster is running faster each level +-+-+-+-+-+ +-+-+-+-+-+-+ +-+-+-+-+-+ +-+-+-+-+-+-+ +-+-+-+-+-+ +-+-+-+-+-+-+ +-+-+-+-+-+ */ #include "mbed.h" #include "LM75B.h" #include "C12832.h" #include <stdio.h> #include <stdlib.h> #include <time.h> #include <string> #include <vector> class Apple { public: float x; float y; }; class Player { public: float x; float y; int life; int eatenApple; int mobKilled; int ammo; bool firstSpawn; // Default class initialization Player() : life(3), ammo (3), firstSpawn( true ) {} }; class Monster { public: float x; float y; bool killed; Monster() : killed( false ) {} }; class Game { public: bool started; bool firstStart; bool paused; int level; // Default class initialization Game() : started( true ), firstStart( true ), paused( false ), level (1) {} void RestartGame (){ started = true; level = 1; } }; // LCD initialization C12832 lcd(D11, D13, D12, D7, D10); // Potentiometer AnalogIn pot1 (A0); AnalogIn pot2 (A1); // RBG LED DigitalOut red_led(D5); DigitalOut blue_led(D8); DigitalOut green_led(D9); // JOYSTICK DigitalIn up(A2); DigitalIn down(A3); DigitalIn left(A4); DigitalIn right(A5); DigitalIn fire(D4); // Temperature Sensor LM75B sensor(D14,D15); // Speaker PwmOut spkr(D6); // Class initialization Apple apple; Player player; Monster monster; Game game; std::vector<Apple> Apples; std::vector<Monster> Monsters; /** setLight Util method for switching LED color @param string color ColorName */ void setLight (string color) { if(color == "blue") { red_led = 1; green_led = 1; blue_led = 0; } else if(color == "red") { red_led = 0; green_led = 1; blue_led = 1; } else if(color == "transparent") { red_led = 1; green_led = 1; blue_led = 1; } else { red_led = 1; green_led = 0; blue_led = 1; } } void PlayMusic () { vector<int> sons; spkr = 0.5; sons.push_back(800); sons.push_back(1100); sons.push_back(400); sons.push_back(1200); sons.push_back(900); int randomSound = rand() % 5; int valueSound = sons.at(randomSound); spkr.period(1.0/valueSound); wait(0.03); spkr = 0.0; } /** Shoot Shooting Lazer, takes right or left parameter @param string position */ void Shoot (string position) { if(player.ammo != 0) // Check if player have enough ammo { if(position == "right") // Right shoot ! { lcd.fillrect(player.x, player.y + 4, 127, player.y + 4, 1); // Display the laser ! int verifShootMonster = Monsters[0].y - player.y; if(verifShootMonster < 2 && player.x < Monsters[0].x) // Check if monster got hit { spkr.period(3.0/300); // Moskito crush sound ! :D spkr=0.9; wait(0.05); spkr.period(3.0/500); spkr=0.9; player.mobKilled++; Monsters[0].killed = true; // Monster is now hidden, to allow player to get the Apple safety } player.ammo--; } if(position == "left") // Left shoot ! { lcd.fillrect(player.x - 5, player.y + 4, 0, player.y + 4, 1); // Display the laser ! int verifShootMonster = Monsters[0].y - player.y; if(verifShootMonster < 2 && player.x > Monsters[0].x) // Check if monster got hit { spkr.period(3.0/300); spkr=0.9; wait(0.05); spkr.period(3.0/500); spkr=0.9; player.mobKilled++; Monsters[0].killed = true; // Monster is now hidden, to allow player to get the Apple safety } player.ammo--; } } else // Sorry, no ammo for the player :/ { spkr.period(4.0/500); spkr=0.9; } } /** ColisionEffect Action in case of collision with monster/apple @param string type */ void ColisionEffect(string type) { if(type == "apple") { player.eatenApple++; setLight("green"); /* Resetting monster/apple to generate randomly the next ground */ Apples.clear(); Monsters.clear(); if(player.eatenApple % 10 == 0 && player.eatenApple > 9){ // Add 1 life each time player ate 10 apple player.life++; } if(player.eatenApple % 5 == 0) // LEVEL UP :D { game.level++; player.ammo += 2; } } else if (type == "monster") { wait(0.5); setLight("red"); spkr.period(1.0/300); spkr = 0.9; player.life--; Monsters.clear(); Apples.clear(); if(player.life <= 0) // End of the game if player's life is equal to 0 { game.started = false; } } } // The monster is following horizontally and vertically the player. void MonsterTrackingPlayer() { if(Monsters[0].y > 14) // Teleport the monster at the top of the map { Monsters[0].y = 0; } else if(Monsters[0].y < 0) // Teleport the monster at the bottom of the map { Monsters[0].y = 13; } else if(Monsters[0].y >= 0 && Monsters[0].y < 15) // Following player, from left to right { if(Monsters[0].y > player.y) { Monsters[0].y -= static_cast <float> (rand()) / static_cast <float> (RAND_MAX); // Trying new rand method which is approximatively..Random :) } else { Monsters[0].y += static_cast <float> (rand()) / static_cast <float> (RAND_MAX); } } if(Monsters[0].x > 120) // Teleport player at the left of the map { Monsters[0].x = 0; } else if(Monsters[0].x < 0) // Teleport player at the right of the map // Unused in my case because monster's move are from left to right { Monsters[0].x = 120; } else if(Monsters[0].x >= 0 && Monsters[0].x < 121) // "Randomize" a bit the monster's move { Monsters[0].x += static_cast <float> (rand()) / static_cast <float> (RAND_MAX / game.level); // Monster's move is faster each level } // Display the monster lcd.locate(Monsters[0].x, Monsters[0].y); lcd.printf("x"); } // Display the start screen Menu void PrintStartMenu() { setLight("blue"); lcd.fillrect(127, 0, 0, 0, 1); lcd.locate(35, 2); lcd.printf("Apple finder :D"); lcd.fillrect(127, 12, 0, 12, 1); lcd.locate(0, 13); lcd.printf("Monster: X"); lcd.locate(55, 13); lcd.printf("Apple: O"); lcd.locate(96, 13); lcd.printf("You: +"); lcd.locate(0, 22); lcd.printf("Presse fire to launch game !"); } // Display the bottom stats ingame menu void PrintBottomMenu() { lcd.locate(0, 23); lcd.fillrect(0, 30, 0, 30, 1); lcd.printf("Apple: %d", player.eatenApple); // Vertical divider lcd.fillrect(42, 23, 42, 32, 1); lcd.locate(45, 23); lcd.printf("LVL %d", game.level); // Vertical divider lcd.fillrect(73, 23, 73, 32, 1); lcd.locate(79, 23); lcd.printf("~%d", player.ammo); // Vertical divider lcd.fillrect(92, 23, 92, 32, 1); lcd.locate(95, 23); lcd.printf("Life: %d", player.life); } // Display the Game Over screen Menu void PrintGameOverMenu() { lcd.fillrect(127, 0, 0, 0, 1); lcd.locate(15, 2); lcd.printf("Game OVER :/ LVL %d", game.level); lcd.fillrect(127, 12, 0, 12, 1); lcd.locate(0, 13); lcd.printf("Apple ate: %d", player.eatenApple); lcd.locate(70, 13); lcd.printf("Mob killed: %d", player.mobKilled); lcd.locate(10, 22); lcd.printf("Presse fire to restart"); } // Default thread int main() { float verifXApple, verifYApple, verifXMonster, verifYMonster = 0.0; int scrollPosition = 0; int breakTimer = 0; bool blinkEnd = true; bool blinkScreenPause = true; // Sound off spkr = 0.0; /* I'm using the temp sensor to generate random number that i'll pass as parameter for the srand fonction with time clock, it allows a different generation (and not random) number each appStart time */ int randHack = int(sensor.temp() + 0.5); srand(randHack); while(true) // Main thread { /* ------ */ PrintStartMenu(); /* ------ */ while(game.firstStart) // First Menu -- Explications { if(fire) // If user press fire, start the game ! { game.firstStart = false; } } // Play while player's alive while(game.started == true) { spkr = 0.0; lcd.cls(); // Initial screen clear while(game.paused == true) { PrintBottomMenu(); // Display the stats bottom menu blinkScreenPause = !blinkScreenPause; // Blink and invert the screen color, fun effect if(blinkScreenPause) // Black foreground { lcd.fillrect(127, 0, 0, 22, 1); } else // White foreground { lcd.fillrect(127, 0, 0, 22, 0); } if(scrollPosition < 12) // Scrolling text vertically, and teleport it at the top if he reach the bottom limit { lcd.locate(32, scrollPosition); lcd.printf("Game PAUSED"); } else { scrollPosition = 1; lcd.locate(32, scrollPosition); lcd.printf("Game PAUSED"); } scrollPosition += 2; if(fire) // Resume pause { if(breakTimer >= 2) { game.paused = false; breakTimer = 0; } else { breakTimer++; } } wait(0.5); } if(player.firstSpawn == true) // Assign the player to default location, but seems little bit buggy due to the the potentiometer's value which is not reset to zero every time the system reboot. { setLight("green"); player.x = 0; player.y = 0; } else // Player positionning with potentiometer { player.x = (float)pot2 * 122; player.y = (float)pot1 * 15; } player.firstSpawn = false; // Random apple generation if(Apples.size() == 0) { apple.x = rand() % 122; apple.y = rand() % 15; Apples.push_back(apple); } // Random monster generation if(Monsters.size() == 0) { monster.x = rand() % 122; monster.y = rand() % 15; Monsters.push_back(monster); } // Bottom map border lcd.fillrect(0, 22, 128, 22, 1); // Colision Verification with apple verifXApple = Apples[0].x - player.x; verifYApple = Apples[0].y - player.y + 4.0; // Check collision with apple if(verifXApple < 4 && verifXApple > -4 && verifYApple < 5 && verifYApple > -5) { ColisionEffect("apple"); } // Verification colision with monster verifXMonster = Monsters[0].x - player.x; verifYMonster = Monsters[0].y - player.y + 4.0; // Check collision with monster if(verifXMonster < 4 && verifXMonster > -4 && verifYMonster < 5 && verifYMonster > -5 && Monsters[0].killed == false) { ColisionEffect("monster"); } else { PlayMusic(); } /* ------ */ PrintBottomMenu(); /* ------ */ if(right) // Joystick event right/left { Shoot("right"); } if(left) { Shoot("left"); } if(fire) { if(breakTimer >= 2) { game.paused = true; breakTimer = 0; } else { breakTimer++; } } // Player positionning lcd.locate(player.x, player.y); lcd.printf("+"); // Apple positionning lcd.locate(Apples[0].x, Apples[0].y); lcd.printf("o"); if(Monsters[0].killed == false) { MonsterTrackingPlayer(); } wait(0.15); } lcd.cls(); // Clear screen before GameOverMenu while(game.started == false) // GameOver Menu { /* ------ */ PrintGameOverMenu(); /* ------ */ spkr = 0.0; if(blinkEnd == true) // Making cool effect with light { blinkEnd = !blinkEnd; setLight("red"); } else { blinkEnd = !blinkEnd; setLight("transparent"); } if(fire) // Start a new game { player.life = 3; player.eatenApple = 0; player.ammo = 1; player.mobKilled = 0; game.RestartGame(); } } } } // Wooh, you finished it !