ELEC2645 (2018/19) / Mbed 2 deprecated el17lw

Dependencies:   mbed

Engine/Engine.cpp

Committer:
lewisgw
Date:
2019-04-15
Revision:
19:f35887b14c23
Parent:
18:304700b5d8f8
Child:
20:a8cad4e044ea

File content as of revision 19:f35887b14c23:

#include "Engine.h"

char buffer[14];

// Constructor and destructor
Engine::Engine() {} 

Engine::~Engine() {}

void Engine::init() {
  // Initialisation of the game. 40 and 22 refer to inital line lengths. 
  reset_skater();
  reset_engine();
  srand(time(NULL));
}

void Engine::check_reset(N5110 &lcd) {
  // Reset the game if the skater has fallen (i.e. reset flag = TRUE).
  // 40 and 22 refer to the inital lengths of lower and upper platfroms respectivly.
  if (_skater.get_reset_flag()) {
    reset_skater();
    reset_engine();
    wait(1);
    lcd.clear();
    for (int i = 0; i < 40; i = i + 8) {
      for (int j = 0; j < 84; j++) {
        lcd.setPixel(j,i,true);
        lcd.setPixel(i,j,true);
        lcd.printString("TRY AGAIN",30,5);  
        lcd.refresh();
        wait(0.001);
      }  
    }
    wait(1);
  }
}

void Engine::reset_skater() {
  _skater_direction = Left;
  _start_platform = true;
  _skater.set_reset_flag(false);
  _moving_counter = 0;
  _jump_counter = 20;
  _fall_flag = false;
}  

void Engine::reset_engine() {
  _input.coord.x = 0;
  _input.coord.y = 0;
  _input.A_flag = false;
  _lower_platforms.init(40);
  _upper_platforms.init(22);
  _coin.init();
  _fire.init();
  _coin_collision_flag = false;
  _player_score = 0;
}  

void Engine::read_input(Gamepad &gamepad) {
  _input.coord = gamepad.get_mapped_coord(); 
  _input.A_flag = gamepad.check_event(Gamepad::A_PRESSED);
} 

void Engine::process_y() {
  // Sets the y coordinate by checking if the skater should be falling, and
  // updating the fall flag and jump counter.
  set_fall_flag();
  if (_fall_flag) {
    _skater.fall(_fall_flag);
  } else {
    _skater.set_y_position( _input.A_flag, _jump_counter, _level_condition );
  }
  _fall_flag = _skater.get_fall_flag();
  _skater_y = _skater.get_y_position();
  _jump_counter = _skater.get_jump_counter();
}

void Engine::set_fall_flag() {
  // Set the fall flag to true if the skater is not on one of the platforms.
  if (((_lower_line_1.x_end < _skater_x) && (_skater_x < (_lower_line_2.x_start - 6)))  && _skater_y == 23) {
    _fall_flag = true; 
  } else if (((_lower_line_2.x_end < _skater_x) && (_skater_x < (_lower_line_3.x_start - 6))) && _skater_y == 23) {
    _fall_flag = true;
  } else if (((_lower_line_3.x_end < _skater_x) && (_skater_x < (_lower_line_1.x_start - 6))) && _skater_y == 23) {
    _fall_flag = true;
  }   
}
    
void Engine::process_x(int game_counter) {
  // Update x coordinate.
  // Will move the skater to the left along with the platforms (if he is not moving
  // left already). Speed divider is dependent on the number of coins you have, more coins 
  // means moves faster.
  _skater.set_x_position_and_sprite(_input.coord.x, 
    _moving_counter, 
    _skater_direction,
    _input.coord.y);
  _skater_x = _skater.get_x_position();
  _moving_counter = _skater.get_moving_counter();
  _speed_divider = int(-0.05*_player_score + 4);
  if ((game_counter % _speed_divider == 0) && (_input.coord.x > -0.1)) {
    _moving_counter--;
  }
}
    
void Engine::process_sprite() {
  // Update the sprite and direction.
  _skater_sprite = _skater.get_sprite_value();
  _skater_direction = _skater.get_direction();
}


void Engine::set_level_condition() {
  // If the skater is under or on top of any of the upper platforms, set
  // level condition to 1.
  if (((_upper_line_1.x_start - 6) <= _skater_x) && (_skater_x <= _upper_line_1.x_end)) {
    _level_condition = 1; 
  } else if (((_upper_line_2.x_start - 6) <= _skater_x) && (_skater_x <= _upper_line_2.x_end)) {
    _level_condition = 1;
  } else if (((_upper_line_3.x_start - 6) <= _skater_x) && (_skater_x <= _upper_line_3.x_end)) {
    _level_condition = 1;
  } else {
    _level_condition = 0;
  }   
}
    
void Engine::generate_level(int game_counter) {
  // Generate parameters for all objects in the level (except skater)
  generate_lower_lines();
  generate_upper_lines();
  _coin.generate_coin();
  generate_fire(game_counter);
}

void Engine::generate_lower_lines() {
  // Use a scaled random number to generate the length of the lower lines.
  _length_1 = (rand() %20) + 10;   
  _lower_platforms.generate_line_1(_length_1);
  _lower_line_1 = _lower_platforms.get_line_1(); 
  _length_2 = (rand() %20) + 10;      
  _lower_platforms.generate_line_2(_length_2);
  _lower_line_2 = _lower_platforms.get_line_2();
  _length_3 = (rand() %20) + 10;      
  _lower_platforms.generate_line_3(_length_3);
  _lower_line_3 = _lower_platforms.get_line_3();
}

void Engine::generate_upper_lines() {   
  // Set the length of the lower lines to be proportionally smaller to
  // the length of the upper lines.
  _upper_platforms.generate_line_1(_length_1 / 2);
  _upper_line_1 = _upper_platforms.get_line_1();       
  _upper_platforms.generate_line_2(_length_2 / 2);
  _upper_line_2 = _upper_platforms.get_line_2();  
  _upper_platforms.generate_line_3(_length_3 / 2);
  _upper_line_3 = _upper_platforms.get_line_3();
}

void Engine::generate_fire(int game_counter) {
  // Generate the x and y coordinate of the fire. X is from the fire class method and
  // y is claculated from a quadratic expression that oscilates from 5 to 23 with the
  // game counter going from 0 to 99 periodicly as its input.
  _fire.update_fire();
  _fire_y = int(-0.0073*game_counter*game_counter + 0.73*game_counter + 5); 
}

void Engine::update_lcd(N5110 &lcd){
  lcd.drawSprite(_skater_x,_skater_y,17,10,(int *)_skater.get_sprite(_skater_sprite));
  lcd.drawSprite(_coin.get_coin_x(),_coin.get_coin_y(),5,5,(int*)_coin.get_coin_sprite());
  lcd.drawSprite(_fire.get_fire_x(),_fire_y,5,8,(int*)_fire.get_fire_sprite()); 
  lcd.drawLine(_lower_line_2.x_start,_lower_line_2.y,_lower_line_2.x_end,_lower_line_2.y,FILL_BLACK);
  lcd.drawLine(_lower_line_1.x_start,_lower_line_1.y,_lower_line_1.x_end,_lower_line_1.y,FILL_BLACK);
  lcd.drawLine(_lower_line_3.x_start,_lower_line_3.y,_lower_line_3.x_end,_lower_line_3.y,FILL_BLACK);
  lcd.drawLine(_upper_line_2.x_start,_upper_line_2.y,_upper_line_2.x_end,_upper_line_2.y,FILL_BLACK);
  lcd.drawLine(_upper_line_1.x_start,_upper_line_1.y,_upper_line_1.x_end,_upper_line_1.y,FILL_BLACK);
  lcd.drawLine(_upper_line_3.x_start,_upper_line_3.y,_upper_line_3.x_end,_upper_line_3.y,FILL_BLACK);
  sprintf(buffer,"%2d",_player_score);
  lcd.printString(buffer,0,0);
}

bool Engine::get_start_platform() {
  // Set start platform flag to be false if the button A is pressed
  // (so the starting text goes away after the first jump).
  if(_input.A_flag) _start_platform = false;
  return _start_platform;
}

void Engine::check_coin_collision() {
  // If the skater coords match the coins, add 1 to the players score and print
  // a new coin in a random position
  if (_skater_x == _coin.get_coin_x() && (_skater_y == _coin.get_coin_y() - 10)) {
    _coin_collision_flag = true;
    _player_score++;
    _coin.update_coin((rand() % 100),(abs(rand() % 100 - 20)));   
  }
}

void Engine::check_fire_collision() {
  // If the skaters coord match the fire and he is not ducking, the player has died
  // and the game is reset. Game will also reset if skater goes off the screen.
  if (_input.coord.y > -0.1 && _skater_x == _fire.get_fire_x() && _skater_y > _fire_y - 10 && _skater_y < _fire_y + 10) {
    _skater.set_reset_flag(true);
  } else if ( _skater_x < -10 || _skater_x > 84 ) {
    _skater.set_reset_flag(true);
  }
}

int Engine::get_player_score() {
  return _player_score;
}