Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed
Fork of el17dg by
game/game.cpp
- Committer:
- Noximilien
- Date:
- 2019-04-16
- Revision:
- 30:d454d0cb72bc
- Parent:
- 29:579e00b7f118
- Child:
- 31:becb8f6bf7b7
File content as of revision 30:d454d0cb72bc:
#include "mbed.h"
#include "N5110.h"
#include "Gamepad.h"
#include "models.h"
#include "main.h"
#include "game.h"
#include "geometry.h"
#include "gameobject.h"
#include "enemies.h"
#include "constants.h"
#include "stars.h"
#include "player.h"
#include "hud.h"
// The speed of every counter is 1Hz
bool game_over = true;
bool is_shield_on = false;
int game_score;
int high_score = 0;
int score_count_for_difficulty;
int player_lifes = 3;
int low_frequency_music_counter = 0;
int high_frequency_music_counter = 0;
bool red_led_state;
int red_led_flashing;
int enemy_ship_delay_counter;
const int increase_difficulty = 50;
int enemy_ship_delay_max = 40;
bool led_state = false;
Enemies enemies;
Stars stars;
Player playerShip;
GameObject gameOverLogo;
GameObject youDied;
CircleBounds circleBounds;
Hud hud;
/**
* This is the main function of game.cpp, where the actual gameplay happens.
* Here all other functions are activeated, and when the player dies, it
* returns back to main menu "main.cpp".
*/
bool Game::updateAndDraw() {
//printf("update \n");
if (game_over) {
printf("start game \n");
startNewGame();
}
if (gamepad.check_event(gamepad.X_PRESSED) && !is_shield_on){
// Checking the button second time to prevent double blast.
gamepad.check_event(gamepad.X_PRESSED);
playerShip.fireNewBlast();
gamepad.tone(200,0.1);
}
playerShip.playerShipMovement();
stars.starsSpawnDelay();
increaseGameDifficultyAndEnemySpawnDelay();
hud.displayLifes();
playerShip.updateAndDrawBlasts();
stars.updateAndDrawSmallStars();
stars.updateAndDrawMediumStars();
enemies.updateAndDrawEnemies();
collideEnemiesAndBlasts();
collideEnemiesBlastsAndPlayer();
collideEnemiesAndPlayer();
enemies.updateAndDrawEnemyBlasts();
hud.drawScore();
return returnToMenu();
}
/**
* This function checks whether the requirments for the collision of the two objects,
* are met. When those requirments are met the collision of two objects function will
* be checking wheter the boundaries of the objects colide. If they do, the blast
* becomes inactive, in game score increases and enemy dies.
*/
void Game::collideEnemiesAndBlasts() {
for (int i = 0; i < max_enemies; ++i) {
for (int j = 0; j < max_player_blasts; ++j) {
Enemy& enemy = enemies.enemies[i];
GameObject& blast = blasts[j];
if (enemy.active && !enemy.dead && blast.active) {
bool collision = circleBounds.circleCollideTwoObjects(
enemy.pos, enemies.enemy_bounds,
blast.pos, blast_bounds
);
if (collision) {
enemy.die();
printf("enemy got hit and dies from blast");
game_score += 30;
score_count_for_difficulty +=30;
blast.active = false;
}
}
}
}
}
/**
* This code does the same work as the one before but with two other objects.
* It checks whether the requirments for the collision of the two objects,
* are met. When those requirments are met the collision of two objects function will
* be checking wheter the boundaries of the objects colide. If they do, the blast
* becomes inactive, in game score increases and enemy dies.
*/
void Game::collideEnemiesBlastsAndPlayer() {
for (int i = 0; i < max_enemies; ++i) {
GameObject& blast = enemies.enemy_blasts[i];
if (blast.active) {
bool collision = circleBounds.circleCollideTwoObjects(
player.pos, player_bounds,
blast.pos, enemies.enemy_blast_bounds
);
if (collision) {
if (!is_shield_on){
gamepad.tone(423,0.4);
player_lifes -= 1;
//printf("lost a life from blast. left: %i \n", player_lifes);
blast.active = false;
}else{
blast.active = false;
gamepad.tone(700,0.6);
}
}
}
}
}
/**
* This code does the same work as the one before but with two other object.
* of enemy ship and the player's ship
*/
void Game::collideEnemiesAndPlayer() {
for (int i = 0; i < max_enemies; ++i) {
Enemy& enemy = enemies.enemies[i];
if (enemy.active && !enemy.dead) {
bool collision = circleBounds.circleCollideTwoObjects(
player.pos, player_bounds,
enemy.pos, enemies.enemy_bounds
);
if (collision) {
player_lifes -= 1;
printf("lost a life from enemy col. left: %i \n", player_lifes);
enemy.die();
printf("enemy got hit from collsion and dies");
}
}
}
}
/**
* This function resets all the values to their intial states when the game is
* first began when the player dies and wants to restart the game.
* It does not reset the values when the game is paused.
*/
void Game::startNewGame() {
gameOverLogo.pos.x = game_area_x - 29; // 0 - the sprite length
gameOverLogo.pos.y = game_area_y;
youDied.pos.x = game_area_width;
youDied.pos.y = game_area_y;
game_over = false;
is_shield_on = false;
player.pos.x = 0; //player was defined in player.h
player.pos.y = 24;
stars_delay = 0;
enemy_ship_delay_max = 40;
enemy_ship_delay_counter = enemy_ship_delay_max;
game_score = 0;
score_count_for_difficulty = 0;
player_lifes = 3;
red_led_state = false;
red_led_flashing = 0;
enemy_blast_speed = 3;
enemy_speed = 1;
for (int i = 0; i < max_enemies; ++i) {
enemies.enemies[i].active = false;
}
for (int i = 0; i < max_player_blasts; ++i) {
blasts[i].active = false;
}
for (int i = 0; i < max_enemy_blasts; ++i) {
enemies.enemy_blasts[i].active = false;
}
//Reset start and Y button event to avoid errors
gamepad.check_event(gamepad.START_PRESSED);
gamepad.check_event(gamepad.Y_PRESSED);
}
/**
* A game over function that shows the sprites of "game over" and "you died".
* Allows to reset the game to play again.
*/
void Game::gameOver() {
drawGameOver();
lcd.normalMode();
char buffer[32];
sprintf(buffer,"Your Score %i",game_score);
lcd.printString(buffer,0,3);
wait(1);
lcd.printString("Press Y",0,4);
lcd.printString("to restart",0,5);
lcd.refresh();
gamepad.check_event(gamepad.START_PRESSED);
while (!gamepad.check_event(gamepad.Y_PRESSED)){/////////////////////////////////
musicGameOver();
ledsGameOver();
}
}
/**
* A function tbat delays enemy spawn on low game score.
* It decreases the enemy spawn delay as in game score increases.
* The enemy spawn delay is located in game.cpp because the game difficulty
* depends on the on how fast enemy appears.
*/
void Game::increaseGameDifficultyAndEnemySpawnDelay(){
if (enemy_ship_delay_counter <= 0){
enemies.spawnNewEnemy();
enemy_ship_delay_counter = enemy_ship_delay_max;
}
else { enemy_ship_delay_counter -= 1;}
if (enemy_ship_delay_max >= 4 && score_count_for_difficulty >= increase_difficulty){
//decrease enemy delay spawn.
enemy_ship_delay_max -= 3;
if (enemy_ship_delay_max <= 20 && enemy_ship_delay_max >= 15){
enemy_blast_speed += 1;
enemy_speed += 1;
}
score_count_for_difficulty = 0;
}
if (game_score >= 500){lcd.inverseMode();}
}
bool Game::forceShildActivate(){
if (gamepad.check_event(gamepad.R_PRESSED)){
is_shield_on = !is_shield_on;
}
return is_shield_on;
}
/**
* This is a single line function to set the player lifes to 0 when the.
* game is over.
*/
bool Game::checkForGameOver() {
return player_lifes == 0;
}
/**
* A separate function that draws game over. */
void Game::drawGameOver(){
for (int i = 0; i < 42; i++){
musicGameOver();
lcd.clear();
gameOverLogo.pos.x += 1;
youDied.pos.x -= 1;
drawSprite(gameOverLogo.pos, game_over_sprite);
drawSprite(youDied.pos, you_died_sprite);
lcd.refresh();
wait(0.1);
}
}
void Game::ledsGameOver(){
gamepad.led(1,(float)led_state);
gamepad.led(2,(float)!led_state);
gamepad.led(3,(float)led_state);
gamepad.led(4,(float)!led_state);
gamepad.led(5,(float)led_state);
gamepad.led(6,(float)!led_state);
wait(0.5);
led_state = !led_state;
}
void Game::musicGameOver(){
lowFrequencyPartMusic();
highFrequencyPartMusic();
high_frequency_music_counter ++;
//low_frequency_music_counter ++; //comment out this for epic game over beat.
printMusicCountersTest();
}
void Game::lowFrequencyPartMusic(){
// Low frequency
if (low_frequency_music_counter == 0){ gamepad.tone(60,3);}
else if (low_frequency_music_counter == 3){gamepad.tone(90,3);}
else if (low_frequency_music_counter == 6){gamepad.tone(60,3);}
else if (low_frequency_music_counter == 9){gamepad.tone(80,3);}
else if (low_frequency_music_counter == 12){gamepad.tone(70,2);}
else if (low_frequency_music_counter == 14){gamepad.tone(60,2);}
else if (low_frequency_music_counter == 16){gamepad.tone(70,3);}
else if (low_frequency_music_counter == 19){gamepad.tone(50,1);}
else if (low_frequency_music_counter == 20){gamepad.tone(40,3);}
else if (low_frequency_music_counter== 23){
gamepad.tone(60,2);
low_frequency_music_counter = 0;
}
}
void Game::highFrequencyPartMusic(){
// High frequency
if ( high_frequency_music_counter == 0){ gamepad.tone(300,0.1);}
else if (high_frequency_music_counter == 3){gamepad.tone(250,0.1);}
else if (high_frequency_music_counter == 6){gamepad.tone(230,0.2);}
else if (high_frequency_music_counter == 9){gamepad.tone(250,0.1);}
else if ( high_frequency_music_counter == 12){gamepad.tone(250,0.2);}
else if ( high_frequency_music_counter == 14){gamepad.tone(220,0.1);}
else if ( high_frequency_music_counter == 16){gamepad.tone(210,0.3);}
else if ( high_frequency_music_counter == 19){gamepad.tone(200,1);}
else if ( high_frequency_music_counter == 21){gamepad.tone(250,1);}
else if ( high_frequency_music_counter == 22){
gamepad.tone(200,1);
high_frequency_music_counter = 0;
}
}
/** This small statment checks whether the pause button was pressed or not.
* If it was pressed, then the game will go back to main menu and will save
* the current status of the object until the game is continued.
*/
bool Game::returnToMenu(){
bool want_to_pause = false;
game_over = checkForGameOver();
if (game_over){
printf("game over happened\n");
gameOver();
want_to_pause = true;
}
if (gamepad.check_event(gamepad.START_PRESSED)){
printf("game paused\n");
gamepad.check_event(gamepad.START_PRESSED);
want_to_pause = true;
}
return want_to_pause;
}
void Game::printMusicCountersTest(){
printf("Low frequency counter value:: %i\n", low_frequency_music_counter);
printf("high frequency counter value:: %i\n", high_frequency_music_counter);
}
