diff --git a/.vscode/launch.json b/.vscode/launch.json index 4c47955..e5add3a 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -8,7 +8,7 @@ "name": "(gdb) Launch", "type": "cppdbg", "request": "launch", - "program": "${workspaceFolder}/a.out", + "program": "${workspaceFolder}/C++ProjectTemplate", "args": [], "stopAtEntry": false, "cwd": "${fileDirname}", diff --git a/C++ProjectTemplate b/C++ProjectTemplate index cc54185..3bb4cef 100755 Binary files a/C++ProjectTemplate and b/C++ProjectTemplate differ diff --git a/a.out b/a.out index 48a50f8..aa52613 100755 Binary files a/a.out and b/a.out differ diff --git a/main.cpp b/main.cpp index ce43259..27f228c 100644 --- a/main.cpp +++ b/main.cpp @@ -1,70 +1,1230 @@ +//======================================================================================================================================== +// F4 Racing +//---------------------------------------------------------------------------------------------------------------------------------------- +// This is an advancement in my game making skills, building off the back of my work on the "Collect the Balls" game. +//---------------------------------------------------------------------------------------------------------------------------------------- +// created by Rune +// black box code by Sigonasr2 from the OLC (one lone coder) Discord server +//======================================================================================================================================== #define OLC_PGE_APPLICATION -#include "pixelGameEngine.h" +#include "pixelGameEngine.h" // used for drawing the game -using namespace olc; - -class Circles : public olc::PixelGameEngine +//======================================================================================================================================== +// protected variables +//======================================================================================================================================== +class Racer : public olc::PixelGameEngine { public: - Circles() + Racer() { - sAppName = "Circles"; + sAppName = "F4 Racing"; } +private: + float car_pos = 0.0f; + float distance = 0.0f; + float speed = 0.0f; + + float curvature = 0.0f; + float track_curve = 0.0f; + float car_curve = 0.0f; + float track_dist = 0.0f; + + float cur_lap_time = 0.0f; + + std::vector> vecTrack; + std::list list_times; + + bool bothKeysPressed = false; // checking for dual key press; could probably work with more than 2 keys + + // custom control template + olc::Key Move_Up = olc::W; + olc::Key Move_Down = olc::S; + olc::Key Move_Left = olc::A; + olc::Key Move_Right = olc::D; + + std::array keyslist = { "UP", "DOWN", "LEFT", "RIGHT" }; + int configKeyIndex = -1; + char pressedKey; + + // selection screen variables + int cup = -1; + int track = -1; + int player = 0; + +//======================================================================================================================================== +// Menu Setup +//======================================================================================================================================== public: + bool activeOption = true; // highlighting current option + int highlighted; - int CIRCLE_PRECISION=32; + struct MenuItem + { + std::string label; // label + olc::vi2d pos; // label's position + std::string label2; // another label to right of label + }; - void DrawCircleDecal(vf2d pos,float radius,Pixel col=WHITE) { - std::vector poly; - std::vector uvs; - for (int i=0;i poly; - std::vector uvs; - poly.push_back(pos); - uvs.push_back({0,0}); - for (int i=0;i mainMenu; + std::vector playGame; + std::vector pickTrack; + std::vector grandPrix; + std::vector selectCar; + std::vector controls; + std::vector pause; + std::vector gameOver; + + std::vector gameObjects; + + enum class state + { + MAIN_MENU, PLAY_GAME, CAR_SELECT, CONTROLS, RUN_GAME, + + // game + TRACK_SELECT, CUP_SELECT, + + // tracks + CIRCUIT, FIG_EIGHT, ARROW_HEAD, track_4, OVERPASS, PEANUT, track_7, TRIDENT, STAR, + JX9, // special track ;) + + // cups + INDIE, STREET, PRO, GRAND_PRIX, PAUSED, RESUME + }; + + state gameState = state::MAIN_MENU; + +//======================================================================================================================================== +// Variables +//======================================================================================================================================== + + // lap times + + // player + int score; // score at end of track; based on final place + int lap; // current lap player is on + int place; // current place player is in + + // initialize sprites + olc::Decal* car; + olc::Decal* hill; + olc::Decal* grass; + olc::Decal* road; + olc::Decal* banner; + olc::Decal* title; + olc::Decal* cups; + olc::Decal* select; + + std::string KeyToString(olc::Key key) + { + const std::array keyStrings = + { + "NONE","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","0","1","2","3","4","5","6","7","8","9", + "F1","F2","F3","F4","F5","F6","F7","F8","F9","F10","F11","F12","UP","DOWN","LEFT","RIGHT","SPACE","TAB","SHIFT","CTRL","INS","DEL","HOME","END","PGUP","PGDN","BACK","ESCAPE","ENTER","ENTER", + "PAUSE","SCROLL LK","Kp-0","Kp-1","Kp-2","Kp-3","Kp-4","Kp-5","Kp-6","Kp-7","Kp-8","Kp-9","Kp-*","Kp-/","Kp-+","Kp--","Kp-.",".","=",",","-","OEM_1", + "OEM_2","OEM_3","OEM_4","OEM_5","OEM_6","OEM_7","OEM_8","CAPS LOCK","END" + }; + return keyStrings[key]; } + // list of all track SECTIONS to be drawn per track + // std::pair is the sections of the track in question + std::vector > test_track = + { + {0.f, 10.f}, + {0.f, 200.f}, + {1.f, 200.f}, + {0.f, 400.f}, + {-1.f, 100.f}, + {0.f, 200.f}, + {-1.f, 200.f}, + {1.f, 200.f}, + {0.f, 200.f}, + {0.2f, 500.f}, + {0.f, 200.f} + }; + + std::vector > circuit_track = + { + {0.f, 10.f}, + {0.f, 270.f}, + {-1.f, 330.f}, + {0.f, 550.f}, + {-1.f, 330.f}, + {0.f, 270.f} + }; + + std::vector > infinity_track = + { + {0.f, 10.f}, + {0.f, 270.f}, + {1.f, 330.f}, + {0.f, 550.f}, + {1.f, 330.f}, + {0.f, 270.f} + }; + + // list of ALL tracks to pick from + std::vector >> trackList = { + test_track, + circuit_track, + infinity_track, + }; + +//======================================================================================================================================== +// Create Game Objects +//======================================================================================================================================== bool OnUserCreate() override { - // Called once at the start, so create things here + mainMenu = // show menu options + { + { "START GAME", { ScreenWidth() / 2, ScreenHeight() / 5 * 3} }, + { "CONTROLS", { ScreenWidth() / 2, ScreenHeight() / 5 * 3 + 64} }, + { "QUIT", {ScreenWidth() / 2, ScreenHeight() / 5 * 3 + 128 } } + }; + + playGame = + { + { "TRACK SELECTION", { ScreenWidth() / 2, ScreenHeight() / 4 } }, + { "GRAND PRIX", { ScreenWidth() / 2, ScreenHeight() / 2 } }, + { "BACK", { ScreenWidth() / 2, ScreenHeight() / 6 * 5} } + }; + + pickTrack = // show track options + { + { "CIRCUIT", { ScreenWidth() / 4, ScreenHeight() / 4 } }, + { "INFINITY", { ScreenWidth() / 2, ScreenHeight() / 4 } }, + { "ARROWHEAD", { ScreenWidth() / 4 * 3, ScreenHeight() / 4 } }, + { "Track 4", { ScreenWidth() / 4, ScreenHeight() / 2 }}, + { "OVERPASS", { ScreenWidth() / 2, ScreenHeight() / 2 } }, + { "PEANUT", { ScreenWidth() / 4 * 3, ScreenHeight() / 2 } } , + { "Track 7", { ScreenWidth() / 4, ScreenHeight() / 4 * 3 } }, + { "TRIDENT", { ScreenWidth() / 2, ScreenHeight() / 4 * 3 } }, + { "STAR", { ScreenWidth() / 4 * 3, ScreenHeight() / 4 * 3 } }, + { "BACK", { ScreenWidth() / 2, ScreenHeight() / 6 * 5} } + }; + + grandPrix = // show race cups + { + { "INDIE CUP", { ScreenWidth() / 3, ScreenHeight() / 3 } }, + { "STREET CUP", { ScreenWidth() / 3 * 2, ScreenHeight() / 3 } }, + { "PRO CUP", { ScreenWidth() / 3, ScreenHeight() / 3 * 2 } }, + { "GRAND PRIX", { ScreenWidth() / 3 * 2, ScreenHeight() / 3 * 2 } }, + { "BACK", { ScreenWidth() / 2, ScreenHeight() / 6 * 5 } } + }; + + selectCar = // pick a color + { + { "RED", { ScreenWidth() / 5, ScreenHeight() / 3 } }, + { "BLUE", { ScreenWidth() / 5 * 2, ScreenHeight() / 3 } }, + { "GREEN", { ScreenWidth() / 5 * 3, ScreenHeight() / 3 } }, + { "GOLD", { ScreenWidth() / 5 * 4, ScreenHeight() / 3 } }, + { "PURPLE", { ScreenWidth() / 5, ScreenHeight() / 3 * 2 } }, + { "WHITE", { ScreenWidth() / 5 * 2, ScreenHeight() / 3 * 2 } }, + { "ORANGE", { ScreenWidth() / 5 * 3, ScreenHeight() / 3 * 2 } }, + { "BLACK", { ScreenWidth() / 5 * 4, ScreenHeight() / 3 * 2 } }, + { "BACK", { ScreenWidth() / 2, ScreenHeight() / 6 * 5} } + }; + + controls = // customize controls + { + { "FORWARD", { ScreenWidth() / 3, ScreenHeight() / 9 * 2 }, KeyToString(Move_Up) }, + { "BACK", { ScreenWidth() / 3, ScreenHeight() / 9 * 3 }, KeyToString(Move_Down) }, + { "LEFT", { ScreenWidth() / 3, ScreenHeight() / 9 * 4 }, KeyToString(Move_Left) }, + { "RIGHT", { ScreenWidth() / 3, ScreenHeight() / 9 * 5 }, KeyToString(Move_Right) }, + { "DEFAULT", { ScreenWidth() / 2, ScreenHeight() / 9 * 6} }, + { "BACK", { ScreenWidth() / 2, ScreenHeight() / 6 * 5} } + }; + + pause = + { + { "RESUME", { ScreenWidth() / 2, ScreenHeight() / 9 * 3} }, + { "RESTART", { ScreenWidth() / 2, ScreenHeight() / 9 * 4} }, + { "MENU", { ScreenWidth() / 2, ScreenHeight() / 9 * 5} }, + { "QUIT", { ScreenWidth() / 2, ScreenHeight() / 9 * 6} } + }; + + gameOver = { "Return to Main Menu" }; + +//======================================================================================================================================== + // load sprites + car = new olc::Decal(new olc::Sprite("art/car.png")); // will contain 8 cars, with 3 angles per car + hill = new olc::Decal(new olc::Sprite("art/hills.png"), false, false); + grass = new olc::Decal(new olc::Sprite("art/grass.png"), false, false); + road = new olc::Decal(new olc::Sprite("art/road.png"), false, false); // holds both road and flag line + banner = new olc::Decal(new olc::Sprite("art/start.png"), false, false); + title = new olc::Decal(new olc::Sprite("art/title.png")); + cups = new olc::Decal(new olc::Sprite("art/cups.png")); // 64 px tiles; 128 px image + select = new olc::Decal(new olc::Sprite("art/selection.png")); + +//======================================================================================================================================== +//======================================================================================================================================== + // may need to separate the track list into it's own function so as to declutter this one + // especially, given that there's a bunch of stuff going on with the tracks with much redundancy + + //trackList= {track_1, track_2}; + + // JX9 track layout + // javidx9 = + //{ + // // they'll likely be wonky for the game as it's not really modified to fit my units of + // // these happen to be measured in meters, as per Javid's original constructionmeasure + // vecTrack.push_back(std::make_pair(0.0f, 10.0f)); // flag (straight) + // vecTrack.push_back(std::make_pair(0.0f, 200.0f)); // straight + // vecTrack.push_back(std::make_pair(1.0f, 200.0f)); // sharp right + // vecTrack.push_back(std::make_pair(0.0f, 400.0f)); // long straight + // vecTrack.push_back(std::make_pair(-1.0f, 100.0f)); // soft left + // vecTrack.push_back(std::make_pair(0.0f, 200.0f)); // straight + // vecTrack.push_back(std::make_pair(-1.0f, 200.0f)); // sharp left + // vecTrack.push_back(std::make_pair(1.0f, 200.0f)); // sharp right + // vecTrack.push_back(std::make_pair(0.0f, 200.0f)); // straight + // vecTrack.push_back(std::make_pair(0.2f, 500.0f)); // gradual right + // vecTrack.push_back(std::make_pair(0.0f, 200.0f)); // straight + //} + + // all 9 tracks below are running on yards for their distance units + // this means the end results are in miles; rather than kilometers + // enjoy the US measures of Burgers per Freedom Eagle + + /*{ + // Classic Oval + // Circuit = + { + // 1 mile loop; 1,760 yards + vecTrack.push_back(std::make_pair(0.0f, 10.0f)); // flag (straight) + vecTrack.push_back(std::make_pair(0.0f, 270.0f)); // straight + vecTrack.push_back(std::make_pair(-1.0f, 330.0f)); // left + vecTrack.push_back(std::make_pair(0.0f, 550.0f)); // straight + vecTrack.push_back(std::make_pair(-1.0f, 330.0f)); // left + vecTrack.push_back(std::make_pair(0.0f, 270.0f)); // straight + } + + // Infinity + // FigureEight = + { + vecTrack.push_back(std::make_pair(0.0f, 10.0f)); // flag (straight); this is positioned somewhere after the intersection + vecTrack.push_back(std::make_pair(0.0f, 0.0f)); // straight + vecTrack.push_back(std::make_pair(-1.0f, 0.0f)); // left + vecTrack.push_back(std::make_pair(0.0f, 0.0f)); // straight; this crosses the first straight, to provide for chances of crashing + vecTrack.push_back(std::make_pair(1.0f, 0.0f)); // right + vecTrack.push_back(std::make_pair(0.0f, 0.0f)); // straight + } + + // Arrow Head + // ArrowHead = + { + // miles + vecTrack.push_back(std::make_pair(0.0f, 10.0f)); // flag (straight) + vecTrack.push_back(std::make_pair(0.0f, 0.0f)); // straight + vecTrack.push_back(std::make_pair(1.0f, 0.0f)); // right + vecTrack.push_back(std::make_pair(0.0f, 0.0f)); // straight + vecTrack.push_back(std::make_pair(1.0f, 0.0f)); // right + vecTrack.push_back(std::make_pair(-1.0f, 0.0f)); // left + vecTrack.push_back(std::make_pair(1.0f, 0.0f)); // right + vecTrack.push_back(std::make_pair(0.0f, 0.0f)); // straight + + } + + // track 4 + // ??? = + { + vecTrack.push_back(std::make_pair(0.0f, 10.0f)); // flag (straight) + } + + // Over/Under + // OverPass = + { + vecTrack.push_back(std::make_pair(0.0f, 10.0f)); // flag (straight) + vecTrack.push_back(std::make_pair(0.0f, 0.0f)); // straight + vecTrack.push_back(std::make_pair(1.0f, 0.0f)); // right + vecTrack.push_back(std::make_pair(0.0f, 0.0f)); // straight + vecTrack.push_back(std::make_pair(1.0f, 0.0f)); // right + vecTrack.push_back(std::make_pair(1.0f, 0.0f)); // right + vecTrack.push_back(std::make_pair(0.0f, 0.0f)); // straight + vecTrack.push_back(std::make_pair(1.0f, 0.0f)); // right + vecTrack.push_back(std::make_pair(0.0f, 0.0f)); // straight + } + + // Peanut + // Peanut = + { + vecTrack.push_back(std::make_pair(0.0f, 10.0f)); // flag (straight) + } + + // track 7 + // ??? = + { + vecTrack.push_back(std::make_pair(0.0f, 10.0f)); // flag (straight) + } + + // Trident + // Trident = + { + vecTrack.push_back(std::make_pair(0.0f, 10.0f)); // flag (straight) + } + + // Star + // ??? = + { + vecTrack.push_back(std::make_pair(0.0f, 10.0f)); // flag (straight) + } + }//*/ + + for (auto t : vecTrack) + { + track_dist += t.second; + } + + distance = track_dist - 100; + list_times = { 0,0,0,0,0 }; + gameObjects.push_back({ /*{-1.5,track_dist - 50}, {10,6}, {0,240}*/ }); + return true; } +//======================================================================================================================================== +// reset game +//======================================================================================================================================== + + void Reset() + { + car_pos = 0.0f; + distance = 0.0f; + speed = 0.0f; + + curvature = 0.0f; + track_curve = 0.0f; + car_curve = 0.0f; + //track_dist = 0.0f; will need to be moved elsewhere; the game will calculate *ALL* track sizes at the start, and then simply use the appropriate numbers when loading each track on request + + cur_lap_time = 0.0f; + + // Note: the following all need to be reset during the process, when they've been implemented + // -player position (on screen) + // -player position (on track) + // -track section + // -all lap times + // -score + // + // if called from other parts of the program, other than the 'F1' key, it should be resetting to the menu + // the 'F1' key is meant to reset the player on the current track they're on + // + } + +//======================================================================================================================================== +// main menu +//======================================================================================================================================== + void DisplayMenu(std::vector list) + { + // drawing and coloring menu selections + for (int i = 0; i < list.size(); i++) + { + olc::vi2d textSize = GetTextSize(list[i].label) / 2 * 4; + olc::Pixel textCol = olc::GREY; // greys out unselected options + if (highlighted == i) + { + textCol = olc::Pixel(255, 201, 14); // gold + } + + DrawStringDecal(list[i].pos - textSize, list[i].label, textCol, { 4.0f, 4.0f }); + if (list[i].label2.size() > 0) + { + olc::vi2d offset = { ScreenWidth() / 3, -textSize.y / 2 }; + DrawStringDecal(list[i].pos + offset, list[i].label2, textCol, { 4.0f, 4.0f }); + } + } + + // selecting options + highlighted = std::clamp(highlighted, 0, (int)list.size() - 1); // loop if out of range + + int shortest = 9999999; + int largest = -9999999; + int targetItem = highlighted; + +//======================================================================================================================================== + if (GetKey(olc::Key::DOWN).bPressed) + { + for (int i = 0; i < list.size(); i++) + { + if (highlighted != i) + { + if (list[highlighted].pos.x == list[i].pos.x) + { + if (list[highlighted].pos.y < list[i].pos.y) + { + // it's below us + int dist = abs(list[highlighted].pos.y - list[i].pos.y); + + if (dist list[i].pos.y) + { + // it's above us + int dist = abs(list[highlighted].pos.y - list[i].pos.y); + + if (dist < shortest) + { + targetItem = i; + shortest = dist; + } + } + } + } + } + for (int i = 0; i < list.size(); i++) + { + if (highlighted != i) + { + if (list[highlighted].pos.y > list[i].pos.y) + { + // it's below us + int dist = abs(list[highlighted].pos.y - list[i].pos.y); + + if (dist < shortest) + { + targetItem = i; + shortest = dist; + } + } + } + } + + // it failed, try another method + if (highlighted == targetItem) + { + targetItem = list.size() - 1; + } + highlighted = targetItem; + } + +//======================================================================================================================================== + if (GetKey(olc::Key::RIGHT).bPressed) + { + for (int i = 0; i < list.size(); i++) + { + if (highlighted != i) + { + if (list[highlighted].pos.y == list[i].pos.y) + { + if (list[highlighted].pos.x < list[i].pos.x) + { + // it's to the right + int dist = abs(list[highlighted].pos.x - list[i].pos.x); + + if (dist < shortest) + { + targetItem = i; + shortest = dist; + } + } + } + } + } + if (highlighted == targetItem) + { + for (int i = 0; i < list.size(); i++) + { + if (highlighted != i) + { + if (list[highlighted].pos.y == list[i].pos.y) + { + if (list[highlighted].pos.x > list[i].pos.x) + { + // it's to the left + int dist = abs(list[highlighted].pos.x - list[i].pos.x); + + if (dist > largest) + { + targetItem = i; + largest = dist; + } + } + } + } + } + } + highlighted = targetItem; + } + +//======================================================================================================================================== + if (GetKey(olc::Key::LEFT).bPressed) + { + for (int i = 0; i < list.size(); i++) + { + if (highlighted != i) + { + if (list[highlighted].pos.y == list[i].pos.y) + { + if (list[highlighted].pos.x > list[i].pos.x) + { + // it's to the right + int dist = abs(list[highlighted].pos.x - list[i].pos.x); + + if (dist < shortest) + { + targetItem = i; + shortest = dist; + } + } + } + } + } + if (highlighted == targetItem) + { + for (int i = 0; i < list.size(); i++) + { + if (highlighted != i) + { + if (list[highlighted].pos.y == list[i].pos.y) + { + if (list[highlighted].pos.x < list[i].pos.x) + { + // it's to the left + int dist = abs(list[highlighted].pos.x - list[i].pos.x); + + if (dist > largest) + { + targetItem = i; + largest = dist; + } + } + } + } + } + } + highlighted = targetItem; + } + + //======================================== + if (highlighted >= (int)list.size()) + { + highlighted = 0; // wrap around when above max + } + if (highlighted < 0) + { + highlighted = list.size() - 1; // wrap around when below zero + } + } + +//======================================================================================================================================== +// controls +//======================================================================================================================================== + void GetAnyKeyPress(olc::Key keypress) override + { + if (configKeyIndex != -1) + { + switch (configKeyIndex) + { + case 0: + { + Move_Up = keypress; + }break; + case 1: + { + Move_Right = keypress; + }break; + case 2: + { + Move_Left = keypress; + }break; + case 3: + { + Move_Down = keypress; + }break; + } + controls[configKeyIndex].label2 = KeyToString(keypress); + configKeyIndex = -1; + } + } + +//======================================================================================================================================== +// Main Game Function +//======================================================================================================================================== bool OnUserUpdate(float fElapsedTime) override { - // called once per frame - DrawCircleDecal({50,50},10,BLUE); - FillCircleDecal({100,100},20,GREEN); + 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; + + } + 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); + } + return true; } }; +//======================================================================================================================================== int main() { - Circles demo; - if (demo.Construct(256, 240, 4, 4)) - demo.Start(); + Racer game; + if (game.Construct(1280, 720, 1, 1)) + game.Start(); return 0; } + +//======================================================================================================================================== +// END OF FILE +//======================================================================================================================================== \ No newline at end of file diff --git a/pixelGameEngine.h b/pixelGameEngine.h index 368ebc3..3005cbe 100644 --- a/pixelGameEngine.h +++ b/pixelGameEngine.h @@ -3,7 +3,7 @@ olcPixelGameEngine.h +-------------------------------------------------------------+ - | OneLoneCoder Pixel Game Engine v2.19 | + | OneLoneCoder Pixel Game Engine v2.20 | | "What do you need? Pixels... Lots of Pixels..." - javidx9 | +-------------------------------------------------------------+ @@ -187,6 +187,8 @@ AlterEgo...........Final Fantasy XII - The Zodiac Age SlicEnDicE.........Noita, Inside TGD................Voucher Gift + Dragoneye..........Lucas Arts Adventure Game Pack + Anonymous Pirate...Return To Monkey Island Special thanks to my Patreons too - I wont name you on here, but I've certainly enjoyed my tea and flapjacks :D @@ -297,9 +299,16 @@ +ConsoleClear() - Clears built in command console output +ConsoleOut() - Stream strings to command console output +ConsoleCaptureStdOut() - Capture std::cout by redirecting to built-in console - +IsConsoleShowing() - Returns true if console is currently active +OnConsoleCommand() - Override is called when command is entered into built in console + 2.20: +DrawRectDecal() - Keeps OneSketchyGuy quiet + +GetScreenSize() + +olc::Sprite::Size() - returns size of sprite in vector format + SIG Updates: + The following additions are included in Sig's version of the PGE header (this is a sig version) + +GetAnyKey() - Returns when a key is activated + +GetAnyKeyPress() - Returns when a key is pressed down (and if a keyboard key, which key it was) + !! Apple Platforms will not see these updates immediately - Sorry, I dont have a mac to test... !! !! Volunteers willing to help appreciated, though PRs are manually integrated with credit !! */ @@ -378,7 +387,7 @@ int main() #include #pragma endregion -#define PGE_VER 219 +#define PGE_VER 220 // O------------------------------------------------------------------------------O // | COMPILER CONFIGURATION ODDITIES | @@ -771,6 +780,7 @@ namespace olc Pixel* GetData(); olc::Sprite* Duplicate(); olc::Sprite* Duplicate(const olc::vi2d& vPos, const olc::vi2d& vSize); + olc::vi2d Size() const; std::vector pColData; Mode modeSample = Mode::NORMAL; @@ -982,6 +992,8 @@ namespace olc const olc::vi2d& GetPixelSize() const; // Gets actual pixel scale const olc::vi2d& GetScreenPixelSize() const; + // Gets "screen" size + const olc::vi2d& GetScreenSize() const; public: // CONFIGURATION ROUTINES // Layer targeting functions @@ -1076,6 +1088,7 @@ namespace olc void DrawStringDecal(const olc::vf2d& pos, const std::string& sText, const Pixel col = olc::WHITE, const olc::vf2d& scale = { 1.0f, 1.0f }); void DrawStringPropDecal(const olc::vf2d& pos, const std::string& sText, const Pixel col = olc::WHITE, const olc::vf2d& scale = { 1.0f, 1.0f }); // Draws a single shaded filled rectangle as a decal + void DrawRectDecal(const olc::vf2d& pos, const olc::vf2d& size, const olc::Pixel col = olc::WHITE); void FillRectDecal(const olc::vf2d& pos, const olc::vf2d& size, const olc::Pixel col = olc::WHITE); // Draws a corner shaded rectangle as a decal void GradientFillRectDecal(const olc::vf2d& pos, const olc::vf2d& size, const olc::Pixel colTL, const olc::Pixel colBL, const olc::Pixel colBR, const olc::Pixel colTR); @@ -1086,7 +1099,6 @@ namespace olc // Draws a line in Decal Space void DrawLineDecal(const olc::vf2d& pos1, const olc::vf2d& pos2, Pixel p = olc::WHITE); - void DrawRectDecal(const olc::vf2d& pos1, const olc::vf2d& pos2, Pixel p = olc::WHITE); void DrawRotatedStringDecal(const olc::vf2d& pos, const std::string& sText, const float fAngle, const olc::vf2d& center = { 0.0f, 0.0f }, const olc::Pixel col = olc::WHITE, const olc::vf2d& scale = { 1.0f, 1.0f }); void DrawRotatedStringPropDecal(const olc::vf2d& pos, const std::string& sText, const float fAngle, const olc::vf2d& center = { 0.0f, 0.0f }, const olc::Pixel col = olc::WHITE, const olc::vf2d& scale = { 1.0f, 1.0f }); // Clears entire draw target to Pixel @@ -1114,7 +1126,6 @@ namespace olc std::string TextEntryGetString() const; int32_t TextEntryGetCursor() const; bool IsTextEntryEnabled() const; - void SetFPSDisplay(bool display); @@ -1152,7 +1163,6 @@ namespace olc #endif public: // Branding std::string sAppName; - Renderable fontRenderable; private: // Inner mysterious workings olc::Sprite* pDrawTarget = nullptr; @@ -1178,8 +1188,8 @@ namespace olc float fFrameTimer = 1.0f; float fLastElapsed = 0.0f; int nFrameCount = 0; - bool showFPS = true; bool bSuspendTextureTransfer = false; + Renderable fontRenderable; std::vector vLayers; uint8_t nTargetLayer = 0; uint32_t nLastFPS = 0; @@ -1511,6 +1521,11 @@ namespace olc return spr; } + olc::vi2d olc::Sprite::Size() const + { + return { width, height }; + } + // O------------------------------------------------------------------------------O // | olc::Decal IMPLEMENTATION | // O------------------------------------------------------------------------------O @@ -1947,6 +1962,9 @@ namespace olc const olc::vi2d& PixelGameEngine::GetScreenPixelSize() const { return vScreenPixelSize; } + const olc::vi2d& PixelGameEngine::GetScreenSize() const + { return vScreenSize; } + const olc::vi2d& PixelGameEngine::GetWindowMouse() const { return vMouseWindowPos; } @@ -2670,7 +2688,12 @@ namespace olc void PixelGameEngine::DrawLineDecal(const olc::vf2d& pos1, const olc::vf2d& pos2, Pixel p) { - DecalInstance di; + auto m = nDecalMode; + nDecalMode = olc::DecalMode::WIREFRAME; + DrawPolygonDecal(nullptr, { pos1, pos2 }, { {0, 0}, {0,0} }, p); + nDecalMode = m; + + /*DecalInstance di; di.decal = nullptr; di.points = uint32_t(2); di.pos.resize(di.points); @@ -2686,19 +2709,26 @@ namespace olc di.tint[1] = p; di.w[1] = 1.0f; di.mode = olc::DecalMode::WIREFRAME; - vLayers[nTargetLayer].vecDecalInstance.push_back(di); + di.structure = nDecalStructure; + vLayers[nTargetLayer].vecDecalInstance.push_back(di);*/ } - void PixelGameEngine::DrawRectDecal(const olc::vf2d& pos, const olc::vf2d& size, const olc::Pixel col) { - DrawLineDecal(pos,{pos.x+size.x,pos.y},col); - DrawLineDecal({pos.x,pos.y},{pos.x,pos.y+size.y},col); - DrawLineDecal({pos.x,pos.y+size.y},{pos.x+size.x,pos.y+size.y},col); - DrawLineDecal({pos.x+size.x,pos.y},{pos.x+size.x,pos.y+size.y},col); + void PixelGameEngine::DrawRectDecal(const olc::vf2d& pos, const olc::vf2d& size, const olc::Pixel col) + { + auto m = nDecalMode; + SetDecalMode(olc::DecalMode::WIREFRAME); + olc::vf2d vNewSize = size;// (size - olc::vf2d(0.375f, 0.375f)).ceil(); + std::array points = { { {pos}, {pos.x, pos.y + vNewSize.y}, {pos + vNewSize}, {pos.x + vNewSize.x, pos.y} } }; + std::array uvs = { {{0,0},{0,0},{0,0},{0,0}} }; + std::array cols = { {col, col, col, col} }; + DrawExplicitDecal(nullptr, points.data(), uvs.data(), cols.data(), 4); + SetDecalMode(m); + } void PixelGameEngine::FillRectDecal(const olc::vf2d& pos, const olc::vf2d& size, const olc::Pixel col) { - olc::vf2d vNewSize = (size - olc::vf2d(0.375f, 0.375f)).ceil(); + olc::vf2d vNewSize = size;// (size - olc::vf2d(0.375f, 0.375f)).ceil(); std::array points = { { {pos}, {pos.x, pos.y + vNewSize.y}, {pos + vNewSize}, {pos.x + vNewSize.x, pos.y} } }; std::array uvs = { {{0,0},{0,0},{0,0},{0,0}} }; std::array cols = { {col, col, col, col} }; @@ -3211,9 +3241,6 @@ namespace olc bool PixelGameEngine::IsTextEntryEnabled() const { return bTextEntryEnable; } - void PixelGameEngine::SetFPSDisplay(bool display) - { showFPS=display; } - void PixelGameEngine::UpdateTextEntry() { @@ -3481,11 +3508,12 @@ namespace olc } if (pressed) { if (keyboard) {GetAnyKeyPress((olc::Key)key);} - else {GetAnyKeyPress(olc::Key::NONE);}} + else {GetAnyKeyPress(olc::Key::NONE);} + } }; ScanHardware(pKeyboardState, pKeyOldState, pKeyNewState, 256); - ScanHardware(pMouseState, pMouseOldState, pMouseNewState, nMouseButtons,false); + ScanHardware(pMouseState, pMouseOldState, pMouseNewState, nMouseButtons, false); // Cache mouse coordinates so they remain consistent during frame vMousePos = vMousePosCache; @@ -3555,21 +3583,16 @@ namespace olc // Present Graphics to screen renderer->DisplayFrame(); - if (showFPS) { - // Update Title Bar - fFrameTimer += fElapsedTime; - nFrameCount++; - if (fFrameTimer >= 1.0f) - { - nLastFPS = nFrameCount; - fFrameTimer -= 1.0f; - std::string sTitle = "OneLoneCoder.com - Pixel Game Engine - " + sAppName + " - FPS: " + std::to_string(nFrameCount); - platform->SetWindowTitle(sTitle); - nFrameCount = 0; - } - } else { - std::string sTitle = "OneLoneCoder.com - Pixel Game Engine - " + sAppName; + // Update Title Bar + fFrameTimer += fElapsedTime; + nFrameCount++; + if (fFrameTimer >= 1.0f) + { + nLastFPS = nFrameCount; + fFrameTimer -= 1.0f; + std::string sTitle = "OneLoneCoder.com - Pixel Game Engine - " + sAppName + " - FPS: " + std::to_string(nFrameCount); platform->SetWindowTitle(sTitle); + nFrameCount = 0; } } diff --git a/sig b/sig index 65804b4..b55ded9 100755 --- a/sig +++ b/sig @@ -1,4 +1,4 @@ -export AUTO_UPDATE=true +export AUTO_UPDATE=false source utils/define.sh