//========================================================================================================================================
// 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
//========================================================================================================================================