|
|
@ -9,6 +9,8 @@ |
|
|
|
#define OLC_PGE_APPLICATION |
|
|
|
#define OLC_PGE_APPLICATION |
|
|
|
#include "pixelGameEngine.h" // used for drawing the game |
|
|
|
#include "pixelGameEngine.h" // used for drawing the game |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
using namespace olc; |
|
|
|
|
|
|
|
|
|
|
|
//========================================================================================================================================
|
|
|
|
//========================================================================================================================================
|
|
|
|
// protected variables
|
|
|
|
// protected variables
|
|
|
|
//========================================================================================================================================
|
|
|
|
//========================================================================================================================================
|
|
|
@ -691,524 +693,21 @@ public: |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
//========================================================================================================================================
|
|
|
|
void DrawCenteredStringDecal(olc::vf2d pos,std::string str,olc::Pixel col=olc::WHITE,olc::vf2d scale={1,1}) { |
|
|
|
// Main Game Function
|
|
|
|
olc::vf2d textOffset = olc::vf2d(GetTextSize(str))*scale/2; |
|
|
|
//========================================================================================================================================
|
|
|
|
DrawStringDecal(pos-textOffset,str,col,scale); |
|
|
|
bool OnUserUpdate(float fElapsedTime) override |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if (GetKey(olc::Key::CTRL).bHeld && GetKey(olc::Key::F12).bHeld && !bothKeysPressed) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// draw skybox
|
|
|
|
|
|
|
|
GradientFillRectDecal({ 0.0f, 0.0f }, { ScreenWidth() + 0.0f, ScreenHeight() / 2 + 0.0f }, olc::DARK_BLUE, olc::BLUE, olc::BLUE, olc::DARK_BLUE); |
|
|
|
|
|
|
|
// the hills have eyes; y'know, like in Super Mario Bros. What reference did you think was going to be here?
|
|
|
|
|
|
|
|
DrawPartialDecal({ 0.0f, ScreenHeight() / 2 - 100.0f }, hill, { 0.0f + track_curve * 200, 0.0f }, { ScreenWidth() + 0.0f, (float)hill->sprite->height }, { 1.5f, 1.0f }); |
|
|
|
|
|
|
|
//DrawPartialDecal({ 180.0f, ScreenHeight() / 2 - 100.0f }, hill, { 0.0f + track_curve * 200, 0.0f }, { ScreenWidth() + 0.0f, (float)hill->sprite->height });
|
|
|
|
|
|
|
|
DrawPartialWarpedDecal // draw grass
|
|
|
|
|
|
|
|
( |
|
|
|
|
|
|
|
grass, { { 0.0f, ScreenHeight() / 2 + 0.0f }, |
|
|
|
|
|
|
|
{ -ScreenWidth() * 2 + 0.0f, ScreenHeight() + 0.0f}, |
|
|
|
|
|
|
|
{ ScreenWidth() * 2 + ScreenWidth() + 0.0f, ScreenHeight() + 0.0f }, |
|
|
|
|
|
|
|
{ ScreenWidth() + 0.0f, ScreenHeight() / 2 + 0.0f } }, |
|
|
|
|
|
|
|
{ 0.0f, -distance }, { 1 * 32, 4 * 64 } |
|
|
|
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//========================================================================================================================================
|
|
|
|
|
|
|
|
if (gameState == state::MAIN_MENU) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
FillRectDecal({ 0, 0 }, { ScreenWidth() + 0.f, ScreenHeight() + 0.f }, olc::Pixel(0, 0, 0, 16)); |
|
|
|
|
|
|
|
// display title
|
|
|
|
|
|
|
|
DrawDecal({ 95.5f, 95.5f }, title/*, {0.4f, 0.4f}*/); |
|
|
|
|
|
|
|
DisplayMenu(mainMenu); |
|
|
|
|
|
|
|
//DrawStringDecal({ ScreenWidth() / 2 + 0.0f, ScreenHeight() / 2 + 0.0f }, "START GAME", olc::WHITE, { 4.0f, 4.0f });
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (GetKey(olc::Key::ENTER).bPressed || GetKey(olc::Key::SPACE).bPressed) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
// vertical menu
|
|
|
|
|
|
|
|
if (highlighted == 0) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
gameState = state::PLAY_GAME; |
|
|
|
|
|
|
|
highlighted = 0; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else if (highlighted == 1) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
gameState = state::CONTROLS; |
|
|
|
|
|
|
|
highlighted = 0; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
return false; // quit game
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (GetKey(olc::Key::ESCAPE).bPressed) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
return false; // exit via Escape key
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
//========================================================================================================================================
|
|
|
|
//========================================================================================================================================
|
|
|
|
else if (gameState == state::PLAY_GAME) |
|
|
|
// Main Game Function
|
|
|
|
{ |
|
|
|
|
|
|
|
FillRectDecal({ 0, 0 }, { ScreenWidth() + 0.f, ScreenHeight() + 0.f }, olc::Pixel(0, 0, 0, 16)); |
|
|
|
|
|
|
|
DisplayMenu(playGame); |
|
|
|
|
|
|
|
if (GetKey(olc::Key::ENTER).bPressed || GetKey(olc::Key::SPACE).bPressed) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
// vertical menu
|
|
|
|
|
|
|
|
if (highlighted == 0) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
gameState = state::TRACK_SELECT; |
|
|
|
|
|
|
|
highlighted = 0; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else if (highlighted == 1) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
gameState = state::CUP_SELECT; |
|
|
|
|
|
|
|
highlighted = 0; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
gameState = state::MAIN_MENU; // return to menu
|
|
|
|
|
|
|
|
highlighted = 0; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (GetKey(olc::Key::ESCAPE).bPressed || GetKey(olc::Key::BACK).bPressed) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
gameState = state::MAIN_MENU; |
|
|
|
|
|
|
|
highlighted = 0; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//========================================================================================================================================
|
|
|
|
|
|
|
|
else if (gameState == state::TRACK_SELECT) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
FillRectDecal({ 0, 0 }, { ScreenWidth() + 0.f, ScreenHeight() + 0.f }, olc::Pixel(0, 0, 0, 16)); |
|
|
|
|
|
|
|
DisplayMenu(pickTrack); |
|
|
|
|
|
|
|
if (GetKey(olc::Key::ENTER).bPressed || GetKey(olc::Key::SPACE).bPressed) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if (highlighted >= 0 && highlighted <= 8) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
track = highlighted + 1; |
|
|
|
|
|
|
|
gameState = state::CAR_SELECT; |
|
|
|
|
|
|
|
highlighted = 0; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
gameState = state::PLAY_GAME; |
|
|
|
|
|
|
|
highlighted = 0; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (GetKey(olc::Key::CTRL).bHeld && GetKey(olc::Key::F9).bHeld) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
// okay, so, gotta work out how to do cheat codes it seems xD
|
|
|
|
|
|
|
|
track = 0; |
|
|
|
|
|
|
|
gameState = state::CAR_SELECT; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (GetKey(olc::Key::ESCAPE).bPressed || GetKey(olc::Key::BACK).bPressed) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
gameState = state::PLAY_GAME; |
|
|
|
|
|
|
|
highlighted = 0; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//========================================================================================================================================
|
|
|
|
|
|
|
|
else if (gameState == state::CUP_SELECT) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
FillRectDecal({ 0, 0 }, { ScreenWidth() + 0.f, ScreenHeight() + 0.f}, olc::Pixel(0, 0, 0, 16)); |
|
|
|
|
|
|
|
DrawPartialDecal({ ScreenWidth() / 3 - 96.f, ScreenHeight() / 3 - 192.f }, cups, { 0, 0 }, { 64, 64 }, { 3.0f, 3.0f }, (highlighted == 0) ? olc::WHITE : olc::DARK_GREY); // bronze
|
|
|
|
|
|
|
|
DrawPartialDecal({ ScreenWidth() / 3 * 2 - 96.f, ScreenHeight() / 3 - 192.f }, cups, { 64, 0 }, { 64, 64 }, { 3.0f, 3.0f }, (highlighted == 1) ? olc::WHITE : olc::DARK_GREY); // silver
|
|
|
|
|
|
|
|
DrawPartialDecal({ ScreenWidth() / 3 - 96.f, ScreenHeight() / 3 * 2 - 192.f }, cups, { 0, 64 }, { 64, 64 }, { 3.0f, 3.0f }, (highlighted == 2) ? olc::WHITE : olc::DARK_GREY); // gold
|
|
|
|
|
|
|
|
DrawPartialDecal({ ScreenWidth() / 3 * 2 - 96.f, ScreenHeight() / 3 * 2 - 192.f }, cups, { 64, 64 }, { 64, 64 }, { 3.0f, 3.0f }, (highlighted == 3) ? olc::WHITE : olc::DARK_GREY); // platinum
|
|
|
|
|
|
|
|
DisplayMenu(grandPrix); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (GetKey(olc::Key::ENTER).bPressed || GetKey(olc::Key::SPACE).bPressed) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
// 2 x 2 menu
|
|
|
|
|
|
|
|
if (highlighted == 0) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
gameState = state::INDIE; |
|
|
|
|
|
|
|
cup = 0; |
|
|
|
|
|
|
|
gameState = state::CAR_SELECT; |
|
|
|
|
|
|
|
highlighted = 0; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else if (highlighted == 1) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
gameState = state::STREET; |
|
|
|
|
|
|
|
cup = 1; |
|
|
|
|
|
|
|
gameState = state::CAR_SELECT; |
|
|
|
|
|
|
|
highlighted = 0; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else if (highlighted == 2) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
gameState = state::PRO; |
|
|
|
|
|
|
|
cup = 2; |
|
|
|
|
|
|
|
gameState = state::CAR_SELECT; |
|
|
|
|
|
|
|
highlighted = 0; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else if (highlighted == 3) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
gameState = state::GRAND_PRIX; |
|
|
|
|
|
|
|
cup = 3; |
|
|
|
|
|
|
|
gameState = state::CAR_SELECT; |
|
|
|
|
|
|
|
highlighted = 0; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
gameState = state::PLAY_GAME; // return to menu
|
|
|
|
|
|
|
|
cup = -1; |
|
|
|
|
|
|
|
highlighted = 0; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (GetKey(olc::Key::ESCAPE).bPressed || GetKey(olc::Key::BACK).bPressed) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
gameState = state::PLAY_GAME; |
|
|
|
|
|
|
|
highlighted = 0; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//========================================================================================================================================
|
|
|
|
|
|
|
|
else if (gameState == state::CAR_SELECT) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
FillRectDecal({ 0, 0 }, { ScreenWidth() + 0.f, ScreenHeight() + 0.f }, olc::Pixel(0, 0, 0, 16)); |
|
|
|
|
|
|
|
DisplayMenu(selectCar); |
|
|
|
|
|
|
|
if (GetKey(olc::Key::ENTER).bPressed || GetKey(olc::Key::SPACE).bPressed) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if (highlighted >= 0&&highlighted <= 7) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
gameState = state::RUN_GAME; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vecTrack.clear(); |
|
|
|
|
|
|
|
for (int i = 0; i < trackList[track].size(); i++) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
vecTrack.push_back(trackList[track][i]); |
|
|
|
|
|
|
|
track_dist += vecTrack[i].second; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if (cup != -1) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
// return to cup select
|
|
|
|
|
|
|
|
gameState = state::CUP_SELECT; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (track != -1) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
// return to track select
|
|
|
|
|
|
|
|
gameState = state::TRACK_SELECT; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
highlighted = 0; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (GetKey(olc::Key::ESCAPE).bPressed || GetKey(olc::Key::BACK).bPressed) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if (cup != -1) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
// return to cup select
|
|
|
|
|
|
|
|
gameState = state::CUP_SELECT; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (track != -1) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
// return to track select
|
|
|
|
|
|
|
|
gameState = state::TRACK_SELECT; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
highlighted = 0; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//========================================================================================================================================
|
|
|
|
|
|
|
|
else if (gameState == state::CONTROLS) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
FillRectDecal({ 0, 0 }, { ScreenWidth() + 0.f, ScreenHeight() + 0.f }, olc::Pixel(0, 0, 0, 16)); |
|
|
|
|
|
|
|
DisplayMenu(controls); |
|
|
|
|
|
|
|
if (GetKey(olc::Key::ENTER).bPressed) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if (highlighted == 0) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
configKeyIndex = highlighted; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else if (highlighted == 1) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
configKeyIndex = highlighted; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else if (highlighted == 2) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
configKeyIndex = highlighted; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else if (highlighted == 3) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
configKeyIndex = highlighted; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else if (highlighted == 4) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
// reset default controls
|
|
|
|
|
|
|
|
DisplayMenu(controls); |
|
|
|
|
|
|
|
Move_Up = olc::W; |
|
|
|
|
|
|
|
Move_Down = olc::S; |
|
|
|
|
|
|
|
Move_Left = olc::A; |
|
|
|
|
|
|
|
Move_Right = olc::D; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
gameState = state::MAIN_MENU; |
|
|
|
|
|
|
|
highlighted = 0; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (GetKey(olc::Key::ESCAPE).bPressed || GetKey(olc::Key::BACK).bPressed) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
gameState = state::MAIN_MENU; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//========================================================================================================================================
|
|
|
|
|
|
|
|
else if (gameState == state::PAUSED) // pause menu
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
FillRectDecal({ 0, 0 }, { ScreenWidth() + 0.f, ScreenHeight() + 0.f }, olc::Pixel(0, 0, 0, 64)); |
|
|
|
|
|
|
|
DisplayMenu(pause); |
|
|
|
|
|
|
|
if (GetKey(olc::Key::ENTER).bPressed) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if (highlighted == 0) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
gameState = state::RUN_GAME; |
|
|
|
|
|
|
|
highlighted = 0; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (highlighted == 1) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
// restart the track
|
|
|
|
|
|
|
|
// this will ONLY work on tracks after the track selection screen
|
|
|
|
|
|
|
|
// or on the first track in each cup (1, 4, 7, 1)
|
|
|
|
|
|
|
|
Reset(); |
|
|
|
|
|
|
|
gameState = state::RUN_GAME; |
|
|
|
|
|
|
|
highlighted = 0; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (highlighted == 2) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
// main menu
|
|
|
|
|
|
|
|
Reset(); |
|
|
|
|
|
|
|
gameState = state::MAIN_MENU; |
|
|
|
|
|
|
|
highlighted = 0; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (highlighted == 3) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//========================================================================================================================================
|
|
|
|
|
|
|
|
//========================================================================================================================================
|
|
|
|
|
|
|
|
else if (gameState == state::RUN_GAME) // run main game loop
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
Clear(olc::BLACK); // this still needed? we've since replaced it with the gradient sky box
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (GetKey(olc::Key::ESCAPE).bPressed || GetKey(olc::Key::PAUSE).bPressed) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
gameState = state::PAUSED; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// debug quick-reset
|
|
|
|
|
|
|
|
if (GetKey(olc::Key::F4).bPressed) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
Reset(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// get a point on the track
|
|
|
|
|
|
|
|
float offset = 0; |
|
|
|
|
|
|
|
int TrackSection = 0; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cur_lap_time += fElapsedTime; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// record lap time
|
|
|
|
|
|
|
|
if (distance >= track_dist) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
distance -= track_dist; |
|
|
|
|
|
|
|
list_times.push_front(cur_lap_time); // push time to front
|
|
|
|
|
|
|
|
list_times.pop_back(); // pop time to back
|
|
|
|
|
|
|
|
cur_lap_time = 0.0f; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// find position on track (could optimize) << should probably optimize given the complexity of this game
|
|
|
|
|
|
|
|
while (TrackSection < vecTrack.size() && offset <= distance) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
offset += vecTrack[TrackSection].second; |
|
|
|
|
|
|
|
TrackSection++; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
float TargetCurvature = vecTrack[TrackSection - 1].first; // drawing curves to screen
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
float TrackCurveDiff = (TargetCurvature - curvature) * fElapsedTime * speed; // correcting the drawing of curves to the screen
|
|
|
|
|
|
|
|
curvature += TrackCurveDiff; // update track curve difference
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
track_curve += (curvature)*fElapsedTime * speed; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//========================================================================================================================================
|
|
|
|
|
|
|
|
// | | draw racetrack canvas
|
|
|
|
|
|
|
|
//========================================================================================================================================
|
|
|
|
|
|
|
|
std::vector<olc::vf2d> pos; |
|
|
|
|
|
|
|
std::vector<olc::vf2d> uvs; |
|
|
|
|
|
|
|
for (int y = 0; y < ScreenHeight() / 2; y++) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
// racetrack canvas variables
|
|
|
|
|
|
|
|
float perspective = (float)y / (ScreenHeight() / 2.0f); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
float mid_point = 0.5f + curvature * powf((1.0f - perspective), 3); |
|
|
|
|
|
|
|
float road_width = 0.1f + perspective * 0.8f; |
|
|
|
|
|
|
|
float curb_width = road_width * 0.15f; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
road_width *= 0.5f; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int lf_curb = (mid_point - road_width) * ScreenWidth(); |
|
|
|
|
|
|
|
int rt_curb = (mid_point + road_width) * ScreenWidth(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int row = ScreenHeight() / 2 + y; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
float horizon = powf(1.0f - perspective, 2) * 80; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// check for finish line
|
|
|
|
|
|
|
|
if (distance + horizon > track_dist - 20 && distance + horizon < track_dist) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
// draw checkerboard pattern
|
|
|
|
|
|
|
|
uvs.push_back({ 0, (float)fmod(((distance + horizon) - (track_dist - 20)) / 20.0f, 0.5f) + 0.5f }); |
|
|
|
|
|
|
|
uvs.push_back({ 1, (float)fmod(((distance + horizon) - (track_dist - 20)) / 20.0f, 0.5f) + 0.5f }); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
// draw standard track piece
|
|
|
|
|
|
|
|
uvs.push_back({ 0, sinf(80.0f * powf(1.0f - perspective, 2) + distance) / 4 + 0.25f }); |
|
|
|
|
|
|
|
uvs.push_back({ 1, sinf(80.0f * powf(1.0f - perspective, 2) + distance) / 4 + 0.25f }); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// drawing grass and curb
|
|
|
|
|
|
|
|
pos.push_back({ lf_curb + 0.0f, row + 0.0f }); |
|
|
|
|
|
|
|
pos.push_back({ rt_curb + 0.0f, row + 0.0f }); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// black box rendering shenanigans; if I ever understand programming enough at a later date, I can figure out wtf is going on here
|
|
|
|
|
|
|
|
int i = 0; |
|
|
|
|
|
|
|
for (Object& obj : gameObjects) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
float horizonRange = powf(1.0f - perspective, 2) * ((distance + horizon) - obj.pos.y) / horizon; |
|
|
|
|
|
|
|
if (!obj.rendered && (distance + horizon) > obj.pos.y && (distance + horizon) < obj.pos.y + 80 && row >= ScreenHeight() / 2 + ScreenHeight() / 2 * horizonRange) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
obj.drawPos = { (mid_point + road_width * obj.pos.x) * ScreenWidth(), horizonRange * (ScreenHeight() / 2) + ScreenHeight() / 2 }; |
|
|
|
|
|
|
|
obj.drawOffsetPos = { obj.offset.x, obj.size.y * road_width * -obj.offset.y }; |
|
|
|
|
|
|
|
obj.drawSize = { obj.size.x * road_width, obj.size.y * road_width }; |
|
|
|
|
|
|
|
obj.rendered = true; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// yeah.... so, even after copying it manually, i still have no clue what this thing is doing, lol
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// on the road again; drawing the track
|
|
|
|
|
|
|
|
SetDecalStructure(olc::DecalStructure::STRIP); |
|
|
|
|
|
|
|
DrawPolygonDecal(road, pos, uvs); |
|
|
|
|
|
|
|
SetDecalStructure(olc::DecalStructure::FAN); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// draw trackside props
|
|
|
|
|
|
|
|
for (Object& obj : gameObjects) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if (obj.rendered) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if (obj.decal != nullptr) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
DrawDecal(obj.drawPos + obj.drawOffsetPos, obj.decal, obj.drawSize); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
FillRectDecal(obj.drawPos, obj.drawSize, olc::BLUE); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//========================================================================================================================================
|
|
|
|
|
|
|
|
// | | car movement
|
|
|
|
|
|
|
|
//========================================================================================================================================
|
|
|
|
|
|
|
|
int car_dir = 0; // default car facing
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (GetKey(Move_Up).bHeld) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
speed += 2.0f * fElapsedTime; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else // might remove this in a later stage of development
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
speed -= 1.0f * fElapsedTime; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (GetKey(Move_Down).bHeld) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
// move back ?
|
|
|
|
|
|
|
|
distance -= 20.0f * fElapsedTime; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (GetKey(Move_Left).bHeld) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
car_curve -= 0.7f * fElapsedTime; |
|
|
|
|
|
|
|
car_dir = -1; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (GetKey(Move_Right).bHeld) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
car_curve += 0.7f * fElapsedTime; |
|
|
|
|
|
|
|
car_dir = +1; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// slow car if on grass
|
|
|
|
|
|
|
|
if (fabs(car_curve - track_curve) >= 0.8f) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
speed -= 5.0f * fElapsedTime; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// clamp speed
|
|
|
|
|
|
|
|
if (speed < 0.0f) speed = 0.0f; |
|
|
|
|
|
|
|
if (speed > 1.0f) speed = 1.0f; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// move car along track according to car speed
|
|
|
|
|
|
|
|
distance += (70.0f * speed) * fElapsedTime; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// draw car
|
|
|
|
|
|
|
|
car_pos = car_curve - track_curve; |
|
|
|
|
|
|
|
DrawDecal({ ScreenWidth() / 2 - 128 + car_pos * ScreenWidth() / 2, ScreenHeight() / 4 * 3.0f - 128 }, car); |
|
|
|
|
|
|
|
SetPixelMode(olc::Pixel::ALPHA); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//========================================================================================================================================
|
|
|
|
|
|
|
|
//========================================================================================================================================
|
|
|
|
//========================================================================================================================================
|
|
|
|
// spedometer
|
|
|
|
bool OnUserUpdate(float fElapsedTime) override |
|
|
|
std::string mph = std::to_string(speed); |
|
|
|
|
|
|
|
DrawString(4, 4, mph); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// show time
|
|
|
|
|
|
|
|
auto disp_time = [](float t) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
int min = t / 60.0f; |
|
|
|
|
|
|
|
int sec = t - (min * 60.0f); |
|
|
|
|
|
|
|
int milli = (t - (float)sec) * 1000.0f; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// need to change this out to a 'DrawString()' function instead
|
|
|
|
|
|
|
|
return std::to_string(min) + "." + std::to_string(sec) + ":" + std::to_string(milli); |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// correct for the first '0' in the seconds timer
|
|
|
|
|
|
|
|
//if ()
|
|
|
|
|
|
|
|
//{
|
|
|
|
|
|
|
|
// // draw min + '0' + sec + milli
|
|
|
|
|
|
|
|
// DrawString(4, 16, disp_time(cur_lap_time));
|
|
|
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
//else
|
|
|
|
|
|
|
|
//{
|
|
|
|
|
|
|
|
DrawString(4, 16, disp_time(cur_lap_time)); |
|
|
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// display last 5 lap times
|
|
|
|
|
|
|
|
int j = 30; |
|
|
|
|
|
|
|
for (auto l : list_times) |
|
|
|
|
|
|
|
{ |
|
|
|
{ |
|
|
|
DrawString(10, j, disp_time(l)); |
|
|
|
DrawLineDecal({(float)ScreenWidth()/2,0},{(float)ScreenWidth()/2,(float)ScreenHeight()},RED); |
|
|
|
j += 10; |
|
|
|
DrawLineDecal({0,(float)ScreenHeight()/2},{(float)ScreenWidth(),(float)ScreenHeight()/2},RED); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// debug code
|
|
|
|
DrawCenteredStringDecal({(float)ScreenWidth()/2,(float)ScreenHeight()/2},"Goblin",olc::GREEN,{2.5,2.5}); |
|
|
|
//std::string numb1 = std::to_string(car_pos);
|
|
|
|
//DrawStringDecal({0,0},"TEST",WHITE,{1,1});
|
|
|
|
//DrawString(4, 26, numb1);
|
|
|
|
|
|
|
|
//std::string numb2 = std::to_string(track_dist);
|
|
|
|
|
|
|
|
//DrawString(4, 38, numb2);
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return true; |
|
|
|
return true; |
|
|
|
} |
|
|
|
} |
|
|
@ -1219,7 +718,7 @@ public: |
|
|
|
int main() |
|
|
|
int main() |
|
|
|
{ |
|
|
|
{ |
|
|
|
Racer game; |
|
|
|
Racer game; |
|
|
|
if (game.Construct(1280, 720, 1, 1)) |
|
|
|
if (game.Construct(256, 240, 4, 4)) |
|
|
|
game.Start(); |
|
|
|
game.Start(); |
|
|
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
return 0; |
|
|
|