parent
b7a2846c9d
commit
fce9280b0b
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
@ -1,40 +1,815 @@ |
||||
#include <memory> |
||||
#include <stdio.h> |
||||
//--------------------------------------------------------------------------------------------------
|
||||
// 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" // used for drawing the game |
||||
|
||||
class C2{ |
||||
//--------------------------------------------------------------------------------------------------
|
||||
// class
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
class Racer : public olc::PixelGameEngine |
||||
{ |
||||
public: |
||||
int data=4; |
||||
~C2(){ |
||||
printf("C2 destroyed\n"); |
||||
Racer() |
||||
{ |
||||
sAppName = "F4 Racing"; |
||||
} |
||||
}; |
||||
|
||||
class C1{ |
||||
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<std::pair<float, float>> vecTrack; |
||||
std::list<float> 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<std::string, 4> keyslist = { "UP", "DOWN", "LEFT", "RIGHT" }; |
||||
int configKeyIndex = -1; |
||||
char pressedKey; |
||||
|
||||
public: |
||||
~C1(){ |
||||
printf("C1 destroyed\n"); |
||||
|
||||
// Menu Setup
|
||||
//----------------------------------------
|
||||
bool activeOption = true; // highlighting current option
|
||||
int highlighted; |
||||
|
||||
struct MenuItem |
||||
{ |
||||
std::string label; // label
|
||||
olc::vi2d pos; // label's position
|
||||
std::string label2; //Another label. To the right of label.
|
||||
}; |
||||
|
||||
struct Object |
||||
{ |
||||
olc::vf2d pos{ 0, 0 }; // the x position represents how far to the left/right it is from the center. -1 ~ 1: road's range; the y position is how far along the track it is
|
||||
olc::vf2d size{ 1, 1 }; |
||||
olc::Decal* decal = nullptr; |
||||
olc::vf2d offset{ 0, 0 }; // how far off the image will be
|
||||
bool rendered = false; |
||||
olc::vf2d drawPos; |
||||
olc::vf2d drawSize; |
||||
olc::vf2d drawOffsetPos; |
||||
}; |
||||
|
||||
std::vector<MenuItem> mainMenu; |
||||
std::vector<MenuItem> playGame; |
||||
std::vector<MenuItem> pickTrack; |
||||
std::vector<MenuItem> grandPrix; |
||||
std::vector<MenuItem> selectCar; |
||||
std::vector<MenuItem> controls; |
||||
std::vector<std::string> gameOver; |
||||
|
||||
std::vector<Object> 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, |
||||
track_5, |
||||
track_6, |
||||
track_7, |
||||
track_8, |
||||
track_9, |
||||
JX9, // special track ;)
|
||||
// cups
|
||||
INDIE, |
||||
STREET, |
||||
PRO, |
||||
GRAND_PRIX |
||||
}; |
||||
|
||||
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
|
||||
|
||||
olc::Decal* car; // initialize car
|
||||
olc::Decal* hill; // initialize hill
|
||||
olc::Decal* grass; // initialize grass
|
||||
olc::Decal* road; // initialize road, curbs, and finish line
|
||||
olc::Decal* banner; // initialize banner
|
||||
olc::Decal* title; // initialize title banner
|
||||
|
||||
std::string KeyToString(olc::Key key) { |
||||
const std::array<std::string,98> 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"}; |
||||
return keyStrings[key]; |
||||
} |
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
// Create Game Objects
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool OnUserCreate() override |
||||
{ |
||||
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() / 4 * 3} } |
||||
}; |
||||
|
||||
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 } }, |
||||
{"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 } } |
||||
}; |
||||
|
||||
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 } } |
||||
}; |
||||
|
||||
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) } |
||||
}; |
||||
|
||||
gameOver = { "Return to Main Menu" }; |
||||
|
||||
//----------------------------------------
|
||||
|
||||
car = new olc::Decal(new olc::Sprite("art/car.png")); // load car
|
||||
hill = new olc::Decal(new olc::Sprite("art/hills.png"), false, false); // load hill
|
||||
grass = new olc::Decal(new olc::Sprite("art/grass.png"), false, false); // load grass
|
||||
road = new olc::Decal(new olc::Sprite("art/road.png"), false, false); // load road, curbs, and finish line
|
||||
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
|
||||
|
||||
// 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
|
||||
|
||||
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<MenuItem> list, bool horizontal = false) |
||||
{ |
||||
// 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 = {256,-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
|
||||
|
||||
if (!horizontal) |
||||
{ |
||||
// vertical controls
|
||||
if (GetKey(olc::Key::W).bPressed || GetKey(olc::Key::UP).bPressed) |
||||
{ |
||||
highlighted--; // up
|
||||
} |
||||
if (GetKey(olc::Key::S).bPressed || GetKey(olc::Key::DOWN).bPressed) |
||||
{ |
||||
highlighted++; // down
|
||||
} |
||||
} |
||||
else |
||||
{ |
||||
if (GetKey(olc::Key::A).bPressed || GetKey(olc::Key::LEFT).bPressed) |
||||
{ |
||||
highlighted--; // left
|
||||
} |
||||
if (GetKey(olc::Key::D).bPressed || GetKey(olc::Key::RIGHT).bPressed) |
||||
{ |
||||
highlighted++; // right
|
||||
} |
||||
} |
||||
|
||||
if (highlighted >= (int)list.size()) |
||||
{ |
||||
highlighted = 0; // wrap around when above max
|
||||
} |
||||
if (highlighted < 0) |
||||
{ |
||||
highlighted = list.size() - 1; // wrap around when below zero
|
||||
} |
||||
} |
||||
|
||||
void GetAnyKeyPress(olc::Key keypress) override{ |
||||
if (configKeyIndex!=-1) { |
||||
switch (configKeyIndex) { |
||||
case 0:{ |
||||
Move_Up=keypress; |
||||
}break; |
||||
case 1:{ |
||||
Move_Down=keypress; |
||||
}break; |
||||
case 2:{ |
||||
Move_Left=keypress; |
||||
}break; |
||||
case 3:{ |
||||
Move_Right=keypress; |
||||
}break; |
||||
} |
||||
controls[configKeyIndex].label2=KeyToString(keypress); |
||||
configKeyIndex=-1; |
||||
} |
||||
} |
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
// Main Game Function
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool OnUserUpdate(float fElapsedTime) override |
||||
{ |
||||
if (GetKey(olc::Key::CTRL).bHeld && GetKey(olc::Key::F12).bHeld && !bothKeysPressed) |
||||
{ |
||||
return false; |
||||
} |
||||
|
||||
// dry 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 });
|
||||
|
||||
// draw grass
|
||||
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); |
||||
//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) |
||||
{ |
||||
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; |
||||
} |
||||
} |
||||
void PrintData(std::weak_ptr<C2>ptr) { |
||||
printf("Data is %d\n",ptr.lock()->data); |
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
else if (gameState == state::TRACK_SELECT) |
||||
{ |
||||
DisplayMenu(pickTrack); |
||||
if (GetKey(olc::Key::ENTER).bPressed || GetKey(olc::Key::SPACE).bPressed) |
||||
{ |
||||
if (highlighted == 0) |
||||
{ |
||||
gameState = state::CIRCUIT; |
||||
gameState = state::CAR_SELECT; |
||||
} |
||||
else if (highlighted == 1) |
||||
{ |
||||
gameState = state::FIG_EIGHT; |
||||
gameState = state::CAR_SELECT; |
||||
} |
||||
else if (highlighted == 2) |
||||
{ |
||||
gameState = state::ARROW_HEAD; |
||||
gameState = state::CAR_SELECT; |
||||
} |
||||
else if (highlighted == 3) |
||||
{ |
||||
gameState = state::track_4; |
||||
gameState = state::CAR_SELECT; |
||||
} |
||||
else if (highlighted == 4) |
||||
{ |
||||
gameState = state::OVERPASS; |
||||
gameState = state::CAR_SELECT; |
||||
} |
||||
else if (highlighted == 5) |
||||
{ |
||||
gameState = state::track_5; |
||||
gameState = state::CAR_SELECT; |
||||
} |
||||
else if (highlighted == 6) |
||||
{ |
||||
gameState = state::track_6; |
||||
gameState = state::CAR_SELECT; |
||||
} |
||||
else if (highlighted == 7) |
||||
{ |
||||
gameState = state::track_7; |
||||
gameState = state::CAR_SELECT; |
||||
} |
||||
else if (highlighted == 8) |
||||
{ |
||||
gameState = state::track_8; |
||||
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
|
||||
} |
||||
} |
||||
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; |
||||
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) |
||||
{ |
||||
DisplayMenu(grandPrix); |
||||
if (GetKey(olc::Key::ENTER).bPressed || GetKey(olc::Key::SPACE).bPressed) |
||||
{ |
||||
// 2 x 2 menu
|
||||
if (highlighted == 0) |
||||
{ |
||||
gameState = state::INDIE; |
||||
gameState = state::CAR_SELECT; |
||||
} |
||||
else if (highlighted == 1) |
||||
{ |
||||
gameState = state::STREET; |
||||
gameState = state::CAR_SELECT; |
||||
} |
||||
else if (highlighted == 2) |
||||
{ |
||||
gameState = state::PRO; |
||||
gameState = state::CAR_SELECT; |
||||
} |
||||
else if (highlighted == 3) |
||||
{ |
||||
gameState = state::GRAND_PRIX; |
||||
gameState = state::CAR_SELECT; |
||||
} |
||||
else |
||||
{ |
||||
gameState = state::PLAY_GAME; // return to menu
|
||||
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) |
||||
{ |
||||
DisplayMenu(selectCar); |
||||
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
|
||||
} |
||||
} |
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
else if (gameState == state::CONTROLS) |
||||
{ |
||||
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 |
||||
{ |
||||
gameState = state::MAIN_MENU; |
||||
highlighted = 0; |
||||
} |
||||
} |
||||
if (GetKey(olc::Key::ESCAPE).bPressed || GetKey(olc::Key::BACK).bPressed) |
||||
{ |
||||
gameState = state::MAIN_MENU; |
||||
} |
||||
} |
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
else // run main game loop
|
||||
{ |
||||
Clear(olc::BLACK); // this still needed? we've since replaced it with the gradient sky box
|
||||
|
||||
// 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); |
||||
} |
||||
} |
||||
} |
||||
|
||||
//----------------------------------------
|
||||
// debug quick-reset
|
||||
if (GetKey(olc::Key::F4).bPressed) |
||||
{ |
||||
Reset(); |
||||
} |
||||
// move forward
|
||||
if (GetKey(olc::Key::W).bHeld || GetKey(olc::Key::UP).bHeld) |
||||
{ |
||||
speed += 2.0f * fElapsedTime; |
||||
} |
||||
else // might remove this in a later stage of development
|
||||
{ |
||||
speed -= 1.0f * fElapsedTime; |
||||
} |
||||
// move back ?
|
||||
if (GetKey(olc::Key::S).bHeld || GetKey(olc::Key::DOWN).bHeld) |
||||
{ |
||||
distance -= 20.0f * fElapsedTime; |
||||
} |
||||
|
||||
int car_dir = 0; // default car facing
|
||||
|
||||
// move left
|
||||
if (GetKey(olc::Key::A).bHeld || GetKey(olc::Key::LEFT).bHeld) |
||||
{ |
||||
car_curve -= 0.7f * fElapsedTime; |
||||
car_dir = -1; |
||||
} |
||||
// move right
|
||||
if (GetKey(olc::Key::D).bHeld || GetKey(olc::Key::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)); |
||||
//}
|
||||
|
||||
int main(){ |
||||
// display last 5 lap times
|
||||
int j = 30; |
||||
for (auto l : list_times) |
||||
{ |
||||
DrawString(10, j, disp_time(l)); |
||||
j += 10; |
||||
} |
||||
|
||||
std::shared_ptr<C1> ptrA{std::make_shared<C1>()}; |
||||
// 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);
|
||||
} |
||||
|
||||
std::weak_ptr<C1>ptrA_2=ptrA; |
||||
if (!ptrA_2.expired()) { |
||||
printf("Count:%ld",ptrA.use_count()); |
||||
std::shared_ptr<C1> ptrA_3{ptrA}; |
||||
printf("Inside if statement.\n"); |
||||
std::shared_ptr<C2> ptrB{std::make_shared<C2>()}; |
||||
ptrA_2.lock()->PrintData(ptrB); |
||||
printf("Count:%ld",ptrA.use_count()); |
||||
return true; |
||||
} |
||||
printf("Count:%ld",ptrA.use_count()); |
||||
printf("Outside if statement.\n"); |
||||
}; |
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
return -1; |
||||
int main() |
||||
{ |
||||
Racer game; |
||||
if (game.Construct(1280, 720, 1, 1)) |
||||
game.Start(); |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
// END OF FILE
|
||||
//--------------------------------------------------------------------------------------------------
|
Loading…
Reference in new issue