diff --git a/C++ProjectTemplate b/C++ProjectTemplate index ec862fe..0244949 100755 Binary files a/C++ProjectTemplate and b/C++ProjectTemplate differ diff --git a/car.png b/art/car.png similarity index 100% rename from car.png rename to art/car.png diff --git a/grass.png b/art/grass.png similarity index 100% rename from grass.png rename to art/grass.png diff --git a/mountain.png b/art/hills.png similarity index 100% rename from mountain.png rename to art/hills.png diff --git a/road.png b/art/road.png similarity index 100% rename from road.png rename to art/road.png diff --git a/start.png b/art/start.png similarity index 100% rename from start.png rename to art/start.png diff --git a/main.cpp b/main.cpp index ee6ac89..6ec6d15 100644 --- a/main.cpp +++ b/main.cpp @@ -47,18 +47,25 @@ private: int configKeyIndex = -1; char pressedKey; + int cup = -1; // for cup selection screen + int track = -1; // for track selection screen + + int player = 0; // for car selection screen + + bool start = false; + public: // Menu Setup //---------------------------------------- bool activeOption = true; // highlighting current option - int highlighted; + int highlighted=0; struct MenuItem { std::string label; // label olc::vi2d pos; // label's position - std::string label2; //Another label. To the right of label. + std::string label2; // another label to right of label }; struct Object @@ -99,7 +106,7 @@ public: ARROW_HEAD, track_4, OVERPASS, - track_5, + PEANUT, track_6, track_7, track_8, @@ -131,8 +138,15 @@ public: olc::Decal* banner; // initialize banner olc::Decal* title; // initialize title banner - 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","NUMPAD0","NUMPAD1","NUMPAD2","NUMPAD3","NUMPAD4","NUMPAD5","NUMPAD6","NUMPAD7","NUMPAD8","NUMPAD9","NUMPAD*","NUMPAD/","NUMPAD+","NUMPAD-","NUMPAD.",".","=",",","-","OEM_1","OEM_2","OEM_3","OEM_4","OEM_5","OEM_6","OEM_7","OEM_8","CAPS LOCK","END"}; + 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]; } @@ -152,7 +166,7 @@ public: { { "TRACK SELECTION", { ScreenWidth() / 2, ScreenHeight() / 4 } }, { "GRAND PRIX", { ScreenWidth() / 2, ScreenHeight() / 2 } }, - { "BACK", { ScreenWidth() / 2, ScreenHeight() / 4 * 3} } + { "BACK", { ScreenWidth() / 2, ScreenHeight() / 6 * 5} } }; pickTrack = // show track options @@ -165,7 +179,8 @@ public: {"Track 6", { ScreenWidth() / 4 * 3, ScreenHeight() / 2 } } , {"Track 7", { ScreenWidth() / 4, ScreenHeight() / 4 * 3 } }, {"Track 8", { ScreenWidth() / 2, ScreenHeight() / 4 * 3 } }, - {"Track 9", { ScreenWidth() / 4 * 3, ScreenHeight() / 4 * 3 } } + {"Track 9", { ScreenWidth() / 4 * 3, ScreenHeight() / 4 * 3 } }, + { "BACK", { ScreenWidth() / 2, ScreenHeight() / 6 * 5} } }; grandPrix = // show race cups @@ -186,15 +201,18 @@ public: { "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 } } + { "BLACK", { ScreenWidth() / 5 * 4, ScreenHeight() / 3 * 2 } }, + { "BACK", { ScreenWidth() / 2, ScreenHeight() / 6 * 5} } }; - controls = + controls = // customize controls { - { "FORWARD", { ScreenWidth() / 3, 64 },KeyToString(Move_Up) }, - { "BACK", { ScreenWidth() / 3, 64 + 64 },KeyToString(Move_Down) }, - { "LEFT", { ScreenWidth() / 3, 64 + 128 },KeyToString(Move_Left) }, - { "RIGHT", { ScreenWidth() / 3, 64 + 192 },KeyToString(Move_Right) } + { "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} } }; gameOver = { "Return to Main Menu" }; @@ -208,18 +226,117 @@ public: banner = new olc::Decal(new olc::Sprite("art/start.png"), false, false); // load banner title = new olc::Decal(new olc::Sprite("art/title.png")); // load title banner + //---------------------------------------- + //---------------------------------------- + + // 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 + // JX9 track layout - vecTrack.push_back(std::make_pair(0.0f, 10.0f)); // start/finish line - 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.0, 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 + // javidx9() + { + // these happen to be measured in meters, as per Javid's original construction + // they'll likely be wonky for the game as it's not really modified to fit my units of measure + 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.0, 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 + } + + // track 6 + // ???() + { + 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) + } + + // track 8 + // ???() + { + vecTrack.push_back(std::make_pair(0.0f, 10.0f)); // flag (straight) + } + + // track 9 + // ???() + { + vecTrack.push_back(std::make_pair(0.0f, 10.0f)); // flag (straight) + } + }//*/ for (auto t : vecTrack) { @@ -267,7 +384,7 @@ public: //-------------------------------------------------------------------------------------------------- // main menu //-------------------------------------------------------------------------------------------------- - void DisplayMenu(std::vector list, bool horizontal = false) + void DisplayMenu(std::vector list) { // drawing and coloring menu selections for (int i = 0; i < list.size(); i++) @@ -279,8 +396,9 @@ public: 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 = {256,-textSize.y/2}; + 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 }); } } @@ -288,28 +406,134 @@ public: // selecting options highlighted = std::clamp(highlighted, 0, (int)list.size() - 1); // loop if out of range - if (!horizontal) - { - // vertical controls - if (GetKey(olc::Key::W).bPressed || GetKey(olc::Key::UP).bPressed) - { - highlighted--; // up + int shortestDist=9999999; + int largestDist=-9999999; + int targetItem=highlighted; + + if (GetKey(olc::Key::DOWN).bPressed) { + for (int i=0;ilist[i].pos.y) { //It's above us. + int dist = abs(list[highlighted].pos.y-list[i].pos.y); + if (distlist[i].pos.y) { //It's above us. + int dist = abs(list[highlighted].pos.y-list[i].pos.y); + if (distlist[i].pos.x) { //It's to the left of us. + int dist = abs(list[highlighted].pos.x-list[i].pos.x); + if (dist>largestDist) { + targetItem=i; + largestDist=dist; + } + } + } + } + } } + highlighted=targetItem; + } + + if (GetKey(olc::Key::LEFT).bPressed) { + for (int i=0;ilist[i].pos.x) { //It's to the left of us. + int dist = abs(list[highlighted].pos.x-list[i].pos.x); + if (distlargestDist) { + targetItem=i; + largestDist=dist; + } + } + } + } + } + } + highlighted=targetItem; } if (highlighted >= (int)list.size()) @@ -322,24 +546,34 @@ public: } } - void GetAnyKeyPress(olc::Key keypress) override{ - if (configKeyIndex!=-1) { - switch (configKeyIndex) { - case 0:{ - Move_Up=keypress; +//-------------------------------------------------------------------------------------------------- +// controls +//-------------------------------------------------------------------------------------------------- + void GetAnyKeyPress(olc::Key keypress) override + { + if (configKeyIndex != -1) + { + switch (configKeyIndex) + { + case 0: + { + Move_Up = keypress; }break; - case 1:{ - Move_Down=keypress; + case 1: + { + Move_Right = keypress; }break; - case 2:{ - Move_Left=keypress; + case 2: + { + Move_Left = keypress; }break; - case 3:{ - Move_Right=keypress; + case 3: + { + Move_Down = keypress; }break; } - controls[configKeyIndex].label2=KeyToString(keypress); - configKeyIndex=-1; + controls[configKeyIndex].label2 = KeyToString(keypress); + configKeyIndex = -1; } } @@ -364,10 +598,8 @@ public: DrawPartialWarpedDecal(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) { - DrawStringDecal({0,0},std::string(1,pressedKey),olc::WHITE,{3,3}); // display title DrawDecal({ 95.5f, 95.5f }, title/*, {0.4f, 0.4f}*/); DisplayMenu(mainMenu); @@ -436,59 +668,68 @@ public: if (highlighted == 0) { gameState = state::CIRCUIT; + track = 1; gameState = state::CAR_SELECT; } else if (highlighted == 1) { gameState = state::FIG_EIGHT; + track = 2; gameState = state::CAR_SELECT; } else if (highlighted == 2) { gameState = state::ARROW_HEAD; + track = 3; gameState = state::CAR_SELECT; } else if (highlighted == 3) { gameState = state::track_4; + track = 4; gameState = state::CAR_SELECT; } else if (highlighted == 4) { gameState = state::OVERPASS; + track = 5; gameState = state::CAR_SELECT; } else if (highlighted == 5) { - gameState = state::track_5; + gameState = state::PEANUT; + track = 6; gameState = state::CAR_SELECT; } else if (highlighted == 6) { gameState = state::track_6; + track = 7; gameState = state::CAR_SELECT; } else if (highlighted == 7) { gameState = state::track_7; + track = 8; gameState = state::CAR_SELECT; } else if (highlighted == 8) { gameState = state::track_8; + track = 9; gameState = state::CAR_SELECT; } - //else else { - // return to previous screen, in this instance it should change according to whether the player - // came down via the Cup selection screen, or the Track selection screen + 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 gameState = state::JX9; + track = 0; gameState = state::CAR_SELECT; } if (GetKey(olc::Key::ESCAPE).bPressed || GetKey(olc::Key::BACK).bPressed) @@ -508,26 +749,31 @@ public: if (highlighted == 0) { gameState = state::INDIE; + cup = 0; gameState = state::CAR_SELECT; } else if (highlighted == 1) { gameState = state::STREET; + cup = 1; gameState = state::CAR_SELECT; } else if (highlighted == 2) { gameState = state::PRO; + cup = 2; gameState = state::CAR_SELECT; } else if (highlighted == 3) { gameState = state::GRAND_PRIX; + cup = 3; gameState = state::CAR_SELECT; } else { gameState = state::PLAY_GAME; // return to menu + cup = -1; highlighted = 0; } } @@ -542,12 +788,77 @@ public: else if (gameState == state::CAR_SELECT) { DisplayMenu(selectCar); + if (GetKey(olc::Key::ENTER).bPressed || GetKey(olc::Key::SPACE).bPressed) + { + if (highlighted == 0) + { + // red car + player = 0; + gameState=state::RUN_GAME; + } + else if (highlighted == 1) + { + // blue car + player = 1; + } + else if (highlighted == 2) + { + // green car + player = 2; + } + else if (highlighted == 3) + { + // gold car + player = 3; + } + else if (highlighted == 4) + { + // purple car + player = 4; + } + else if (highlighted == 5) + { + // white car + player = 5; + } + else if (highlighted == 6) + { + // orange car + player = 6; + } + else if (highlighted == 7) + { + // black car + player = 7; + } + 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) { - // needs to go to previous screen - // previous screen may be: - // -Cup Select - // -Track Select + if (cup != -1) + { + // return to cup select + gameState = state::CUP_SELECT; + } + if (track != -1) + { + // return to track select + gameState = state::TRACK_SELECT; + } + highlighted = 0; } } @@ -559,19 +870,29 @@ public: { if (highlighted == 0) { - configKeyIndex=highlighted; + configKeyIndex = highlighted; } else if (highlighted == 1) { - configKeyIndex=highlighted; + configKeyIndex = highlighted; } else if (highlighted == 2) { - configKeyIndex=highlighted; + configKeyIndex = highlighted; } else if (highlighted == 3) { - configKeyIndex=highlighted; + 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 { @@ -586,7 +907,7 @@ public: } //-------------------------------------------------------------------------------------------------- - else // run main game loop + 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 @@ -647,8 +968,8 @@ public: 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 }); + uvs.push_back({ 0, fmod(((distance + horizon) - (track_dist - 20)) / 20.0f, 0.5f) + 0.5f }); + uvs.push_back({ 1, fmod(((distance + horizon) - (track_dist - 20)) / 20.0f, 0.5f) + 0.5f }); } else { @@ -798,7 +1119,6 @@ public: } }; - //-------------------------------------------------------------------------------------------------- int main()