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
GameEngine/engine.cpp@12:bc9a43f56261, 2019-05-10 (annotated)
- Committer:
- batJoro
- Date:
- Fri May 10 14:38:36 2019 +0000
- Revision:
- 12:bc9a43f56261
- Parent:
- 11:0e6a221ad8a9
final3
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| batJoro | 8:b3738229ba85 | 1 | |
| batJoro | 8:b3738229ba85 | 2 | #include "engine.h" |
| batJoro | 8:b3738229ba85 | 3 | |
| batJoro | 11:0e6a221ad8a9 | 4 | Engine::Engine(){ |
| batJoro | 8:b3738229ba85 | 5 | |
| batJoro | 8:b3738229ba85 | 6 | } |
| batJoro | 8:b3738229ba85 | 7 | |
| batJoro | 8:b3738229ba85 | 8 | Engine::~Engine(){ |
| batJoro | 8:b3738229ba85 | 9 | |
| batJoro | 8:b3738229ba85 | 10 | } |
| batJoro | 8:b3738229ba85 | 11 | |
| batJoro | 8:b3738229ba85 | 12 | void Engine::init(int screenHeight, int screenWidth, int speed){ |
| batJoro | 8:b3738229ba85 | 13 | |
| batJoro | 8:b3738229ba85 | 14 | _screen_height = screenHeight; |
| batJoro | 9:dc13042b09f5 | 15 | _screen_width = screenWidth; |
| batJoro | 10:b939edd9b87c | 16 | |
| batJoro | 11:0e6a221ad8a9 | 17 | // set the car parameters to 0.0f |
| batJoro | 10:b939edd9b87c | 18 | car.set_speed(0.0f); |
| batJoro | 10:b939edd9b87c | 19 | car.set_car_position(0.0f); |
| batJoro | 10:b939edd9b87c | 20 | car.set_car_distance(0.0f); |
| batJoro | 11:0e6a221ad8a9 | 21 | car.set_gear(); // this one starts from 1 |
| batJoro | 10:b939edd9b87c | 22 | |
| batJoro | 11:0e6a221ad8a9 | 23 | // road curvature is 0.0 i.e it is in the middle (straight line) |
| batJoro | 9:dc13042b09f5 | 24 | _curvature = 0.0f; |
| batJoro | 9:dc13042b09f5 | 25 | |
| batJoro | 11:0e6a221ad8a9 | 26 | // set map fields to 0.0 as well |
| batJoro | 10:b939edd9b87c | 27 | map.set_player_curvature(0.0f); |
| batJoro | 10:b939edd9b87c | 28 | map.set_timed_curvature(0.0f); |
| batJoro | 9:dc13042b09f5 | 29 | |
| batJoro | 11:0e6a221ad8a9 | 30 | // some variables to keep details of the current map and time |
| batJoro | 10:b939edd9b87c | 31 | _track_distance = 0.0f; |
| batJoro | 10:b939edd9b87c | 32 | _lap_time = 0.0f; |
| batJoro | 9:dc13042b09f5 | 33 | |
| batJoro | 11:0e6a221ad8a9 | 34 | |
| batJoro | 11:0e6a221ad8a9 | 35 | // design a map |
| batJoro | 10:b939edd9b87c | 36 | addSegment(0.0f, 500.0f); |
| batJoro | 10:b939edd9b87c | 37 | addSegment(-1.0f, 600.0f); |
| batJoro | 10:b939edd9b87c | 38 | addSegment(1.0f, 600.0f); |
| batJoro | 10:b939edd9b87c | 39 | addSegment(-1.0f, 600.0f); |
| batJoro | 10:b939edd9b87c | 40 | addSegment(-1.0f, 600.0f); |
| batJoro | 12:bc9a43f56261 | 41 | addSegment(1.0f, 140.0f); |
| batJoro | 12:bc9a43f56261 | 42 | addSegment(-1.0f, 150.0f); |
| batJoro | 10:b939edd9b87c | 43 | addSegment(1.0f, 600.0f); |
| batJoro | 10:b939edd9b87c | 44 | addSegment(-1.0f, 600.0f); |
| batJoro | 12:bc9a43f56261 | 45 | addSegment(1.0f, 200.0f); |
| batJoro | 12:bc9a43f56261 | 46 | addSegment(-1.0f, 600.0f); |
| batJoro | 12:bc9a43f56261 | 47 | addSegment(0.0f, 500.0f); |
| batJoro | 10:b939edd9b87c | 48 | addSegment(-1.0f, 600.0f); |
| batJoro | 12:bc9a43f56261 | 49 | addSegment(1.0f, 200.0f); |
| batJoro | 12:bc9a43f56261 | 50 | addSegment(1.0f, 140.0f); |
| batJoro | 12:bc9a43f56261 | 51 | addSegment(-1.0f, 50.0f); |
| batJoro | 12:bc9a43f56261 | 52 | addSegment(1.0f, 140.0f); |
| batJoro | 12:bc9a43f56261 | 53 | addSegment(-1.0f, 150.0f); |
| batJoro | 10:b939edd9b87c | 54 | addSegment(0.0f, 700.0f); |
| batJoro | 9:dc13042b09f5 | 55 | |
| batJoro | 11:0e6a221ad8a9 | 56 | // find how long is the track |
| batJoro | 10:b939edd9b87c | 57 | calc_track_distance(); |
| batJoro | 10:b939edd9b87c | 58 | |
| batJoro | 8:b3738229ba85 | 59 | } |
| batJoro | 8:b3738229ba85 | 60 | |
| batJoro | 8:b3738229ba85 | 61 | |
| batJoro | 9:dc13042b09f5 | 62 | void Engine::update(Gamepad &pad, N5110 &lcd, float elapsedTime) { |
| batJoro | 8:b3738229ba85 | 63 | |
| batJoro | 11:0e6a221ad8a9 | 64 | // split the curvature do it appears slowly |
| batJoro | 10:b939edd9b87c | 65 | if(fabs(map.get_player_curvature() - map.get_timed_curvature()) >= 0.5f) { |
| batJoro | 10:b939edd9b87c | 66 | |
| batJoro | 10:b939edd9b87c | 67 | car.set_speed(car.get_speed() - 5.0f * elapsedTime); |
| batJoro | 9:dc13042b09f5 | 68 | } |
| batJoro | 9:dc13042b09f5 | 69 | |
| batJoro | 9:dc13042b09f5 | 70 | |
| batJoro | 10:b939edd9b87c | 71 | // how the car perceives the track |
| batJoro | 10:b939edd9b87c | 72 | car.set_car_distance(car.get_car_distance() + |
| batJoro | 10:b939edd9b87c | 73 | (car.get_speed() * 300.0f) * elapsedTime * car.get_rev()); |
| batJoro | 9:dc13042b09f5 | 74 | |
| batJoro | 9:dc13042b09f5 | 75 | // get point on track |
| batJoro | 9:dc13042b09f5 | 76 | float foffset = 0; |
| batJoro | 9:dc13042b09f5 | 77 | int ntrackSection = 0; |
| batJoro | 9:dc13042b09f5 | 78 | |
| batJoro | 11:0e6a221ad8a9 | 79 | // add the time to the overall time |
| batJoro | 10:b939edd9b87c | 80 | _lap_time += elapsedTime; |
| batJoro | 10:b939edd9b87c | 81 | |
| batJoro | 10:b939edd9b87c | 82 | // restart the car distance |
| batJoro | 10:b939edd9b87c | 83 | if ( car.get_car_distance() >= _track_distance) { |
| batJoro | 10:b939edd9b87c | 84 | car.set_car_distance(car.get_car_distance() - _track_distance); |
| batJoro | 10:b939edd9b87c | 85 | _lap = 1; |
| batJoro | 10:b939edd9b87c | 86 | } |
| batJoro | 10:b939edd9b87c | 87 | |
| batJoro | 9:dc13042b09f5 | 88 | // find position on track |
| batJoro | 10:b939edd9b87c | 89 | while( ntrackSection < track.size() && foffset < car.get_car_distance()){ |
| batJoro | 9:dc13042b09f5 | 90 | |
| batJoro | 9:dc13042b09f5 | 91 | foffset += track[ntrackSection].meters; |
| batJoro | 9:dc13042b09f5 | 92 | ntrackSection++; |
| batJoro | 9:dc13042b09f5 | 93 | } |
| batJoro | 9:dc13042b09f5 | 94 | |
| batJoro | 10:b939edd9b87c | 95 | // the curvature of the segment we are in |
| batJoro | 9:dc13042b09f5 | 96 | float targetCurvature = track[ntrackSection -1].curvature; |
| batJoro | 9:dc13042b09f5 | 97 | |
| batJoro | 11:0e6a221ad8a9 | 98 | // small curvature to be displayed but this time based on speed as well |
| batJoro | 10:b939edd9b87c | 99 | float curvDiff = (targetCurvature - _curvature) * elapsedTime * car.get_speed(); |
| batJoro | 11:0e6a221ad8a9 | 100 | // slowly changing curvature |
| batJoro | 9:dc13042b09f5 | 101 | _curvature += curvDiff; |
| batJoro | 10:b939edd9b87c | 102 | |
| batJoro | 10:b939edd9b87c | 103 | // the best curvature we should aim for |
| batJoro | 11:0e6a221ad8a9 | 104 | // other wise the car gets slowed down |
| batJoro | 10:b939edd9b87c | 105 | map.set_timed_curvature( (_curvature) * elapsedTime * car.get_speed() ); |
| batJoro | 9:dc13042b09f5 | 106 | |
| batJoro | 10:b939edd9b87c | 107 | |
| batJoro | 10:b939edd9b87c | 108 | // draw car |
| batJoro | 10:b939edd9b87c | 109 | car.set_car_position(map.get_player_curvature() - map.get_timed_curvature()); |
| batJoro | 11:0e6a221ad8a9 | 110 | |
| batJoro | 10:b939edd9b87c | 111 | } |
| batJoro | 10:b939edd9b87c | 112 | |
| batJoro | 10:b939edd9b87c | 113 | void Engine::read_input(Gamepad &pad, float elapsedTime) { |
| batJoro | 10:b939edd9b87c | 114 | |
| batJoro | 10:b939edd9b87c | 115 | float _mag; |
| batJoro | 10:b939edd9b87c | 116 | _mag = pad.get_mag(); |
| batJoro | 10:b939edd9b87c | 117 | |
| batJoro | 11:0e6a221ad8a9 | 118 | // car moving to the front |
| batJoro | 10:b939edd9b87c | 119 | if(pad.get_direction() == N) { |
| batJoro | 10:b939edd9b87c | 120 | car.set_speed(car.get_speed() + 0.5f * elapsedTime * _mag); |
| batJoro | 10:b939edd9b87c | 121 | car.set_direction(0); // |
| batJoro | 10:b939edd9b87c | 122 | } |
| batJoro | 10:b939edd9b87c | 123 | else { |
| batJoro | 10:b939edd9b87c | 124 | car.set_speed(car.get_speed() - 1.8f * elapsedTime); |
| batJoro | 10:b939edd9b87c | 125 | } |
| batJoro | 8:b3738229ba85 | 126 | |
| batJoro | 11:0e6a221ad8a9 | 127 | // car brake |
| batJoro | 10:b939edd9b87c | 128 | if(pad.get_direction() == S) { |
| batJoro | 10:b939edd9b87c | 129 | car.set_speed(car.get_speed() - 5.0f * elapsedTime * _mag); |
| batJoro | 10:b939edd9b87c | 130 | car.set_direction(0); // |
| batJoro | 10:b939edd9b87c | 131 | } |
| batJoro | 11:0e6a221ad8a9 | 132 | |
| batJoro | 11:0e6a221ad8a9 | 133 | // car moving to the diagonally |
| batJoro | 10:b939edd9b87c | 134 | if(pad.get_direction() == W || pad.get_direction() == NW) { |
| batJoro | 10:b939edd9b87c | 135 | if(pad.get_direction() == NW) { |
| batJoro | 10:b939edd9b87c | 136 | map.set_player_curvature(map.get_player_curvature() - 0.7f * elapsedTime); |
| batJoro | 10:b939edd9b87c | 137 | car.set_speed(car.get_speed() + 4.5f * elapsedTime * _mag); |
| batJoro | 10:b939edd9b87c | 138 | } |
| batJoro | 10:b939edd9b87c | 139 | else |
| batJoro | 10:b939edd9b87c | 140 | map.set_player_curvature(map.get_player_curvature() - 1.4f * elapsedTime); |
| batJoro | 10:b939edd9b87c | 141 | car.set_direction(1); |
| batJoro | 10:b939edd9b87c | 142 | |
| batJoro | 10:b939edd9b87c | 143 | } |
| batJoro | 11:0e6a221ad8a9 | 144 | // car moving to the diagonally |
| batJoro | 10:b939edd9b87c | 145 | if(pad.get_direction() == E || pad.get_direction() == NE) { |
| batJoro | 10:b939edd9b87c | 146 | if(pad.get_direction() == NE) { |
| batJoro | 10:b939edd9b87c | 147 | map.set_player_curvature(map.get_player_curvature() + 0.7f * elapsedTime); |
| batJoro | 10:b939edd9b87c | 148 | car.set_speed(car.get_speed() + 4.5f * elapsedTime * _mag); |
| batJoro | 10:b939edd9b87c | 149 | } |
| batJoro | 10:b939edd9b87c | 150 | else |
| batJoro | 10:b939edd9b87c | 151 | map.set_player_curvature(map.get_player_curvature() + 1.4f * elapsedTime); |
| batJoro | 10:b939edd9b87c | 152 | car.set_direction(2); |
| batJoro | 10:b939edd9b87c | 153 | } |
| batJoro | 11:0e6a221ad8a9 | 154 | |
| batJoro | 11:0e6a221ad8a9 | 155 | // change gears |
| batJoro | 10:b939edd9b87c | 156 | if(pad.check_event(Gamepad::Y_PRESSED)) { |
| batJoro | 10:b939edd9b87c | 157 | car.upShift(); |
| batJoro | 10:b939edd9b87c | 158 | } |
| batJoro | 10:b939edd9b87c | 159 | if(pad.check_event(Gamepad::X_PRESSED)) { |
| batJoro | 10:b939edd9b87c | 160 | car.downShift(); |
| batJoro | 10:b939edd9b87c | 161 | } |
| batJoro | 10:b939edd9b87c | 162 | } |
| batJoro | 10:b939edd9b87c | 163 | |
| batJoro | 11:0e6a221ad8a9 | 164 | // draw the road and the sides we only need half the screen |
| batJoro | 10:b939edd9b87c | 165 | void Engine::draw(N5110 &lcd) { |
| batJoro | 10:b939edd9b87c | 166 | |
| batJoro | 10:b939edd9b87c | 167 | for (int y = 0; y < _screen_height / 2; y++) { |
| batJoro | 9:dc13042b09f5 | 168 | |
| batJoro | 9:dc13042b09f5 | 169 | float fPerspective = (float)y / (_screen_height / 2.0f); |
| batJoro | 9:dc13042b09f5 | 170 | |
| batJoro | 8:b3738229ba85 | 171 | for (int x = 0; x < _screen_width; x++) { |
| batJoro | 8:b3738229ba85 | 172 | |
| batJoro | 9:dc13042b09f5 | 173 | float fPointCentre = 0.5f + _curvature * powf((1.0f - fPerspective), 3); |
| batJoro | 9:dc13042b09f5 | 174 | float fRoadSpace = 0.1f + fPerspective * 0.8f; |
| batJoro | 8:b3738229ba85 | 175 | float fSideSpace = fRoadSpace * 0.15f; |
| batJoro | 8:b3738229ba85 | 176 | |
| batJoro | 10:b939edd9b87c | 177 | // for easier calculating the sides spliting the road space in two |
| batJoro | 8:b3738229ba85 | 178 | fRoadSpace *= 0.5f; |
| batJoro | 8:b3738229ba85 | 179 | |
| batJoro | 8:b3738229ba85 | 180 | int leftGrass = (fPointCentre - fRoadSpace - fSideSpace) * _screen_width; |
| batJoro | 8:b3738229ba85 | 181 | int leftSide = (fPointCentre - fRoadSpace) * _screen_width; |
| batJoro | 8:b3738229ba85 | 182 | int rightGrass = (fPointCentre + fRoadSpace + fSideSpace) * _screen_width; |
| batJoro | 8:b3738229ba85 | 183 | int rightSide = (fPointCentre + fRoadSpace) * _screen_width; |
| batJoro | 8:b3738229ba85 | 184 | |
| batJoro | 8:b3738229ba85 | 185 | int row = _screen_height / 2 + y; |
| batJoro | 8:b3738229ba85 | 186 | |
| batJoro | 10:b939edd9b87c | 187 | float GrassColour = defineStripes(lcd, car, 20.0f, fPerspective); |
| batJoro | 10:b939edd9b87c | 188 | float SideColour = defineStripes(lcd, car, 40.0f, fPerspective); |
| batJoro | 9:dc13042b09f5 | 189 | |
| batJoro | 10:b939edd9b87c | 190 | assignPixel(lcd, x, y, row, SideColour, GrassColour, leftGrass, rightGrass, |
| batJoro | 10:b939edd9b87c | 191 | leftSide, |
| batJoro | 10:b939edd9b87c | 192 | rightSide); |
| batJoro | 10:b939edd9b87c | 193 | } |
| batJoro | 11:0e6a221ad8a9 | 194 | car.draw(lcd, 84); |
| batJoro | 11:0e6a221ad8a9 | 195 | drawFrame(lcd); // draw the frame around the picture |
| batJoro | 11:0e6a221ad8a9 | 196 | |
| batJoro | 10:b939edd9b87c | 197 | } |
| batJoro | 10:b939edd9b87c | 198 | } |
| batJoro | 11:0e6a221ad8a9 | 199 | // colour the pixel accoring to the give boundaries |
| batJoro | 10:b939edd9b87c | 200 | void Engine::assignPixel(N5110 &lcd,int x, int y, int row, float SideColour, float GrassColour, |
| batJoro | 10:b939edd9b87c | 201 | int leftGrass, |
| batJoro | 10:b939edd9b87c | 202 | int rightGrass, |
| batJoro | 10:b939edd9b87c | 203 | int leftSide, |
| batJoro | 10:b939edd9b87c | 204 | int rightSide) { |
| batJoro | 8:b3738229ba85 | 205 | if ( x >= 0 && x < leftGrass) { |
| batJoro | 9:dc13042b09f5 | 206 | if ( GrassColour == 0.0f ) |
| batJoro | 8:b3738229ba85 | 207 | lcd.setPixel(x, row, true); |
| batJoro | 8:b3738229ba85 | 208 | } |
| batJoro | 8:b3738229ba85 | 209 | if ( x >= leftGrass && x < leftSide) { |
| batJoro | 9:dc13042b09f5 | 210 | if ( x % 2 ==0) |
| batJoro | 9:dc13042b09f5 | 211 | if ( SideColour == 0.0f ) |
| batJoro | 9:dc13042b09f5 | 212 | lcd.setPixel(x, row, true); |
| batJoro | 8:b3738229ba85 | 213 | } |
| batJoro | 8:b3738229ba85 | 214 | if ( x >= rightSide && x < rightGrass ) { |
| batJoro | 9:dc13042b09f5 | 215 | if ( x % 2 ==0) |
| batJoro | 9:dc13042b09f5 | 216 | if ( SideColour == 0.0f ) |
| batJoro | 9:dc13042b09f5 | 217 | lcd.setPixel(x, row, true); |
| batJoro | 8:b3738229ba85 | 218 | } |
| batJoro | 8:b3738229ba85 | 219 | if ( x >= rightGrass && x < _screen_width) { |
| batJoro | 9:dc13042b09f5 | 220 | if ( GrassColour == 0.0f ) |
| batJoro | 8:b3738229ba85 | 221 | lcd.setPixel(x, row, true); |
| batJoro | 10:b939edd9b87c | 222 | } |
| batJoro | 10:b939edd9b87c | 223 | } |
| batJoro | 10:b939edd9b87c | 224 | |
| batJoro | 11:0e6a221ad8a9 | 225 | // use sin function to 'paint' the grass |
| batJoro | 10:b939edd9b87c | 226 | float Engine::defineStripes(N5110 &lcd, Car &car, float frequency, float perspective) { |
| batJoro | 9:dc13042b09f5 | 227 | |
| batJoro | 10:b939edd9b87c | 228 | float colour = sinf(frequency * powf(1.0f - perspective, 3) + car.get_car_distance() * 0.1f); |
| batJoro | 10:b939edd9b87c | 229 | |
| batJoro | 10:b939edd9b87c | 230 | if (colour > 0.0f) colour = 1.0f; |
| batJoro | 10:b939edd9b87c | 231 | else colour = 0.0f; |
| batJoro | 10:b939edd9b87c | 232 | |
| batJoro | 10:b939edd9b87c | 233 | return colour; |
| batJoro | 8:b3738229ba85 | 234 | } |
| batJoro | 11:0e6a221ad8a9 | 235 | // add segment to the map |
| batJoro | 10:b939edd9b87c | 236 | void Engine::addSegment(float curvature, float meters) { |
| batJoro | 10:b939edd9b87c | 237 | |
| batJoro | 10:b939edd9b87c | 238 | // clap the curvature variable |
| batJoro | 10:b939edd9b87c | 239 | if(curvature < -1.0f) curvature = -1.0f; |
| batJoro | 10:b939edd9b87c | 240 | if(curvature > 1.0f) curvature = 1.0f; |
| batJoro | 11:0e6a221ad8a9 | 241 | // place a segment on the map |
| batJoro | 10:b939edd9b87c | 242 | MapSegment segment; |
| batJoro | 10:b939edd9b87c | 243 | segment.curvature = curvature; |
| batJoro | 10:b939edd9b87c | 244 | segment.meters = meters; |
| batJoro | 10:b939edd9b87c | 245 | track.push_back(segment); |
| batJoro | 10:b939edd9b87c | 246 | } |
| batJoro | 10:b939edd9b87c | 247 | |
| batJoro | 11:0e6a221ad8a9 | 248 | // go throught the map and add distance |
| batJoro | 10:b939edd9b87c | 249 | void Engine::calc_track_distance() { |
| batJoro | 8:b3738229ba85 | 250 | |
| batJoro | 10:b939edd9b87c | 251 | for (vector<MapSegment>::iterator it = track.begin(); it != track.end(); ++it) { |
| batJoro | 10:b939edd9b87c | 252 | _track_distance += it->meters; |
| batJoro | 10:b939edd9b87c | 253 | } |
| batJoro | 10:b939edd9b87c | 254 | } |
| batJoro | 10:b939edd9b87c | 255 | |
| batJoro | 10:b939edd9b87c | 256 | int Engine::get_lap() { |
| batJoro | 10:b939edd9b87c | 257 | |
| batJoro | 10:b939edd9b87c | 258 | return _lap; |
| batJoro | 10:b939edd9b87c | 259 | } |
| batJoro | 8:b3738229ba85 | 260 | |
| batJoro | 10:b939edd9b87c | 261 | float Engine::get_lap_time() { |
| batJoro | 10:b939edd9b87c | 262 | |
| batJoro | 10:b939edd9b87c | 263 | return _lap_time; |
| batJoro | 10:b939edd9b87c | 264 | } |
| batJoro | 10:b939edd9b87c | 265 |