ELEC2645 (2018/19) / Mbed 2 deprecated el17dtt

Dependencies:   mbed

Committer:
batJoro
Date:
Fri May 10 13:58:51 2019 +0000
Revision:
11:0e6a221ad8a9
Parent:
10:b939edd9b87c
Child:
12:bc9a43f56261
final 2;

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