diff --git a/C++ProjectTemplate b/C++ProjectTemplate index 3bb4cef..6425f6a 100755 Binary files a/C++ProjectTemplate and b/C++ProjectTemplate differ diff --git a/main.cpp b/main.cpp index 27f228c..6ce8258 100644 --- a/main.cpp +++ b/main.cpp @@ -9,6 +9,8 @@ #define OLC_PGE_APPLICATION #include "pixelGameEngine.h" // used for drawing the game +using namespace olc; + //======================================================================================================================================== // 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}) { + olc::vf2d textOffset = olc::vf2d(GetTextSize(str))*scale/2; + DrawStringDecal(pos-textOffset,str,col,scale); + } + //======================================================================================================================================== // Main Game Function //======================================================================================================================================== 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) - { - 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; + DrawLineDecal({(float)ScreenWidth()/2,0},{(float)ScreenWidth()/2,(float)ScreenHeight()},RED); + DrawLineDecal({0,(float)ScreenHeight()/2},{(float)ScreenWidth(),(float)ScreenHeight()/2},RED); - } - 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 pos; - std::vector 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 - 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)); - j += 10; - } - - // debug code - //std::string numb1 = std::to_string(car_pos); - //DrawString(4, 26, numb1); - //std::string numb2 = std::to_string(track_dist); - //DrawString(4, 38, numb2); - } + DrawCenteredStringDecal({(float)ScreenWidth()/2,(float)ScreenHeight()/2},"Goblin",olc::GREEN,{2.5,2.5}); + //DrawStringDecal({0,0},"TEST",WHITE,{1,1}); return true; } @@ -1219,7 +718,7 @@ public: int main() { Racer game; - if (game.Construct(1280, 720, 1, 1)) + if (game.Construct(256, 240, 4, 4)) game.Start(); return 0;