Both Keys pressed example

Co-authored-by: sigonasr2 <sigonasr2@gmail.com>
master
sigonasr2 2 years ago
parent a1168e4202
commit 66aa6d03c6
  1. BIN
      C++ProjectTemplate
  2. 378
      main.cpp
  3. BIN
      start.png

Binary file not shown.

@ -1,183 +1,26 @@
//--------------------------------------------------------------------------------------------------
// 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
//--------------------------------------------------------------------------------------------------
#define OLC_PGE_APPLICATION
#include "pixelGameEngine.h" // used for drawing the game
#include "pixelGameEngine.h"
//--------------------------------------------------------------------------------------------------
// class
//--------------------------------------------------------------------------------------------------
class Racer : public olc::PixelGameEngine
class PressDetect : public olc::PixelGameEngine
{
public:
Racer()
PressDetect()
{
sAppName = "F4 Racing";
sAppName = "Double Press Down Detect";
}
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;
public:
// Menu Setup
//----------------------------------------
struct MenuItem
{
std::string label; // label
olc::vi2d pos; // label's position
};
struct Object
{
olc::vf2d pos; //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;
bool rendered=false;
olc::vf2d drawPos;
olc::vf2d drawSize;
};
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,
TRACK_SELECT,
CUP_SELECT,
CAR_SELECT,
CONTROLS,
RUN_GAME
};
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 image
olc::Decal* hill; // initialize hill image
olc::Decal* grass; // initialize grass image
olc::Decal* road; // initialize road image
//--------------------------------------------------------------------------------------------------
// Create Game Objects
//--------------------------------------------------------------------------------------------------
bool OnUserCreate() override
{
// show menu options
mainMenu =
{
{ "START GAME", { ScreenWidth() / 2, ScreenHeight() / 2 } },
{ "CONTROLS", { ScreenWidth() / 2, ScreenHeight() / 2 + 16} },
{ "QUIT", {ScreenWidth() / 2, ScreenHeight() / 2 + 32 } }
};
playGame =
{
{ "TRACK SELECTION", { ScreenWidth() / 2, ScreenHeight() / 2 } },
{ "GRAND PRIX", { ScreenWidth() / 2, ScreenHeight() / 2 + 32 } }
};
// show track options
pickTrack =
{
{ "LOOP", { ScreenWidth() / 3, ScreenHeight() / 3 } },
{ "INFINITY", { ScreenWidth() / 2, ScreenHeight() / 3 } },
{ "ARROWHEAD", { ScreenWidth() / 3 * 2, ScreenHeight() / 3 } }//,
// track 4
//{ "OVERPASS", { ScreenWidth() / 3 * 2, ScreenHeight() / 3 * 2 } },
// track 6
// track 7
// track 8
// track 9
};
grandPrix =
{
// { "INDIE CUP", { ScreenWidth() / 2, ScreenHeight() / 2 } }
// { "STREET CUP", { ScreenWidth() / 2, ScreenHeight() / 2 } }
// { "PRO CUP", { ScreenWidth() / 2, ScreenHeight() / 2 } }
{ "GRAND PRIX", { ScreenWidth() / 2, ScreenHeight() / 2 } }
};
selectCar =
{
{ "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 } }
};
gameOver = { "Return to Main Menu" };
//----------------------------------------
car = new olc::Decal(new olc::Sprite("car.png")); // load car image
hill = new olc::Decal(new olc::Sprite("mountain.png"), false, false); // load hill image
grass = new olc::Decal(new olc::Sprite("grass.png"), false, false); // load grass image
road = new olc::Decal(new olc::Sprite("road.png"), false, false); // load grass image
// 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;
}
list_times = { 0,0,0,0,0 };
Object dot1 = {{0,600},{16,16}};
Object dot2 = {{0,900},{16,16}};
gameObjects.push_back(dot1);
gameObjects.push_back(dot2);
return true;
}
@ -186,218 +29,31 @@ public:
//--------------------------------------------------------------------------------------------------
bool OnUserUpdate(float fElapsedTime) override
{
Clear(olc::BLACK);
// get point on 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;
// 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/12.0f }, { 1 * 32, 5 * 2 } );
std::vector<olc::vf2d> pos;
std::vector<olc::vf2d> uv;
for (Object&obj:gameObjects) {
obj.rendered=false;
}
// draw track canvas
for (int y = 0; y < ScreenHeight() / 2; y++)
{
// track 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;
// drawing grass and curb
olc::Pixel curb_col = sinf(80.0f * powf(1.0f - perspective, 3) + distance) > 0.0f ? olc::RED : olc::WHITE;
pos.push_back({lf_curb,row});
pos.push_back({rt_curb,row});
float horizonDistance = powf(1.0f - perspective, 2)*80;
if (distance+horizonDistance>track_dist-20&&distance+horizonDistance<track_dist) {
uv.push_back({0,fmod(((distance+horizonDistance)-(track_dist-20))/20.0F,0.5)+0.5});
uv.push_back({1,fmod(((distance+horizonDistance)-(track_dist-20))/20.0F,0.5)+0.5});
} else {
uv.push_back({0,sinf(80.0f * powf(1.0f - perspective, 2) + distance)/4+0.25});
uv.push_back({1,sinf(80.0f * powf(1.0f - perspective, 2) + distance)/4+0.25});
}
int i=0;
for (Object&obj:gameObjects) {
float perspectiveRange = powf(1.0f - perspective, 2)*((distance+80)-obj.pos.y)/80;
if (!obj.rendered&&(distance+horizonDistance)>obj.pos.y&&(distance+horizonDistance)<obj.pos.y+80&&row>=ScreenHeight()/2+ScreenHeight()/2*perspectiveRange) {
std::cout<<":"<<powf(1.0f - perspective, 2)<<","<<(distance+80)<<","<<obj.pos.y<<","<<row<<","<<ScreenHeight()/2+ScreenHeight()/2*perspectiveRange<<"\n";
float horizonRange = powf(1.0f - perspective, 2)*((distance+horizonDistance)-obj.pos.y)/horizonDistance;
obj.drawPos={mid_point*ScreenWidth(),horizonRange*(ScreenHeight()/2)+ScreenHeight()/2};
std::cout<<obj.pos.y<<"/"<<(distance+horizonDistance)<<"\n";
obj.drawSize={64*perspectiveRange,64*perspectiveRange};
obj.rendered=true;
}
}
//olc::Pixel road_col = (TrackSection - 1) == 0 ? olc::GREY : olc::DARK_GREY; // checkerboard line
}
SetDecalStructure(olc::DecalStructure::STRIP);
DrawPolygonDecal(road,pos,uv);
SetDecalStructure(olc::DecalStructure::FAN);
for (Object&obj:gameObjects) {
if (obj.rendered) {
FillRectDecal(obj.drawPos,obj.drawSize,olc::BLUE);
}
}
//----------------------------------------
// 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 -= 10.0f * fElapsedTime;
if (GetKey(olc::SHIFT).bHeld&&GetKey(olc::A).bHeld&&!bothKeysPressed) {
bothKeysPressed=true;
std::cout<<"Both Keys pressed\n";
}
int car_dir = 0;
// 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;
if (bothKeysPressed&&(GetKey(olc::SHIFT).bReleased||GetKey(olc::A).bReleased)) {
bothKeysPressed=false;
std::cout<<"Both Keys released\n";
}
// 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);
DrawStringDecal({4, 4},std::to_string(distance));
// show time
auto disp_time = [](float t)
{
int min = t / 60.0f;
int sec = t - (min * 60.0f);
int milli = (t - (float)sec) * 1000.0f;
// need to change this out to a 'DrawString()' function instead
return std::to_string(min) + "." + std::to_string(sec) + ":" + std::to_string(milli);
};
// correct for the first '0' in the seconds timer
//if ()
//{
// // draw min + '0' + sec + milli
// DrawString(4, 16, disp_time(cur_lap_time));
//}
//else
//{
DrawString(4, 16, disp_time(cur_lap_time));
//}
// display last 5 lap times
int j = 30;
for (auto l : list_times)
{
DrawString(10, j, disp_time(l));
j += 10;
}
// debug code
//std::string numb1 = std::to_string(car_pos);
//DrawString(4, 26, numb1);
//std::string numb2 = std::to_string(track_dist);
//DrawString(4, 38, numb2);
Clear(olc::VERY_DARK_BLUE);
DrawRect({32,32},{32,32},(bothKeysPressed)?olc::YELLOW:olc::BLACK);
return true;
}
};
//--------------------------------------------------------------------------------------------------
int main()
{
std::cout<<(-265%50)<<"\n";
std::cout<<(-26%50)<<"\n";
Racer game;
if (game.Construct(1280, 720, 1, 1))
PressDetect game;
if (game.Construct(256, 240, 4, 4))
game.Start();
return 0;
}
//--------------------------------------------------------------------------------------------------
// END OF FILE
//--------------------------------------------------------------------------------------------------

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Loading…
Cancel
Save