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.
GameEngine/GameEngine.cpp
- Committer:
- evanso
- Date:
- 2020-05-19
- Revision:
- 49:ed569eceeaa4
- Parent:
- 47:49fa1adc10b4
- Child:
- 51:35cb8e604b72
File content as of revision 49:ed569eceeaa4:
#include "GameEngine.h"
/** Define acelleromter object */
FXOS8700CQ accelerometer(I2C_SDA,I2C_SCL);
/** Define SD card object */
SDFileSystem sd(PTE3, PTE1, PTE2, PTE4, "sd");
GameEngine::GameEngine() {
//attach ticker to isr
ticker.attach(callback(this, &GameEngine::lcd_frame_time_isr), 0.04 );
}
GameEngine::~GameEngine() {
}
void GameEngine::init() {
// Initalise objects
pad.init();
lcd.init();
spaceship.init();
map.init(pad);
menu.init();
accelerometer.init();
// Set seed value
srand(pad.read_adc()*64000);
// Assign values to variables
spawn_time_multipler_ = 1;
alien_number_counter_ = 3;
spawn_alien_counter_ = 0;
spaceship_lives_ = 3;
spaceship_destroyed_ = false;
reset_map_counter_ = 0;
smart_bomb_counter_ = 4;
create_people();
points_ = 0;
smart_bomb_timer_ = 0;
bullet_timer_ = 0;
current_menu_part_= menu.get_current_menu_part();
lcd_frame_time_flag_ = 0;
}
// Menu Control-----------------------------------------------------------------
void GameEngine::game_select_part(){
switch (current_menu_part_) {
case main_menu: run_menu(); break;
case play: run_play(); break;
case settings: run_settings(); break;
case saved_games: run_saved_games(); break;
}
}
void GameEngine::run_menu(){
lcd.setContrast(pad.read_pot1());
lcd.clear();
// Scrolls, draws and selcts menu parts
read_joystick_direction();
menu.menu_scroll(pad, d_);
menu.draw_part(lcd);
menu.select_part(lcd, pad);
current_menu_part_ = menu.get_current_menu_part();
lcd.refresh();
}
void GameEngine::run_play(){
while (1) {
// Checks flag and prints spaceship on lcd then resets flag
if (lcd_frame_time_flag_) {
// resets ISR flag
lcd_frame_time_flag_ = 0;
gameplay_loop();
// break out of game loop when lives = 0
if(!spaceship_lives_){
break;
}
}
// MCU put to sleep between each frame to save power
sleep();
}
lcd.clear();
lcd.printString("Game Over",15,3);
lcd.refresh();
wait(3);
current_menu_part_ = main_menu;
}
void GameEngine::gameplay_loop() {
// clear screen and set contrast
lcd.setContrast(pad.read_pot1());
lcd.clear();
// creat objects
spawn_aliens();
spawn_people();
//If spaceship is destroyed stop joystick input, dont draw spaceship sprite
if (!spaceship_destroyed_){
//read_joystick_direction();
read_accelerometer_direction();
spaceship.movement(d_);
spaceship.draw(lcd);
create_weapons_bullets();
create_weapons_smart_bomb();
}
// Draws objects
map.draw_map(lcd, d_);
draw_aliens();
draw_bullets();
draw_explosions();
draw_people();
hud.draw_HUD(lcd, spaceship_lives_, points_, smart_bomb_counter_);
spaceship_lives_leds();
reset_map_timer();
// refresh's screen
lcd.refresh();
}
void GameEngine::run_settings(){
}
void GameEngine::run_saved_games(){
}
void GameEngine::lcd_frame_time_isr(){
// set ISR flag
lcd_frame_time_flag_ = 1;
}
//Spaceship control ------------------------------------------------------------
void GameEngine::read_joystick_direction(){
d_ = pad.get_direction();
}
void GameEngine::read_accelerometer_direction(){
float roll = accelerometer.get_roll_angle();
float pitch = accelerometer.get_pitch_angle();
// printf("Pitch = %f Roll = %f\n", pitch, roll);
//north
if(pitch >= -35){
if(roll >= 10){
d_ = NE;
}else if (roll <= -10){
d_ = NW;
}else {
d_ = N;
}
//south
}else if(pitch <= -55){
if (roll >= 10){
d_ = SE;
}else if(roll <= -10){
d_ = SW;
}else {
d_ = S;
}
// East/west
}else {
if (roll >= 10){
d_ = E;
}else if(roll <= -10){
d_ = W;
}else{
d_ = CENTRE;
}
}
}
void GameEngine::spaceship_lives_leds(){
pad.leds_off();
//top two red leds on if 1 lives left
if(spaceship_lives_ >= 1){
pad.led(1,1);
pad.led(4,1);
}
//middle two orange leds also on if 2 lives left
if(spaceship_lives_ >= 2){
pad.led(2,1);
pad.led(5,1);
}
//bottom two red leds also on if 3 lives left
if(spaceship_lives_ == 3){
pad.led(3,1);
pad.led(6,1);
}
}
//Weapon control ---------------------------------------------------------------
void GameEngine::create_weapons_bullets(){
// controlls speed that bullet can be fired
if(bullet_timer_ <=0){
if (pad.A_pressed()){
// Bullet object
Weapons new_bullet;
new_bullet.init(spaceship.get_pos(),
spaceship.get_spaceship_sprite_direction(), true);
// Stores bullet object in vector
bullet_vector.push_back(new_bullet);
}
bullet_timer_ = 5;
}
bullet_timer_--;
}
void GameEngine::create_weapons_smart_bomb(){
// timer to stop smart bomb button be accidently pressed twice
if(smart_bomb_timer_ <=0){
if (pad.B_pressed() && smart_bomb_counter_ > 0){
weapons.smart_bomb(lcd);
smart_bomb_counter_--;
//Deletes alien object if on screen
for (int i = (alien_vector.size() -1) ; i >= 0 ; i--){
Vector2D alien_pos = alien_vector[i].get_pos();
// Creats explosion if alien was on the screen
if(alien_pos.x <= 84 && alien_pos.x >= -6){
create_explosion(alien_pos);
//delete person object if was being abducted by destroyed alien
if(alien_vector[i].get_collision_people_element() > -1){
people_vector.erase(people_vector.begin() +
alien_vector[i].get_collision_people_element());
}
alien_vector.erase(alien_vector.begin()+ i);
points_ ++;
}
}
smart_bomb_timer_ = 30;
}
}
smart_bomb_timer_--;
}
void GameEngine::draw_bullets(){
// interates over bullet vectors, moves and draws bullet objects
// Alien bullets
for (int i = 0; i < alien_bullet_vector.size(); i++){
alien_bullet_vector[i].draw_alien_bullet(lcd, d_);
// deletes alien bullet object after bullet has moved set distance
if(alien_bullet_vector[i].get_bullet_delete_counter() >> 5){
alien_bullet_vector.erase(alien_bullet_vector.begin()+ i);
}
// Deletes bullet and shpaceship if collision detected
if (spaceship.check_collision(alien_bullet_vector[i]) &&
!spaceship_destroyed_ ){
create_explosion(spaceship.get_pos());
spaceship_destroyed_ = true;
alien_bullet_vector.erase(alien_bullet_vector.begin()+ i);
}
}
// Spaceship bullets
for (int i = 0; i < bullet_vector.size(); i++){
bullet_vector[i].draw_bullet(lcd);
// deletes bullet object after bullet has moved set distance
if(bullet_vector[i].get_bullet_delete_counter() >> 5){
bullet_vector.erase(bullet_vector.begin()+ i);
}
}
}
//Alien Control ----------------------------------------------------------------
void GameEngine::spawn_aliens(){
if(alien_vector.size() <= alien_number_counter_){
create_alien();
}
//printf( " alien_number_counter_ = %d\n",alien_number_counter_);
//slowley incresing the alien counter as game goes on to make harder
if(spawn_alien_counter_%(500*spawn_time_multipler_) == 0){
alien_number_counter_++;
spawn_time_multipler_++;
}
spawn_alien_counter_++;
}
void GameEngine::create_alien(){
int position_x_start = 0;
// Alien object
Alien new_alien;
//spawns aliens between x > 84 and x <0
if(rand() % 2){
position_x_start = rand() % 84 + 84;
}else{
position_x_start =rand() % 83 - 84;
}
new_alien.init(pad, position_x_start, (rand() % 33 + 9));
// Stores alien object in vector
alien_vector.push_back(new_alien);
}
void GameEngine::check_alien_people_collision(int i){
// only a collision if all three of theses conditions are met:
// check all these codition for every alien to every person
// 1)person hasn't already had a collision
// 2)There is an acutaual collision of people and alien
for (int x = 0; x < people_vector.size(); x++){
if (!people_vector[x].get_alien_collision_flag() &&
people_vector[x].check_alien_collision(alien_vector[i])){
alien_vector[i].set_collision_people_element(x);
}
}
//draws collision if detected
if(alien_vector[i].get_collision_people_element() > -1){
alien_vector[i].draw_alien(lcd,spaceship.get_pos(),d_,
map.get_length_map(), map.get_position_x_map(),true);
}else{
alien_vector[i].draw_alien(lcd,spaceship.get_pos(),d_,
map.get_length_map(), map.get_position_x_map(),false);
}
}
void GameEngine::alliens_fire_bullets(int i){
if (alien_vector[i].get_alien_fire_counter()%60 == 0){
Weapons alien_bullet;
// fires bullet towards direction of spaceship
bool alien_bullet_direction = false;
Vector2D spaceship_pos = spaceship.get_pos();
Vector2D alien_pos = alien_vector[i].get_pos();
if(spaceship_pos.x > alien_pos.x){
alien_bullet_direction = true;
}
alien_bullet.init(alien_vector[i].get_pos(),
alien_bullet_direction , false);
// Stores bullet object in vector
alien_bullet_vector.push_back(alien_bullet);
}
}
void GameEngine::delete_aliens(int i){
for (int x = 0; x < bullet_vector.size(); x++){
if (alien_vector[i].check_collision(bullet_vector[x])){
create_explosion(alien_vector[i].get_pos());
//delete person object if was carried by destroyed alien
if(alien_vector[i].get_collision_people_element() > -1){
people_vector.erase(people_vector.begin() +
alien_vector[i].get_collision_people_element());
}
bullet_vector.erase(bullet_vector.begin()+ x);
alien_vector.erase(alien_vector.begin()+ i);
points_ ++;
}
}
}
void GameEngine::draw_aliens(){
// interates over alien vector and draws each new_alien object
for (int i = 0; i < alien_vector.size(); i++){
check_alien_people_collision(i);
// deleted spaceship if alien ship touches spaceship
if (spaceship.check_alien_collision(alien_vector[i]) &&
!spaceship_destroyed_){
create_explosion(spaceship.get_pos());
spaceship_destroyed_ = true;
}
alliens_fire_bullets(i);
delete_aliens(i);
}
}
//Explotion Control ------------------------------------------------------------
void GameEngine::create_explosion(Vector2D destroyed_position){
// explosion object
Explosion new_explosion;
new_explosion.init(destroyed_position);
// Stores explosion object in vector
explosion_vector.push_back(new_explosion);
}
void GameEngine::draw_explosions(){
// interates over expoltion vector and draws each explosion object then
// deleted object after set size
for (int i = 0; i < explosion_vector.size(); i++){
explosion_vector[i].draw_explosion(lcd);
// delete explosion after reaches set size
if(explosion_vector[i].get_explosion_radius() == 8){
explosion_vector.erase(explosion_vector.begin()+ i);
}
}
}
//People Control ---------------------------------------------------------------
void GameEngine::spawn_people(){
// Keeps number of people objects constant as people objecs are erased
if(people_vector.size() <= 5){
create_people();
}
}
void GameEngine::create_people(){
// People object
People people;
people.init(pad, (rand() % 168 - 84));
// Stores alien object in vector
people_vector.push_back(people);
}
void GameEngine::draw_people(){
for (int i = 0; i < people_vector.size(); i++){
people_vector[i].draw_people(lcd, d_,
map.get_length_map(), map.get_position_x_map());
//errase person if at top of screen as captured by alien and alien is
//set to track mode
Vector2D people_pos = people_vector[i].get_pos();
for (int x = 0; x < alien_vector.size(); x++){
Vector2D alien_pos = alien_vector[x].get_pos();
if(people_pos.y < 30 && alien_pos.y < 9){
//set alien who abducted person to track mode
if(alien_vector[x].get_collision_people_element() == i){
alien_vector[x].set_track_flag(true);
people_vector.erase(people_vector.begin()+ i);
}
}
}
}
}
//Map Control-------------------------------------------------------------------
void GameEngine::reset_map_timer(){
if(spaceship_destroyed_){
reset_map_counter_++;
// stops map movement
d_ = CENTRE;
// reset map after set time
if(reset_map_counter_ == 50){
reset_map();
}
}
}
void GameEngine::reset_map(){
// Reassign values to variables
spaceship.init();
spaceship_lives_--;
spaceship_destroyed_ = false;
reset_map_counter_ = 0;
// erase aliens so redrawn in random positions when respawning spaceship
for (int i = (alien_vector.size() - 1); i >= 0 ; i--){
alien_vector.erase(alien_vector.begin()+ i);
}
// erase all people so redrawn at bottom of map
for (int i = (people_vector.size() - 1); i >= 0 ; i--){
people_vector.erase(people_vector.begin()+ i);
}
// erase all alien bullets
for (int i = (alien_bullet_vector.size() - 1); i >= 0 ; i--){
alien_bullet_vector.erase(alien_bullet_vector.begin()+ i);
}
}