ELEC2645 (2018/19) / Mbed 2 deprecated el17dtt

Dependencies:   mbed

Committer:
batJoro
Date:
Fri May 10 14:38:36 2019 +0000
Revision:
12:bc9a43f56261
Parent:
11:0e6a221ad8a9
final3

Who changed what in which revision?

UserRevisionLine numberNew 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