ELEC2645 (2018/19) / Mbed 2 deprecated el17lw

Dependencies:   mbed

Committer:
lewisgw
Date:
Tue Apr 16 19:19:43 2019 +0000
Revision:
20:a8cad4e044ea
Parent:
19:f35887b14c23
Child:
21:20478f086bc2
Added sounds throughout the game for jumping, falling, collisions and dying sequence and added a musical tune that plays over the menus.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
lewisgw 5:eda40cdde3e7 1 #include "Engine.h"
lewisgw 5:eda40cdde3e7 2
lewisgw 15:876c047a6ec9 3 char buffer[14];
lewisgw 15:876c047a6ec9 4
lewisgw 14:9861fe85c803 5 // Constructor and destructor
lewisgw 9:fff2009f826e 6 Engine::Engine() {}
lewisgw 5:eda40cdde3e7 7
lewisgw 9:fff2009f826e 8 Engine::~Engine() {}
lewisgw 5:eda40cdde3e7 9
lewisgw 15:876c047a6ec9 10 void Engine::init() {
lewisgw 15:876c047a6ec9 11 // Initialisation of the game. 40 and 22 refer to inital line lengths.
lewisgw 15:876c047a6ec9 12 reset_skater();
lewisgw 17:f377df4ea7b1 13 reset_engine();
lewisgw 15:876c047a6ec9 14 srand(time(NULL));
lewisgw 15:876c047a6ec9 15 }
lewisgw 15:876c047a6ec9 16
lewisgw 20:a8cad4e044ea 17 void Engine::check_reset(N5110 &lcd, Gamepad &gamepad) {
lewisgw 14:9861fe85c803 18 // Reset the game if the skater has fallen (i.e. reset flag = TRUE).
lewisgw 14:9861fe85c803 19 // 40 and 22 refer to the inital lengths of lower and upper platfroms respectivly.
lewisgw 9:fff2009f826e 20 if (_skater.get_reset_flag()) {
lewisgw 17:f377df4ea7b1 21 wait(1);
lewisgw 17:f377df4ea7b1 22 lcd.clear();
lewisgw 19:f35887b14c23 23 for (int i = 0; i < 40; i = i + 8) {
lewisgw 19:f35887b14c23 24 for (int j = 0; j < 84; j++) {
lewisgw 19:f35887b14c23 25 lcd.setPixel(j,i,true);
lewisgw 19:f35887b14c23 26 lcd.setPixel(i,j,true);
lewisgw 19:f35887b14c23 27 lcd.printString("TRY AGAIN",30,5);
lewisgw 19:f35887b14c23 28 lcd.refresh();
lewisgw 20:a8cad4e044ea 29 gamepad.tone(int(1099 - 15.4*j - 1.2*i), 0.05);
lewisgw 19:f35887b14c23 30 wait(0.001);
lewisgw 20:a8cad4e044ea 31 sprintf(buffer,"%2d",_player_score);
lewisgw 20:a8cad4e044ea 32 lcd.printString(buffer,0,5);
lewisgw 19:f35887b14c23 33 }
lewisgw 19:f35887b14c23 34 }
lewisgw 8:5327418f823a 35 wait(1);
lewisgw 20:a8cad4e044ea 36 reset_skater();
lewisgw 20:a8cad4e044ea 37 reset_engine();
lewisgw 9:fff2009f826e 38 }
lewisgw 9:fff2009f826e 39 }
lewisgw 9:fff2009f826e 40
lewisgw 9:fff2009f826e 41 void Engine::reset_skater() {
lewisgw 18:304700b5d8f8 42 _skater_direction = Left;
lewisgw 11:b66170249a26 43 _start_platform = true;
lewisgw 17:f377df4ea7b1 44 _skater.set_reset_flag(false);
lewisgw 19:f35887b14c23 45 _moving_counter = 0;
lewisgw 19:f35887b14c23 46 _jump_counter = 20;
lewisgw 19:f35887b14c23 47 _fall_flag = false;
lewisgw 17:f377df4ea7b1 48 }
lewisgw 17:f377df4ea7b1 49
lewisgw 17:f377df4ea7b1 50 void Engine::reset_engine() {
lewisgw 17:f377df4ea7b1 51 _input.coord.x = 0;
lewisgw 17:f377df4ea7b1 52 _input.coord.y = 0;
lewisgw 17:f377df4ea7b1 53 _input.A_flag = false;
lewisgw 18:304700b5d8f8 54 _lower_platforms.init(40);
lewisgw 18:304700b5d8f8 55 _upper_platforms.init(22);
lewisgw 17:f377df4ea7b1 56 _coin.init();
lewisgw 18:304700b5d8f8 57 _fire.init();
lewisgw 17:f377df4ea7b1 58 _coin_collision_flag = false;
lewisgw 17:f377df4ea7b1 59 _player_score = 0;
lewisgw 9:fff2009f826e 60 }
lewisgw 8:5327418f823a 61
lewisgw 5:eda40cdde3e7 62 void Engine::read_input(Gamepad &gamepad) {
lewisgw 9:fff2009f826e 63 _input.coord = gamepad.get_mapped_coord();
lewisgw 9:fff2009f826e 64 _input.A_flag = gamepad.check_event(Gamepad::A_PRESSED);
lewisgw 9:fff2009f826e 65 }
lewisgw 5:eda40cdde3e7 66
lewisgw 20:a8cad4e044ea 67 void Engine::process_y(Gamepad &gamepad) {
lewisgw 14:9861fe85c803 68 // Sets the y coordinate by checking if the skater should be falling, and
lewisgw 14:9861fe85c803 69 // updating the fall flag and jump counter.
lewisgw 9:fff2009f826e 70 set_fall_flag();
lewisgw 9:fff2009f826e 71 if (_fall_flag) {
lewisgw 20:a8cad4e044ea 72 _skater.fall(_fall_flag, gamepad);
lewisgw 9:fff2009f826e 73 } else {
lewisgw 20:a8cad4e044ea 74 _skater.set_y_position( _input.A_flag, _jump_counter, _level_condition, gamepad);
lewisgw 9:fff2009f826e 75 }
lewisgw 9:fff2009f826e 76 _fall_flag = _skater.get_fall_flag();
lewisgw 18:304700b5d8f8 77 _skater_y = _skater.get_y_position();
lewisgw 9:fff2009f826e 78 _jump_counter = _skater.get_jump_counter();
lewisgw 9:fff2009f826e 79 }
lewisgw 14:9861fe85c803 80
lewisgw 9:fff2009f826e 81 void Engine::set_fall_flag() {
lewisgw 14:9861fe85c803 82 // Set the fall flag to true if the skater is not on one of the platforms.
lewisgw 18:304700b5d8f8 83 if (((_lower_line_1.x_end < _skater_x) && (_skater_x < (_lower_line_2.x_start - 6))) && _skater_y == 23) {
lewisgw 9:fff2009f826e 84 _fall_flag = true;
lewisgw 18:304700b5d8f8 85 } else if (((_lower_line_2.x_end < _skater_x) && (_skater_x < (_lower_line_3.x_start - 6))) && _skater_y == 23) {
lewisgw 9:fff2009f826e 86 _fall_flag = true;
lewisgw 18:304700b5d8f8 87 } else if (((_lower_line_3.x_end < _skater_x) && (_skater_x < (_lower_line_1.x_start - 6))) && _skater_y == 23) {
lewisgw 9:fff2009f826e 88 _fall_flag = true;
lewisgw 9:fff2009f826e 89 }
lewisgw 9:fff2009f826e 90 }
lewisgw 5:eda40cdde3e7 91
lewisgw 17:f377df4ea7b1 92 void Engine::process_x(int game_counter) {
lewisgw 17:f377df4ea7b1 93 // Update x coordinate.
lewisgw 14:9861fe85c803 94 // Will move the skater to the left along with the platforms (if he is not moving
lewisgw 17:f377df4ea7b1 95 // left already). Speed divider is dependent on the number of coins you have, more coins
lewisgw 17:f377df4ea7b1 96 // means moves faster.
lewisgw 17:f377df4ea7b1 97 _skater.set_x_position_and_sprite(_input.coord.x,
lewisgw 17:f377df4ea7b1 98 _moving_counter,
lewisgw 18:304700b5d8f8 99 _skater_direction,
lewisgw 17:f377df4ea7b1 100 _input.coord.y);
lewisgw 18:304700b5d8f8 101 _skater_x = _skater.get_x_position();
lewisgw 17:f377df4ea7b1 102 _moving_counter = _skater.get_moving_counter();
lewisgw 17:f377df4ea7b1 103 _speed_divider = int(-0.05*_player_score + 4);
lewisgw 17:f377df4ea7b1 104 if ((game_counter % _speed_divider == 0) && (_input.coord.x > -0.1)) {
lewisgw 17:f377df4ea7b1 105 _moving_counter--;
lewisgw 9:fff2009f826e 106 }
lewisgw 9:fff2009f826e 107 }
lewisgw 5:eda40cdde3e7 108
lewisgw 5:eda40cdde3e7 109 void Engine::process_sprite() {
lewisgw 14:9861fe85c803 110 // Update the sprite and direction.
lewisgw 18:304700b5d8f8 111 _skater_sprite = _skater.get_sprite_value();
lewisgw 18:304700b5d8f8 112 _skater_direction = _skater.get_direction();
lewisgw 9:fff2009f826e 113 }
lewisgw 5:eda40cdde3e7 114
lewisgw 5:eda40cdde3e7 115
lewisgw 10:8bf3713d9e9c 116 void Engine::set_level_condition() {
lewisgw 14:9861fe85c803 117 // If the skater is under or on top of any of the upper platforms, set
lewisgw 14:9861fe85c803 118 // level condition to 1.
lewisgw 18:304700b5d8f8 119 if (((_upper_line_1.x_start - 6) <= _skater_x) && (_skater_x <= _upper_line_1.x_end)) {
lewisgw 10:8bf3713d9e9c 120 _level_condition = 1;
lewisgw 18:304700b5d8f8 121 } else if (((_upper_line_2.x_start - 6) <= _skater_x) && (_skater_x <= _upper_line_2.x_end)) {
lewisgw 10:8bf3713d9e9c 122 _level_condition = 1;
lewisgw 18:304700b5d8f8 123 } else if (((_upper_line_3.x_start - 6) <= _skater_x) && (_skater_x <= _upper_line_3.x_end)) {
lewisgw 10:8bf3713d9e9c 124 _level_condition = 1;
lewisgw 9:fff2009f826e 125 } else {
lewisgw 10:8bf3713d9e9c 126 _level_condition = 0;
lewisgw 10:8bf3713d9e9c 127 }
lewisgw 9:fff2009f826e 128 }
lewisgw 7:bbc2b75c1418 129
lewisgw 17:f377df4ea7b1 130 void Engine::generate_level(int game_counter) {
lewisgw 16:331be5c7ed80 131 // Generate parameters for all objects in the level (except skater)
lewisgw 10:8bf3713d9e9c 132 generate_lower_lines();
lewisgw 10:8bf3713d9e9c 133 generate_upper_lines();
lewisgw 15:876c047a6ec9 134 _coin.generate_coin();
lewisgw 18:304700b5d8f8 135 generate_fire(game_counter);
lewisgw 9:fff2009f826e 136 }
lewisgw 5:eda40cdde3e7 137
lewisgw 10:8bf3713d9e9c 138 void Engine::generate_lower_lines() {
lewisgw 14:9861fe85c803 139 // Use a scaled random number to generate the length of the lower lines.
lewisgw 10:8bf3713d9e9c 140 _length_1 = (rand() %20) + 10;
lewisgw 18:304700b5d8f8 141 _lower_platforms.generate_line_1(_length_1);
lewisgw 18:304700b5d8f8 142 _lower_line_1 = _lower_platforms.get_line_1();
lewisgw 10:8bf3713d9e9c 143 _length_2 = (rand() %20) + 10;
lewisgw 18:304700b5d8f8 144 _lower_platforms.generate_line_2(_length_2);
lewisgw 18:304700b5d8f8 145 _lower_line_2 = _lower_platforms.get_line_2();
lewisgw 10:8bf3713d9e9c 146 _length_3 = (rand() %20) + 10;
lewisgw 18:304700b5d8f8 147 _lower_platforms.generate_line_3(_length_3);
lewisgw 18:304700b5d8f8 148 _lower_line_3 = _lower_platforms.get_line_3();
lewisgw 10:8bf3713d9e9c 149 }
lewisgw 10:8bf3713d9e9c 150
lewisgw 10:8bf3713d9e9c 151 void Engine::generate_upper_lines() {
lewisgw 14:9861fe85c803 152 // Set the length of the lower lines to be proportionally smaller to
lewisgw 14:9861fe85c803 153 // the length of the upper lines.
lewisgw 18:304700b5d8f8 154 _upper_platforms.generate_line_1(_length_1 / 2);
lewisgw 18:304700b5d8f8 155 _upper_line_1 = _upper_platforms.get_line_1();
lewisgw 18:304700b5d8f8 156 _upper_platforms.generate_line_2(_length_2 / 2);
lewisgw 18:304700b5d8f8 157 _upper_line_2 = _upper_platforms.get_line_2();
lewisgw 18:304700b5d8f8 158 _upper_platforms.generate_line_3(_length_3 / 2);
lewisgw 18:304700b5d8f8 159 _upper_line_3 = _upper_platforms.get_line_3();
lewisgw 10:8bf3713d9e9c 160 }
lewisgw 5:eda40cdde3e7 161
lewisgw 18:304700b5d8f8 162 void Engine::generate_fire(int game_counter) {
lewisgw 18:304700b5d8f8 163 // Generate the x and y coordinate of the fire. X is from the fire class method and
lewisgw 18:304700b5d8f8 164 // y is claculated from a quadratic expression that oscilates from 5 to 23 with the
lewisgw 19:f35887b14c23 165 // game counter going from 0 to 99 periodicly as its input.
lewisgw 18:304700b5d8f8 166 _fire.update_fire();
lewisgw 19:f35887b14c23 167 _fire_y = int(-0.0073*game_counter*game_counter + 0.73*game_counter + 5);
lewisgw 16:331be5c7ed80 168 }
lewisgw 16:331be5c7ed80 169
lewisgw 5:eda40cdde3e7 170 void Engine::update_lcd(N5110 &lcd){
lewisgw 18:304700b5d8f8 171 lcd.drawSprite(_skater_x,_skater_y,17,10,(int *)_skater.get_sprite(_skater_sprite));
lewisgw 16:331be5c7ed80 172 lcd.drawSprite(_coin.get_coin_x(),_coin.get_coin_y(),5,5,(int*)_coin.get_coin_sprite());
lewisgw 18:304700b5d8f8 173 lcd.drawSprite(_fire.get_fire_x(),_fire_y,5,8,(int*)_fire.get_fire_sprite());
lewisgw 10:8bf3713d9e9c 174 lcd.drawLine(_lower_line_2.x_start,_lower_line_2.y,_lower_line_2.x_end,_lower_line_2.y,FILL_BLACK);
lewisgw 10:8bf3713d9e9c 175 lcd.drawLine(_lower_line_1.x_start,_lower_line_1.y,_lower_line_1.x_end,_lower_line_1.y,FILL_BLACK);
lewisgw 10:8bf3713d9e9c 176 lcd.drawLine(_lower_line_3.x_start,_lower_line_3.y,_lower_line_3.x_end,_lower_line_3.y,FILL_BLACK);
lewisgw 10:8bf3713d9e9c 177 lcd.drawLine(_upper_line_2.x_start,_upper_line_2.y,_upper_line_2.x_end,_upper_line_2.y,FILL_BLACK);
lewisgw 10:8bf3713d9e9c 178 lcd.drawLine(_upper_line_1.x_start,_upper_line_1.y,_upper_line_1.x_end,_upper_line_1.y,FILL_BLACK);
lewisgw 10:8bf3713d9e9c 179 lcd.drawLine(_upper_line_3.x_start,_upper_line_3.y,_upper_line_3.x_end,_upper_line_3.y,FILL_BLACK);
lewisgw 15:876c047a6ec9 180 sprintf(buffer,"%2d",_player_score);
lewisgw 15:876c047a6ec9 181 lcd.printString(buffer,0,0);
lewisgw 11:b66170249a26 182 }
lewisgw 11:b66170249a26 183
lewisgw 11:b66170249a26 184 bool Engine::get_start_platform() {
lewisgw 14:9861fe85c803 185 // Set start platform flag to be false if the button A is pressed
lewisgw 14:9861fe85c803 186 // (so the starting text goes away after the first jump).
lewisgw 11:b66170249a26 187 if(_input.A_flag) _start_platform = false;
lewisgw 11:b66170249a26 188 return _start_platform;
lewisgw 15:876c047a6ec9 189 }
lewisgw 15:876c047a6ec9 190
lewisgw 20:a8cad4e044ea 191 void Engine::check_coin_collision(Gamepad &gamepad) {
lewisgw 16:331be5c7ed80 192 // If the skater coords match the coins, add 1 to the players score and print
lewisgw 16:331be5c7ed80 193 // a new coin in a random position
lewisgw 18:304700b5d8f8 194 if (_skater_x == _coin.get_coin_x() && (_skater_y == _coin.get_coin_y() - 10)) {
lewisgw 15:876c047a6ec9 195 _coin_collision_flag = true;
lewisgw 15:876c047a6ec9 196 _player_score++;
lewisgw 20:a8cad4e044ea 197 _coin.update_coin((rand() % 100),(abs(rand() % 100 - 20)));
lewisgw 20:a8cad4e044ea 198 gamepad.tone(1500, 0.05);
lewisgw 20:a8cad4e044ea 199 wait(0.05);
lewisgw 20:a8cad4e044ea 200 gamepad.tone(3000, 0.05);
lewisgw 15:876c047a6ec9 201 }
lewisgw 16:331be5c7ed80 202 }
lewisgw 16:331be5c7ed80 203
lewisgw 20:a8cad4e044ea 204 void Engine::check_fire_collision(Gamepad &gamepad) {
lewisgw 18:304700b5d8f8 205 // If the skaters coord match the fire and he is not ducking, the player has died
lewisgw 17:f377df4ea7b1 206 // and the game is reset. Game will also reset if skater goes off the screen.
lewisgw 19:f35887b14c23 207 if (_input.coord.y > -0.1 && _skater_x == _fire.get_fire_x() && _skater_y > _fire_y - 10 && _skater_y < _fire_y + 10) {
lewisgw 17:f377df4ea7b1 208 _skater.set_reset_flag(true);
lewisgw 20:a8cad4e044ea 209 gamepad.tone(400, 0.25);
lewisgw 20:a8cad4e044ea 210 wait(0.05);
lewisgw 20:a8cad4e044ea 211 gamepad.tone(200, 0.25);
lewisgw 18:304700b5d8f8 212 } else if ( _skater_x < -10 || _skater_x > 84 ) {
lewisgw 16:331be5c7ed80 213 _skater.set_reset_flag(true);
lewisgw 20:a8cad4e044ea 214 gamepad.tone(200, 0.5);
lewisgw 16:331be5c7ed80 215 }
lewisgw 16:331be5c7ed80 216 }
lewisgw 17:f377df4ea7b1 217
lewisgw 17:f377df4ea7b1 218 int Engine::get_player_score() {
lewisgw 17:f377df4ea7b1 219 return _player_score;
lewisgw 17:f377df4ea7b1 220 }
lewisgw 16:331be5c7ed80 221