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
Diff: Engine/Engine.cpp
- Revision:
- 26:4253656c0755
- Parent:
- 23:ff9073e12106
- Child:
- 27:c920c5ec31af
--- a/Engine/Engine.cpp Wed Apr 24 17:58:35 2019 +0000 +++ b/Engine/Engine.cpp Fri May 03 09:33:34 2019 +0000 @@ -1,7 +1,8 @@ #include "Engine.h" // Reference for the technique used to generate random numbers. -// [1] "rand" cplusplus. [Online] Available: http://www.cplusplus.com/reference/cstdlib/rand/ [Accessed: 22 April 2019]. +// [1] "rand" cplusplus. [Online] Available: +// http://www.cplusplus.com/reference/cstdlib/rand/ [Accessed: 22 April 2019]. // Buffer to print updated score. char buffer[14]; @@ -20,15 +21,17 @@ void Engine::check_reset(N5110 &lcd, Gamepad &gamepad) { // If reset flag is true, end and restart the game. if (_skater.get_reset_flag()) { + gamepad.leds_on(); execute_dying_sequence(lcd, gamepad); - wait(1); + wait(1); // Short pause. reset_skater(); reset_engine(); } } void Engine::execute_dying_sequence(N5110 &lcd, Gamepad &gamepad) { - wait(1); + wait(1); // Short pause. + gamepad.leds_off(); lcd.clear(); for (int i = 0; i < 40; i = i + 8) { // Counter for y direction, sweeps top // to bottom. @@ -38,8 +41,8 @@ lcd.printString("TRY AGAIN",30,5); lcd.refresh(); gamepad.tone(int(1099 - 15.4*j - 1.2*i), 0.05); // Frequnecy of tone is - // dependent on counters. - wait(0.001); + // dependent on counters. + wait(0.001); // Control speed of the sequence. sprintf(buffer,"%2d",_player_score); lcd.printString(buffer,0,5); } @@ -51,7 +54,7 @@ _start_platform_flag = true; // For printing start text in EngineController. _skater.set_reset_flag(false); _moving_counter = 0; - _jump_counter = 20; + _jump_counter = 20; // Start game falling onto the platform. _fall_flag = false; } @@ -65,16 +68,18 @@ _fire.init(); _coin_collision_flag = false; _player_score = 0; + _fire_height = 0; } void Engine::read_input(Gamepad &gamepad) { + // Set up the input struct. _input.coord = gamepad.get_mapped_coord(); _input.A_flag = gamepad.check_event(Gamepad::A_PRESSED); } void Engine::process_y(Gamepad &gamepad) { // Sets the y coord by first checking if the skater should be falling. - set_fall_flag(); + set_fall_flag(); // Update the fall flag dependent on skater position. if (_fall_flag) { _skater.fall(_fall_flag, gamepad); } else { @@ -88,15 +93,19 @@ void Engine::set_fall_flag() { // Set the fall flag to true if the skater is not on one of the lower - // platforms. + // platforms. The start platform condition has been offset by 6 to account for + // skater sprite size. + // If the skater is between platform 1 and 2, and on the lower level. if (((_lower_line_1.x_end < _skater_x) && (_skater_x < (_lower_line_2.x_start - 6))) - && _skater_y == 23) { + && _skater_y == 23) { _fall_flag = true; + // If the skater is between platforms 2 and 3, and on the lower level. } else if (((_lower_line_2.x_end < _skater_x) && (_skater_x < (_lower_line_3.x_start - 6))) && _skater_y == 23) { _fall_flag = true; + // If the skater is between platforms 3 and 1, and on the lower level. } else if (((_lower_line_3.x_end < _skater_x) && (_skater_x < (_lower_line_1.x_start - 6))) && _skater_y == 23) { @@ -112,9 +121,11 @@ _input.coord.y); _skater_x = _skater.get_x_position(); _moving_counter = _skater.get_moving_counter(); // Update moving counter. - _speed_divider = int(-0.05*_player_score + 4); + _speed_divider = int(-0.05*_player_score + 4); // Speed divider is calculated + // from player score. + // Move the skater along with platforms at rate determined by speed divider if + // the skater is not moving left. if ((game_counter % _speed_divider == 0) && (_input.coord.x > -0.1)) { - // Move the skater along with platforms at rate determined by speed divider. _moving_counter--; } } @@ -128,13 +139,17 @@ void Engine::set_level_condition() { // If the skater is under or on top of any of the upper platforms, set - // level condition to 1. + // level condition to 1. + // Offset of 6 is to account for sprite size. + // If the skater is between start and end of upper platform 1. if (((_upper_line_1.x_start - 6) <= _skater_x) && (_skater_x <= _upper_line_1.x_end)) { _level_condition = 1; + // If the skater is between start and end of upper platform 2. } else if (((_upper_line_2.x_start - 6) <= _skater_x) && (_skater_x <= _upper_line_2.x_end)) { _level_condition = 1; + // If the skater is between start and end of upper platform 3. } else if (((_upper_line_3.x_start - 6) <= _skater_x) && (_skater_x <= _upper_line_3.x_end)) { _level_condition = 1; @@ -144,21 +159,50 @@ } void Engine::generate_level(int game_counter) { + // Generate properties for the level. generate_lower_lines(); generate_upper_lines(); _coin.generate_coin(); generate_fire(game_counter); } +void Engine::draw_screen_fire(int game_counter, N5110 &lcd) { + // Prints the dynamic fire at the bottom of the screen. + // Restricts the max fire height multiplier, which is dependent on player + // score. + if (_player_score < 15) { + _fire_height = _player_score; + } else { + _fire_height = 14; + } + // i corresponds to horizontal positions of pixels. + for (int i = 1; i < 84; i++) { + if (i % 4 == 0) { + // j corresponds to vertical height of pixels, and the max height is + // dependent on game counter (0 to 99) so changes every loop, and is + // scaled. + for (int j = 0; j < game_counter*0.01*_fire_height; j++) { + lcd.setPixel(i + (rand() % 8 + 1) ,50 - j*1.3,true); // Horizontal + // position of pixel is constrained random [1], multiplier on j varies + // local height. + lcd.setPixel(i - (rand() % 8 + 1) ,50 - j*1.2,true); // [1]. + lcd.setPixel(i - (rand() % 8 + 1) ,50 - j*1.6,true); // [1]. + lcd.setPixel(i + (rand() % 8 + 1) ,50 - j*1.1,true); // [1]. + lcd.setPixel(i - (rand() % 8 + 1) ,50 - j*1.4,true); // [1]. + } + } + } +} + void Engine::generate_lower_lines() { // Use a scaled random number to generate the length of the lower lines. - _length_1 = (rand() %20) + 10; // [1]. + _length_1 = (rand() %20) + 10; // [1]. _lower_platforms.set_line_1(_length_1); _lower_line_1 = _lower_platforms.get_line_1(); - _length_2 = (rand() %20) + 10; // [1]. + _length_2 = (rand() %20) + 10; // [1]. _lower_platforms.set_line_2(_length_2); _lower_line_2 = _lower_platforms.get_line_2(); - _length_3 = (rand() %20) + 10; // [1]. + _length_3 = (rand() %20) + 10; // [1]. _lower_platforms.set_line_3(_length_3); _lower_line_3 = _lower_platforms.get_line_3(); } @@ -177,11 +221,12 @@ void Engine::generate_fire(int game_counter) { // Generates the x and y coordinate of the fire. Y oscillates from 5 to 23. _fire.generate_fire(); // Generates X coord of fire. + // Y is calculated from parabolic relation to game counter. _fire_y = int(-0.0073*game_counter*game_counter + 0.73*game_counter + 5); - // Y is calculated from parabolic relation to game counter. } -void Engine::update_lcd(N5110 &lcd){ +void Engine::update_lcd(N5110 &lcd, int game_counter){ + // Draw all sprites, screen fire, platforms and player score. 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, @@ -201,36 +246,41 @@ _upper_line_3.y,FILL_BLACK); sprintf(buffer,"%2d",_player_score); lcd.printString(buffer,0,0); + draw_screen_fire(game_counter, lcd); } bool Engine::get_start_platform_flag() { - if (_input.A_flag) _start_platform_flag = false; // Means starting platform - // will vanish after first jump of the game. + if (_input.A_flag) _start_platform_flag = false; // Makes starting platform + // vanish after first jump of the game. return _start_platform_flag; } void Engine::check_coin_collision(Gamepad &gamepad) { + // If skater x and y coord matches the coin's. Small adjustment for Y coord + // compensates for skater sprite size. if (_skater_x == _coin.get_coin_x() - && (_skater_y == _coin.get_coin_y() - 10)) { // Small adjustment for Y - // coord compensates for skater sprite size. + && (_skater_y == _coin.get_coin_y() - 10)) { _coin_collision_flag = true; _player_score++; _coin.set_coin((rand() % 100),(abs(rand() % 100 - 20))); // Place coin // on a constrained random position, [1]. - gamepad.tone(1500, 0.05); // Make noise on buzzer. + gamepad.tone(1500, 0.05); // Make collection noise on buzzer. wait(0.05); gamepad.tone(3000, 0.05); } } -void Engine::check_fire_collision(Gamepad &gamepad) { +void Engine::check_fire_collision(Gamepad &gamepad, int game_counter) { + // If skater is not ducking, has same x coord and within a range of y coord + // as fire. if (_input.coord.y > -0.1 && _skater_x == _fire.get_fire_x() && _skater_y > _fire_y - 10 - && _skater_y < _fire_y + 10) { // If skater is not ducking. A range of Y - // coords to make collision more frequent. + && _skater_y < _fire_y + 10 + ) { // A range of Y coords to make collision + // more frequent. _skater.set_reset_flag(true); - gamepad.tone(400, 0.25); // Make noise on buzzer. + gamepad.tone(400, 0.25); // Make collision noise on buzzer. wait(0.05); gamepad.tone(200, 0.25); } else if ( _skater_x < -10 || _skater_x > 84 ) { // If skater goes off the @@ -238,6 +288,11 @@ _skater.set_reset_flag(true); gamepad.tone(200, 0.5); } + // If the skater collides with the scaled peak of the background fire. + if (_skater_y > (50 - game_counter*_fire_height*0.023)) { + _fall_flag = true; + wait(0.05); // Slow down falling sequence. + } } int Engine::get_player_score() {