You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
729 lines
23 KiB
729 lines
23 KiB
//========================================================================================================================================
|
|
// 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
|
|
|
|
using namespace olc;
|
|
|
|
//========================================================================================================================================
|
|
// protected variables
|
|
//========================================================================================================================================
|
|
class Racer : public olc::PixelGameEngine
|
|
{
|
|
public:
|
|
Racer()
|
|
{
|
|
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<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;
|
|
|
|
// selection screen variables
|
|
int cup = -1;
|
|
int track = -1;
|
|
int player = 0;
|
|
|
|
//========================================================================================================================================
|
|
// Menu Setup
|
|
//========================================================================================================================================
|
|
public:
|
|
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 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<MenuItem> pause;
|
|
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, 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<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","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 <std::pair <float, float>> 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 <std::pair <float, float>> 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 <std::pair <float, float>> 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 <std::vector <std::pair<float, float>>> trackList = {
|
|
test_track,
|
|
circuit_track,
|
|
infinity_track,
|
|
};
|
|
|
|
//========================================================================================================================================
|
|
// 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() / 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<MenuItem> 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<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 above 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 = 0;
|
|
}
|
|
highlighted = targetItem;
|
|
}
|
|
|
|
//========================================================================================================================================
|
|
if (GetKey(olc::Key::UP).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 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;
|
|
}
|
|
}
|
|
|
|
void DrawCenteredStringDecal(olc::vf2d pos,std::string str,olc::Pixel col=olc::WHITE,olc::vf2d scale={1,1}) {
|
|
olc::vf2d textOffset = olc::vf2d(GetTextSize(str))*scale/2;
|
|
DrawStringDecal(pos-textOffset,str,col,scale);
|
|
}
|
|
|
|
//========================================================================================================================================
|
|
// Main Game Function
|
|
//========================================================================================================================================
|
|
bool OnUserUpdate(float fElapsedTime) override
|
|
{
|
|
DrawLineDecal({(float)ScreenWidth()/2,0},{(float)ScreenWidth()/2,(float)ScreenHeight()},RED);
|
|
DrawLineDecal({0,(float)ScreenHeight()/2},{(float)ScreenWidth(),(float)ScreenHeight()/2},RED);
|
|
|
|
DrawCenteredStringDecal({(float)ScreenWidth()/2,(float)ScreenHeight()/2},"Goblin",olc::GREEN,{2.5,2.5});
|
|
//DrawStringDecal({0,0},"TEST",WHITE,{1,1});
|
|
|
|
return true;
|
|
}
|
|
};
|
|
|
|
//========================================================================================================================================
|
|
|
|
int main()
|
|
{
|
|
Racer game;
|
|
if (game.Construct(256, 240, 4, 4))
|
|
game.Start();
|
|
|
|
return 0;
|
|
}
|
|
|
|
//========================================================================================================================================
|
|
// END OF FILE
|
|
//========================================================================================================================================
|