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
- Committer:
- batJoro
- Date:
- 2019-05-10
- Revision:
- 10:b939edd9b87c
- Parent:
- 9:dc13042b09f5
- Child:
- 11:0e6a221ad8a9
File content as of revision 10:b939edd9b87c:
#include "engine.h"
Engine::Engine(){
}
Engine::~Engine(){
}
void Engine::init(int screenHeight, int screenWidth, int speed){
_screen_height = screenHeight;
_screen_width = screenWidth;
car.set_speed(0.0f);
car.set_car_position(0.0f);
car.set_car_distance(0.0f);
car.set_gear();
_curvature = 0.0f;
map.set_player_curvature(0.0f);
map.set_timed_curvature(0.0f);
_track_distance = 0.0f;
_lap_time = 0.0f;
addSegment(0.0f, 500.0f);
addSegment(-1.0f, 600.0f);
addSegment(1.0f, 600.0f);
addSegment(-1.0f, 600.0f);
addSegment(-1.0f, 600.0f);
addSegment(1.0f, 600.0f);
addSegment(-1.0f, 600.0f);
addSegment(1.0f, 600.0f);
addSegment(-1.0f, 600.0f);
addSegment(0.0f, 700.0f);
calc_track_distance();
}
void Engine::update(Gamepad &pad, N5110 &lcd, float elapsedTime) {
clearScreen(lcd);
drawFrame(lcd); // draw the frame around the picture
if(fabs(map.get_player_curvature() - map.get_timed_curvature()) >= 0.5f) {
car.set_speed(car.get_speed() - 5.0f * elapsedTime);
}
// how the car perceives the track
car.set_car_distance(car.get_car_distance() +
(car.get_speed() * 300.0f) * elapsedTime * car.get_rev());
// get point on track
float foffset = 0;
int ntrackSection = 0;
_lap_time += elapsedTime;
// restart the car distance
if ( car.get_car_distance() >= _track_distance) {
car.set_car_distance(car.get_car_distance() - _track_distance);
_lap = 1;
}
// find position on track
while( ntrackSection < track.size() && foffset < car.get_car_distance()){
foffset += track[ntrackSection].meters;
ntrackSection++;
}
// the curvature of the segment we are in
float targetCurvature = track[ntrackSection -1].curvature;
// small curvature to be displayed
float curvDiff = (targetCurvature - _curvature) * elapsedTime * car.get_speed();
// slowly changing curvature
_curvature += curvDiff;
// the best curvature we should aim for
map.set_timed_curvature( (_curvature) * elapsedTime * car.get_speed() );
draw(lcd); // change the pixels of the buffer;
// draw car
car.set_car_position(map.get_player_curvature() - map.get_timed_curvature());
car.draw(lcd, _screen_width);
lcd.refresh();
}
void Engine::read_input(Gamepad &pad, float elapsedTime) {
float _mag;
_mag = pad.get_mag();
if(pad.get_direction() == N) {
car.set_speed(car.get_speed() + 0.5f * elapsedTime * _mag);
car.set_direction(0); //
}
else {
car.set_speed(car.get_speed() - 1.8f * elapsedTime);
}
if(pad.get_direction() == S) {
car.set_speed(car.get_speed() - 5.0f * elapsedTime * _mag);
car.set_direction(0); //
}
if(pad.get_direction() == W || pad.get_direction() == NW) {
if(pad.get_direction() == NW) {
map.set_player_curvature(map.get_player_curvature() - 0.7f * elapsedTime);
car.set_speed(car.get_speed() + 4.5f * elapsedTime * _mag);
}
else
map.set_player_curvature(map.get_player_curvature() - 1.4f * elapsedTime);
car.set_direction(1);
}
if(pad.get_direction() == E || pad.get_direction() == NE) {
if(pad.get_direction() == NE) {
map.set_player_curvature(map.get_player_curvature() + 0.7f * elapsedTime);
car.set_speed(car.get_speed() + 4.5f * elapsedTime * _mag);
}
else
map.set_player_curvature(map.get_player_curvature() + 1.4f * elapsedTime);
car.set_direction(2);
}
if(pad.check_event(Gamepad::Y_PRESSED)) {
car.upShift();
}
if(pad.check_event(Gamepad::X_PRESSED)) {
car.downShift();
}
}
void Engine::draw(N5110 &lcd) {
for (int y = 0; y < _screen_height / 2; y++) {
float fPerspective = (float)y / (_screen_height / 2.0f);
for (int x = 0; x < _screen_width; x++) {
float fPointCentre = 0.5f + _curvature * powf((1.0f - fPerspective), 3);
float fRoadSpace = 0.1f + fPerspective * 0.8f;
float fSideSpace = fRoadSpace * 0.15f;
// for easier calculating the sides spliting the road space in two
fRoadSpace *= 0.5f;
int leftGrass = (fPointCentre - fRoadSpace - fSideSpace) * _screen_width;
int leftSide = (fPointCentre - fRoadSpace) * _screen_width;
int rightGrass = (fPointCentre + fRoadSpace + fSideSpace) * _screen_width;
int rightSide = (fPointCentre + fRoadSpace) * _screen_width;
int row = _screen_height / 2 + y;
float GrassColour = defineStripes(lcd, car, 20.0f, fPerspective);
float SideColour = defineStripes(lcd, car, 40.0f, fPerspective);
assignPixel(lcd, x, y, row, SideColour, GrassColour, leftGrass, rightGrass,
leftSide,
rightSide);
}
}
}
void Engine::assignPixel(N5110 &lcd,int x, int y, int row, float SideColour, float GrassColour,
int leftGrass,
int rightGrass,
int leftSide,
int rightSide) {
if ( x >= 0 && x < leftGrass) {
if ( GrassColour == 0.0f )
lcd.setPixel(x, row, true);
}
if ( x >= leftGrass && x < leftSide) {
if ( x % 2 ==0)
if ( SideColour == 0.0f )
lcd.setPixel(x, row, true);
}
if ( x >= rightSide && x < rightGrass ) {
if ( x % 2 ==0)
if ( SideColour == 0.0f )
lcd.setPixel(x, row, true);
}
if ( x >= rightGrass && x < _screen_width) {
if ( GrassColour == 0.0f )
lcd.setPixel(x, row, true);
}
}
float Engine::defineStripes(N5110 &lcd, Car &car, float frequency, float perspective) {
float colour = sinf(frequency * powf(1.0f - perspective, 3) + car.get_car_distance() * 0.1f);
if (colour > 0.0f) colour = 1.0f;
else colour = 0.0f;
return colour;
}
void Engine::addSegment(float curvature, float meters) {
// clap the curvature variable
if(curvature < -1.0f) curvature = -1.0f;
if(curvature > 1.0f) curvature = 1.0f;
MapSegment segment;
segment.curvature = curvature;
segment.meters = meters;
track.push_back(segment);
}
void Engine::calc_track_distance() {
for (vector<MapSegment>::iterator it = track.begin(); it != track.end(); ++it) {
_track_distance += it->meters;
}
}
int Engine::get_lap() {
return _lap;
}
float Engine::get_lap_time() {
return _lap_time;
}