terminal_racer/game.cpp
thatscringebro 11e7558feb lap times
2023-10-11 09:35:05 -04:00

227 lines
7.9 KiB
C++

#include "game.h"
#define DELAY 30000
Game::Game()
:max_x(1000), max_y(800), direction(0), window(sf::VideoMode(max_x, max_y), "ASCII RACER"),
racecar(400.0f, 30.0f, 1.7f) { // maxSpeed, acceleration, and steerSpeed values
if (!font.loadFromFile("cascaydia.otf")) {
std::cerr << "Failed to load font" << std::endl;
exit(1);
}
// Create a text object for displaying speed
speedText.setFont(font);
// Create a map text object and set its properties
mapText.setFont(font);
mapText.setCharacterSize(24);
mapText.setFillColor(sf::Color::White);
mapText.setPosition(0, 0);
timerText.setFont(font);
timerText.setCharacterSize(24);
timerText.setFillColor(sf::Color::White);
racecar.setPosition(1000, 80); // Set initial position for the racecar
racecar.setRotation(180);
// Initialize the times and quadrants data structure
timesAndQuadrants.push_back(std::make_pair(1, "00:00:00.000"));
}
void Game::run() {
sf::Clock clock;
// Create a view that will follow the racecar
view = sf::View(sf::FloatRect(0, 0, max_x, max_y));
view.setCenter(racecar.getX(), racecar.getY()); // Center the view on the racecar
window.setView(view);
while (window.isOpen()) {
float dt = clock.restart().asSeconds();
// Update game time
sf::Time gameTime = gameTimeClock.getElapsedTime();
int milis = static_cast<int>(gameTime.asMilliseconds());
int seconds = static_cast<int>(gameTime.asSeconds());
int minutes = seconds / 60;
seconds %= 60;
milis %= 1000;
// Use std::setw and std::setfill to format numbers as two digits
std::ostringstream timerStream;
timerStream << std::setw(2) << std::setfill('0') << minutes << ":"
<< std::setw(2) << std::setfill('0') << seconds << ":"
<< std::setw(2) << std::setfill('0') << milis;
std::string timerString = timerStream.str();
timerText.setString(timerString);
// Detect when the racecar changes quadrants and save the time
int currentQuadrant = determineQuadrant(racecar.getX(), racecar.getY());
if (currentQuadrant != timesAndQuadrants.back().first) {
timesAndQuadrants.push_back(std::make_pair(currentQuadrant, timerString));
}
determineLap(timerString);
sf::Event event;
while (window.pollEvent(event)) {
if (event.type == sf::Event::Closed) {
window.close();
}
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up)) {
if (racecar.getSpeed() < 0) {
racecar.brake(dt);
} else {
float newX = racecar.getX() + ((racecar.getSpeed() + 1.1) * dt * cos(racecar.getRotation()));
float newY = racecar.getY() + ((racecar.getSpeed() + 1.1) * dt * sin(racecar.getRotation()));
//std::cout << "New: " << newX << "," << newY << " Old: " << racecar.getX() << "," << racecar.getY() << std::endl;
if (!isTrackCollision(newX, newY)) {
racecar.accelerate(dt);
} else {
racecar.stop();
}
}
} else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down)) {
if (racecar.getSpeed() > 0) {
racecar.brake(dt);
} else {
float newX = racecar.getX() + ((racecar.getSpeed() + 1.1) * dt * cos(racecar.getRotation()));
float newY = racecar.getY() + ((racecar.getSpeed() + 1.1) * dt * sin(racecar.getRotation()));
//std::cout << "New: " << newX << "," << newY << " Old: " << racecar.getX() << "," << racecar.getY() << std::endl;
if (!isTrackCollision(newX, newY)) {
racecar.reverse(dt);
} else {
racecar.stop();
}
}
} else {
racecar.decelerate(dt);
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left)) {
racecar.steer(dt, -1.0f); // Steer left
} else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right)) {
racecar.steer(dt, 1.0f); // Steer right
}
racecar.update(dt);
speedText.setString(std::to_string(static_cast<int>(racecar.getSpeed())) + " km/h");
speedText.setCharacterSize(24);
speedText.setFillColor(sf::Color::Green);
speedText.setPosition(racecar.getX() - 475, racecar.getY() + 350);
if(racecar.getSpeed() < 0){
speedText.setFillColor(sf::Color::Blue);
}
if(racecar.getSpeed() >= 250){
speedText.setCharacterSize(27);
speedText.setFillColor(sf::Color::Yellow);
}
if(racecar.getSpeed() >= 360){
speedText.setCharacterSize(30);
speedText.setFillColor(sf::Color::Red);
}
timerText.setPosition(racecar.getX() - 80, racecar.getY() - 350);
// Update the view to follow the racecar
view.setCenter(racecar.getX(), racecar.getY());
window.setView(view);
window.clear();
mapText.setString(asciiMap);
window.draw(mapText);
window.draw(racecar.getDrawable());
window.draw(speedText);
window.draw(timerText);
displaySavedTimes();
window.display();
sf::sleep(sf::microseconds(DELAY));
}
}
bool Game::isTrackCollision(float x, float y) {
if (x <= 0) {
// return true;
} else if (y <= 0) {
// return true;
} else {
// int currX = (x / 13.85) - 1;
// int currY = (y / 27.88) - 1;
// char currentChar = asciiMap[currY * 194 + currX];
// //std::cout << x << ", " << y << std::endl;
// if (currentChar == '\\' || currentChar == '|' || currentChar == '/' || currentChar == '-' || currentChar == '_') {
// //return true;
// }
}
return false; // No collision with track or out of bounds
}
void Game::determineLap(std::string timerString) {
lapFinished = true;
int requiredOrder[] = {1,2,1,2,3,4,1};
if(timesAndQuadrants.size() >= 7) {
for (int i = 0; i < 7; i++) {
if (std::get<0>(timesAndQuadrants[i]) != requiredOrder[i])
lapFinished = false;
}
}
else {
lapFinished = false;
}
if (lapFinished) {
lapTimes.push_back(timerString);
timesAndQuadrants.clear();
timesAndQuadrants.push_back(std::make_pair(1, timerString));
}
}
int Game::determineQuadrant(float x, float y) {
if (y <= 460 && x <= 1150)
return 1;
if (y > 460 && x <= 1150)
return 2;
if (y > 460 && x > 1150)
return 3;
if (y <= 460 && x > 1150)
return 4;
return 0;
}
void Game::displaySavedTimes() {
// Display the saved times on the left side of the screen
int textY = 10; // Adjust the vertical position as needed
for (const auto& lapTime : lapTimes) {
std::string timeString = "Lap Time: " + lapTime;
sf::Text text;
text.setFont(font);
text.setCharacterSize(18);
text.setFillColor(sf::Color::White);
text.setPosition(racecar.getX() - 475, (racecar.getY() - 300) + textY);
text.setString(timeString);
window.draw(text);
textY += 30; // Adjust the spacing as needed
}
for (const auto& timeAndQuadrant : timesAndQuadrants) {
std::string timeString = "Quadrant " + std::to_string(timeAndQuadrant.first) + ": " + timeAndQuadrant.second;
sf::Text text;
text.setFont(font);
text.setCharacterSize(18);
text.setFillColor(sf::Color::White);
text.setPosition(racecar.getX() - 475, (racecar.getY() - 300) + textY);
text.setString(timeString);
window.draw(text);
textY += 30; // Adjust the spacing as needed
}
}