ELEC2645 (2018/19) / Mbed 2 deprecated el17lw

Dependencies:   mbed

Committer:
lewisgw
Date:
Mon Apr 22 16:28:04 2019 +0000
Revision:
22:d2969236b4f3
Parent:
21:20478f086bc2
ELEC 2665 Gamepad Project.; SID: 201122085

Who changed what in which revision?

UserRevisionLine numberNew contents of line
lewisgw 5:eda40cdde3e7 1 #include "Engine.h"
lewisgw 5:eda40cdde3e7 2
lewisgw 22:d2969236b4f3 3 // Reference for the technique used to generate random numbers.
lewisgw 22:d2969236b4f3 4 // [1] "rand" cplusplus. [Online] Available: http://www.cplusplus.com/reference/cstdlib/rand/ [Accessed: 22 April 2019].
lewisgw 22:d2969236b4f3 5
lewisgw 21:20478f086bc2 6 // Buffer to print updated score.
lewisgw 21:20478f086bc2 7 char buffer[14];
lewisgw 15:876c047a6ec9 8
lewisgw 21:20478f086bc2 9 // Constructor and destructor.
lewisgw 9:fff2009f826e 10 Engine::Engine() {}
lewisgw 5:eda40cdde3e7 11
lewisgw 9:fff2009f826e 12 Engine::~Engine() {}
lewisgw 5:eda40cdde3e7 13
lewisgw 15:876c047a6ec9 14 void Engine::init() {
lewisgw 22:d2969236b4f3 15 //
lewisgw 15:876c047a6ec9 16 reset_skater();
lewisgw 17:f377df4ea7b1 17 reset_engine();
lewisgw 22:d2969236b4f3 18 srand(time(NULL)); // Set up for generating random numbers, [1].
lewisgw 15:876c047a6ec9 19 }
lewisgw 15:876c047a6ec9 20
lewisgw 20:a8cad4e044ea 21 void Engine::check_reset(N5110 &lcd, Gamepad &gamepad) {
lewisgw 21:20478f086bc2 22 // If reset flag is true, end and restart the game.
lewisgw 9:fff2009f826e 23 if (_skater.get_reset_flag()) {
lewisgw 21:20478f086bc2 24 execute_dying_sequence(lcd, gamepad);
lewisgw 8:5327418f823a 25 wait(1);
lewisgw 20:a8cad4e044ea 26 reset_skater();
lewisgw 20:a8cad4e044ea 27 reset_engine();
lewisgw 9:fff2009f826e 28 }
lewisgw 9:fff2009f826e 29 }
lewisgw 9:fff2009f826e 30
lewisgw 21:20478f086bc2 31 void Engine::execute_dying_sequence(N5110 &lcd, Gamepad &gamepad) {
lewisgw 21:20478f086bc2 32 wait(1);
lewisgw 21:20478f086bc2 33 lcd.clear();
lewisgw 21:20478f086bc2 34 for (int i = 0; i < 40; i = i + 8) { // Counter for y direction, sweeps top
lewisgw 21:20478f086bc2 35 // to bottom.
lewisgw 21:20478f086bc2 36 for (int j = 0; j < 84; j++) { // Counter for x direction, sweeps L to R
lewisgw 21:20478f086bc2 37 lcd.setPixel(j,i,true);
lewisgw 21:20478f086bc2 38 lcd.setPixel(i,j,true);
lewisgw 21:20478f086bc2 39 lcd.printString("TRY AGAIN",30,5);
lewisgw 21:20478f086bc2 40 lcd.refresh();
lewisgw 21:20478f086bc2 41 gamepad.tone(int(1099 - 15.4*j - 1.2*i), 0.05); // Frequnecy of tone is
lewisgw 21:20478f086bc2 42 // dependent on counters.
lewisgw 21:20478f086bc2 43 wait(0.001);
lewisgw 21:20478f086bc2 44 sprintf(buffer,"%2d",_player_score);
lewisgw 21:20478f086bc2 45 lcd.printString(buffer,0,5);
lewisgw 21:20478f086bc2 46 }
lewisgw 21:20478f086bc2 47 }
lewisgw 21:20478f086bc2 48 }
lewisgw 21:20478f086bc2 49
lewisgw 9:fff2009f826e 50 void Engine::reset_skater() {
lewisgw 18:304700b5d8f8 51 _skater_direction = Left;
lewisgw 21:20478f086bc2 52 _start_platform_flag = true; // For printing start text in EngineController
lewisgw 17:f377df4ea7b1 53 _skater.set_reset_flag(false);
lewisgw 19:f35887b14c23 54 _moving_counter = 0;
lewisgw 21:20478f086bc2 55 _jump_counter = 20;
lewisgw 19:f35887b14c23 56 _fall_flag = false;
lewisgw 17:f377df4ea7b1 57 }
lewisgw 17:f377df4ea7b1 58
lewisgw 17:f377df4ea7b1 59 void Engine::reset_engine() {
lewisgw 17:f377df4ea7b1 60 _input.coord.x = 0;
lewisgw 17:f377df4ea7b1 61 _input.coord.y = 0;
lewisgw 17:f377df4ea7b1 62 _input.A_flag = false;
lewisgw 21:20478f086bc2 63 _lower_platforms.init(40); // 40 is the platform y coord.
lewisgw 21:20478f086bc2 64 _upper_platforms.init(22); // 22 is the platform y coord.
lewisgw 17:f377df4ea7b1 65 _coin.init();
lewisgw 18:304700b5d8f8 66 _fire.init();
lewisgw 17:f377df4ea7b1 67 _coin_collision_flag = false;
lewisgw 17:f377df4ea7b1 68 _player_score = 0;
lewisgw 9:fff2009f826e 69 }
lewisgw 8:5327418f823a 70
lewisgw 5:eda40cdde3e7 71 void Engine::read_input(Gamepad &gamepad) {
lewisgw 9:fff2009f826e 72 _input.coord = gamepad.get_mapped_coord();
lewisgw 9:fff2009f826e 73 _input.A_flag = gamepad.check_event(Gamepad::A_PRESSED);
lewisgw 9:fff2009f826e 74 }
lewisgw 5:eda40cdde3e7 75
lewisgw 20:a8cad4e044ea 76 void Engine::process_y(Gamepad &gamepad) {
lewisgw 21:20478f086bc2 77 // Sets the y coord by first checking if the skater should be falling.
lewisgw 9:fff2009f826e 78 set_fall_flag();
lewisgw 9:fff2009f826e 79 if (_fall_flag) {
lewisgw 20:a8cad4e044ea 80 _skater.fall(_fall_flag, gamepad);
lewisgw 9:fff2009f826e 81 } else {
lewisgw 21:20478f086bc2 82 _skater.set_y_position( _input.A_flag, _jump_counter, _level_condition,
lewisgw 21:20478f086bc2 83 gamepad);
lewisgw 9:fff2009f826e 84 }
lewisgw 21:20478f086bc2 85 _fall_flag = _skater.get_fall_flag(); // Update fall flag.
lewisgw 18:304700b5d8f8 86 _skater_y = _skater.get_y_position();
lewisgw 21:20478f086bc2 87 _jump_counter = _skater.get_jump_counter(); // Update jump counter.
lewisgw 9:fff2009f826e 88 }
lewisgw 14:9861fe85c803 89
lewisgw 9:fff2009f826e 90 void Engine::set_fall_flag() {
lewisgw 21:20478f086bc2 91 // Set the fall flag to true if the skater is not on one of the lower
lewisgw 21:20478f086bc2 92 // platforms.
lewisgw 21:20478f086bc2 93 if (((_lower_line_1.x_end < _skater_x)
lewisgw 21:20478f086bc2 94 && (_skater_x < (_lower_line_2.x_start - 6)))
lewisgw 21:20478f086bc2 95 && _skater_y == 23) {
lewisgw 9:fff2009f826e 96 _fall_flag = true;
lewisgw 21:20478f086bc2 97 } else if (((_lower_line_2.x_end < _skater_x)
lewisgw 21:20478f086bc2 98 && (_skater_x < (_lower_line_3.x_start - 6)))
lewisgw 21:20478f086bc2 99 && _skater_y == 23) {
lewisgw 9:fff2009f826e 100 _fall_flag = true;
lewisgw 21:20478f086bc2 101 } else if (((_lower_line_3.x_end < _skater_x)
lewisgw 21:20478f086bc2 102 && (_skater_x < (_lower_line_1.x_start - 6)))
lewisgw 21:20478f086bc2 103 && _skater_y == 23) {
lewisgw 9:fff2009f826e 104 _fall_flag = true;
lewisgw 9:fff2009f826e 105 }
lewisgw 9:fff2009f826e 106 }
lewisgw 5:eda40cdde3e7 107
lewisgw 17:f377df4ea7b1 108 void Engine::process_x(int game_counter) {
lewisgw 21:20478f086bc2 109 // Sets the x coord.
lewisgw 17:f377df4ea7b1 110 _skater.set_x_position_and_sprite(_input.coord.x,
lewisgw 17:f377df4ea7b1 111 _moving_counter,
lewisgw 18:304700b5d8f8 112 _skater_direction,
lewisgw 17:f377df4ea7b1 113 _input.coord.y);
lewisgw 18:304700b5d8f8 114 _skater_x = _skater.get_x_position();
lewisgw 21:20478f086bc2 115 _moving_counter = _skater.get_moving_counter(); // Update moving counter.
lewisgw 17:f377df4ea7b1 116 _speed_divider = int(-0.05*_player_score + 4);
lewisgw 21:20478f086bc2 117 if ((game_counter % _speed_divider == 0) && (_input.coord.x > -0.1)) {
lewisgw 21:20478f086bc2 118 // Move the skater along with platforms at rate determined by speed divider.
lewisgw 17:f377df4ea7b1 119 _moving_counter--;
lewisgw 9:fff2009f826e 120 }
lewisgw 9:fff2009f826e 121 }
lewisgw 5:eda40cdde3e7 122
lewisgw 5:eda40cdde3e7 123 void Engine::process_sprite() {
lewisgw 14:9861fe85c803 124 // Update the sprite and direction.
lewisgw 18:304700b5d8f8 125 _skater_sprite = _skater.get_sprite_value();
lewisgw 18:304700b5d8f8 126 _skater_direction = _skater.get_direction();
lewisgw 9:fff2009f826e 127 }
lewisgw 5:eda40cdde3e7 128
lewisgw 5:eda40cdde3e7 129
lewisgw 10:8bf3713d9e9c 130 void Engine::set_level_condition() {
lewisgw 14:9861fe85c803 131 // If the skater is under or on top of any of the upper platforms, set
lewisgw 14:9861fe85c803 132 // level condition to 1.
lewisgw 21:20478f086bc2 133 if (((_upper_line_1.x_start - 6) <= _skater_x)
lewisgw 21:20478f086bc2 134 && (_skater_x <= _upper_line_1.x_end)) {
lewisgw 10:8bf3713d9e9c 135 _level_condition = 1;
lewisgw 21:20478f086bc2 136 } else if (((_upper_line_2.x_start - 6) <= _skater_x)
lewisgw 21:20478f086bc2 137 && (_skater_x <= _upper_line_2.x_end)) {
lewisgw 10:8bf3713d9e9c 138 _level_condition = 1;
lewisgw 21:20478f086bc2 139 } else if (((_upper_line_3.x_start - 6) <= _skater_x)
lewisgw 21:20478f086bc2 140 && (_skater_x <= _upper_line_3.x_end)) {
lewisgw 10:8bf3713d9e9c 141 _level_condition = 1;
lewisgw 9:fff2009f826e 142 } else {
lewisgw 10:8bf3713d9e9c 143 _level_condition = 0;
lewisgw 10:8bf3713d9e9c 144 }
lewisgw 9:fff2009f826e 145 }
lewisgw 7:bbc2b75c1418 146
lewisgw 17:f377df4ea7b1 147 void Engine::generate_level(int game_counter) {
lewisgw 10:8bf3713d9e9c 148 generate_lower_lines();
lewisgw 10:8bf3713d9e9c 149 generate_upper_lines();
lewisgw 15:876c047a6ec9 150 _coin.generate_coin();
lewisgw 18:304700b5d8f8 151 generate_fire(game_counter);
lewisgw 9:fff2009f826e 152 }
lewisgw 5:eda40cdde3e7 153
lewisgw 10:8bf3713d9e9c 154 void Engine::generate_lower_lines() {
lewisgw 14:9861fe85c803 155 // Use a scaled random number to generate the length of the lower lines.
lewisgw 22:d2969236b4f3 156 _length_1 = (rand() %20) + 10; // [1].
lewisgw 21:20478f086bc2 157 _lower_platforms.set_line_1(_length_1);
lewisgw 18:304700b5d8f8 158 _lower_line_1 = _lower_platforms.get_line_1();
lewisgw 22:d2969236b4f3 159 _length_2 = (rand() %20) + 10; // [1].
lewisgw 21:20478f086bc2 160 _lower_platforms.set_line_2(_length_2);
lewisgw 18:304700b5d8f8 161 _lower_line_2 = _lower_platforms.get_line_2();
lewisgw 22:d2969236b4f3 162 _length_3 = (rand() %20) + 10; // [1].
lewisgw 21:20478f086bc2 163 _lower_platforms.set_line_3(_length_3);
lewisgw 18:304700b5d8f8 164 _lower_line_3 = _lower_platforms.get_line_3();
lewisgw 10:8bf3713d9e9c 165 }
lewisgw 10:8bf3713d9e9c 166
lewisgw 10:8bf3713d9e9c 167 void Engine::generate_upper_lines() {
lewisgw 21:20478f086bc2 168 // Set the length of the upper lines to be proportionally smaller to
lewisgw 21:20478f086bc2 169 // the length of the lower lines.
lewisgw 21:20478f086bc2 170 _upper_platforms.set_line_1(_length_1 / 2);
lewisgw 18:304700b5d8f8 171 _upper_line_1 = _upper_platforms.get_line_1();
lewisgw 21:20478f086bc2 172 _upper_platforms.set_line_2(_length_2 / 2);
lewisgw 18:304700b5d8f8 173 _upper_line_2 = _upper_platforms.get_line_2();
lewisgw 21:20478f086bc2 174 _upper_platforms.set_line_3(_length_3 / 2);
lewisgw 18:304700b5d8f8 175 _upper_line_3 = _upper_platforms.get_line_3();
lewisgw 10:8bf3713d9e9c 176 }
lewisgw 5:eda40cdde3e7 177
lewisgw 18:304700b5d8f8 178 void Engine::generate_fire(int game_counter) {
lewisgw 21:20478f086bc2 179 // Generates the x and y coordinate of the fire. Y oscillates from 5 to 23.
lewisgw 21:20478f086bc2 180 _fire.generate_fire(); // Generates X coord of fire.
lewisgw 21:20478f086bc2 181 _fire_y = int(-0.0073*game_counter*game_counter + 0.73*game_counter + 5);
lewisgw 21:20478f086bc2 182 // Y is calculated from parabolic relation to game counter.
lewisgw 16:331be5c7ed80 183 }
lewisgw 16:331be5c7ed80 184
lewisgw 5:eda40cdde3e7 185 void Engine::update_lcd(N5110 &lcd){
lewisgw 21:20478f086bc2 186 lcd.drawSprite(_skater_x,_skater_y,17,10,
lewisgw 21:20478f086bc2 187 (int *)_skater.get_sprite(_skater_sprite));
lewisgw 21:20478f086bc2 188 lcd.drawSprite(_coin.get_coin_x(),_coin.get_coin_y(),5,5,
lewisgw 21:20478f086bc2 189 (int*)_coin.get_coin_sprite());
lewisgw 18:304700b5d8f8 190 lcd.drawSprite(_fire.get_fire_x(),_fire_y,5,8,(int*)_fire.get_fire_sprite());
lewisgw 21:20478f086bc2 191 lcd.drawLine(_lower_line_2.x_start,_lower_line_2.y,_lower_line_2.x_end,
lewisgw 21:20478f086bc2 192 _lower_line_2.y,FILL_BLACK);
lewisgw 21:20478f086bc2 193 lcd.drawLine(_lower_line_1.x_start,_lower_line_1.y,_lower_line_1.x_end,
lewisgw 21:20478f086bc2 194 _lower_line_1.y,FILL_BLACK);
lewisgw 21:20478f086bc2 195 lcd.drawLine(_lower_line_3.x_start,_lower_line_3.y,_lower_line_3.x_end,
lewisgw 21:20478f086bc2 196 _lower_line_3.y,FILL_BLACK);
lewisgw 21:20478f086bc2 197 lcd.drawLine(_upper_line_2.x_start,_upper_line_2.y,_upper_line_2.x_end,
lewisgw 21:20478f086bc2 198 _upper_line_2.y,FILL_BLACK);
lewisgw 21:20478f086bc2 199 lcd.drawLine(_upper_line_1.x_start,_upper_line_1.y,_upper_line_1.x_end,
lewisgw 21:20478f086bc2 200 _upper_line_1.y,FILL_BLACK);
lewisgw 21:20478f086bc2 201 lcd.drawLine(_upper_line_3.x_start,_upper_line_3.y,_upper_line_3.x_end,
lewisgw 21:20478f086bc2 202 _upper_line_3.y,FILL_BLACK);
lewisgw 15:876c047a6ec9 203 sprintf(buffer,"%2d",_player_score);
lewisgw 15:876c047a6ec9 204 lcd.printString(buffer,0,0);
lewisgw 11:b66170249a26 205 }
lewisgw 11:b66170249a26 206
lewisgw 21:20478f086bc2 207 bool Engine::get_start_platform_flag() {
lewisgw 21:20478f086bc2 208 if (_input.A_flag) _start_platform_flag = false; // Means starting platform
lewisgw 21:20478f086bc2 209 // will vanish after first jump of the game.
lewisgw 21:20478f086bc2 210 return _start_platform_flag;
lewisgw 15:876c047a6ec9 211 }
lewisgw 15:876c047a6ec9 212
lewisgw 20:a8cad4e044ea 213 void Engine::check_coin_collision(Gamepad &gamepad) {
lewisgw 21:20478f086bc2 214 if (_skater_x == _coin.get_coin_x()
lewisgw 21:20478f086bc2 215 && (_skater_y == _coin.get_coin_y() - 10)) { // Small adjustment for Y
lewisgw 21:20478f086bc2 216 // coord compensates for skater sprite size.
lewisgw 15:876c047a6ec9 217 _coin_collision_flag = true;
lewisgw 15:876c047a6ec9 218 _player_score++;
lewisgw 21:20478f086bc2 219 _coin.set_coin((rand() % 100),(abs(rand() % 100 - 20))); // Place coin
lewisgw 22:d2969236b4f3 220 // on a constrained random position, [1].
lewisgw 21:20478f086bc2 221 gamepad.tone(1500, 0.05); // Make noise on buzzer.
lewisgw 20:a8cad4e044ea 222 wait(0.05);
lewisgw 20:a8cad4e044ea 223 gamepad.tone(3000, 0.05);
lewisgw 15:876c047a6ec9 224 }
lewisgw 16:331be5c7ed80 225 }
lewisgw 16:331be5c7ed80 226
lewisgw 20:a8cad4e044ea 227 void Engine::check_fire_collision(Gamepad &gamepad) {
lewisgw 21:20478f086bc2 228 if (_input.coord.y > -0.1
lewisgw 21:20478f086bc2 229 && _skater_x == _fire.get_fire_x()
lewisgw 21:20478f086bc2 230 && _skater_y > _fire_y - 10
lewisgw 21:20478f086bc2 231 && _skater_y < _fire_y + 10) { // If skater is not ducking. A range of Y
lewisgw 21:20478f086bc2 232 // coords to make collision more frequent.
lewisgw 17:f377df4ea7b1 233 _skater.set_reset_flag(true);
lewisgw 21:20478f086bc2 234 gamepad.tone(400, 0.25); // Make noise on buzzer.
lewisgw 20:a8cad4e044ea 235 wait(0.05);
lewisgw 20:a8cad4e044ea 236 gamepad.tone(200, 0.25);
lewisgw 21:20478f086bc2 237 } else if ( _skater_x < -10 || _skater_x > 84 ) { // If skater goes off the
lewisgw 21:20478f086bc2 238 // screen.
lewisgw 16:331be5c7ed80 239 _skater.set_reset_flag(true);
lewisgw 20:a8cad4e044ea 240 gamepad.tone(200, 0.5);
lewisgw 16:331be5c7ed80 241 }
lewisgw 16:331be5c7ed80 242 }
lewisgw 17:f377df4ea7b1 243
lewisgw 17:f377df4ea7b1 244 int Engine::get_player_score() {
lewisgw 17:f377df4ea7b1 245 return _player_score;
lewisgw 17:f377df4ea7b1 246 }
lewisgw 16:331be5c7ed80 247