Fork Copy #include #include #include #include #include #include #include "Player.h" int main() { sf::VideoMode vm(1086, 679); sf::RenderWindow window(vm, "Highway Racer", sf::Style::Titlebar); // Load textures with absolute paths sf::Texture textureRoad; if (!textureRoad.loadFromFile("C:/scs/Project7/assets/imgs/background.png")) { std::cerr << "Error loading C:/scs/Project7/assets/imgs/background.png" << std::endl; return 1; } sf::Texture textureRoadStripe; if (!textureRoadStripe.loadFromFile("C:/scs/Project7/assets/imgs/roadStripe.png")) { std::cerr << "Error loading C:/scs/Project7/assets/imgs/roadStripe.png" << std::endl; return 1; } sf::Texture textureRock; if (!textureRock.loadFromFile("C:/scs/Project7/assets/imgs/rock.png")) { std::cerr << "Error loading C:/scs/Project7/assets/imgs/rock.png" << std::endl; return 1; } sf::Texture textureCars[8]; if (!textureCars[0].loadFromFile("C:/scs/Project7/assets/imgs/carOne.png")) { std::cerr << "Error loading C:/scs/Project7/assets/imgs/carOne.png" << std::endl; return 1; } if (!textureCars[1].loadFromFile("C:/scs/Project7/assets/imgs/carTwo.png")) { std::cerr << "Error loading C:/scs/Project7/assets/imgs/carTwo.png" << std::endl; return 1; } if (!textureCars[2].loadFromFile("C:/scs/Project7/assets/imgs/carThree.png")) { std::cerr << "Error loading C:/scs/Project7/assets/imgs/carThree.png" << std::endl; return 1; } if (!textureCars[3].loadFromFile("C:/scs/Project7/assets/imgs/carFour.png")) { std::cerr << "Error loading C:/scs/Project7/assets/imgs/carFour.png" << std::endl; return 1; } if (!textureCars[4].loadFromFile("C:/scs/Project7/assets/imgs/carFive.png")) { std::cerr << "Error loading C:/scs/Project7/assets/imgs/carFive.png" << std::endl; return 1; } if (!textureCars[5].loadFromFile("C:/scs/Project7/assets/imgs/carSix.png")) { std::cerr << "Error loading C:/scs/Project7/assets/imgs/carSix.png" << std::endl; return 1; } if (!textureCars[6].loadFromFile("C:/scs/Project7/assets/imgs/carSeven.png")) { std::cerr << "Error loading C:/scs/Project7/assets/imgs/carSeven.png" << std::endl; return 1; } if (!textureCars[7].loadFromFile("C:/scs/Project7/assets/imgs/carEight.png")) { std::cerr << "Error loading C:/scs/Project7/assets/imgs/carEight.png" << std::endl; return 1; } sf::Texture textureTree; if (!textureTree.loadFromFile("C:/scs/Project7/assets/imgs/tree.png")) { std::cerr << "Error loading C:/scs/Project7/assets/imgs/tree.png" << std::endl; return 1; } sf::Texture textureSpeedometer; if (!textureSpeedometer.loadFromFile("C:/scs/Project7/assets/imgs/speedometer.png")) { std::cerr << "Error loading C:/scs/Project7/assets/imgs/speedometer.png" << std::endl; return 1; } // Set the road up sf::Sprite spriteRoad; spriteRoad.setTexture(textureRoad); sf::Sprite spriteRoadStripe[5]; for (int i = 0; i < 5; i++) { spriteRoadStripe[i].setTexture(textureRoadStripe); spriteRoadStripe[i].setPosition(525, i * 150); } // Environment details // Rocks const int NUMBEROFROCKS = 2; sf::Sprite spriteRock[NUMBEROFROCKS]; srand(static_cast(time(nullptr))); for (int i = 0; i < NUMBEROFROCKS; i++) { spriteRock[i].setTexture(textureRock); if (i == 0) { spriteRock[i].setPosition((rand() % 280), (rand() % 1000) - 1500); } else { spriteRock[i].setPosition((rand() % 770) + 710, (rand() % 1000) - 900); } } // Trees const int NUMBEROFTREES = 20; sf::Sprite spriteTree[NUMBEROFTREES]; for (int i = 0; i < NUMBEROFTREES; i++) { spriteTree[i].setTexture(textureTree); if (i % 2 == 0) { spriteTree[i].setPosition((rand() % 230), (rand() % 1000) - 500); } else { spriteTree[i].setPosition((rand() % 810) + 780, (rand() % 1000) - 500); } spriteTree[i].setOrigin(94, 102); spriteTree[i].setRotation((rand() % 360) + 1); } // Set player car up Player player; player.setTexture(textureCars[0]); player.setPlayerPosition(575, 500); player.setCarState(Player::CarState::STOPPED); // Set up the NPC car sf::Sprite spriteNpc; int textureChoice = rand() % 8; spriteNpc.setTexture(textureCars[textureChoice]); spriteNpc.setPosition((rand() % 345) + 344, (rand() % 1000) - 2000); // Set up the HUD sf::Sprite spriteSpeedometer; spriteSpeedometer.setTexture(textureSpeedometer); spriteSpeedometer.setPosition(840, 520); // Speedometer needle sf::ConvexShape dometerNeedle(3); dometerNeedle.setPoint(0, sf::Vector2f(0, 10)); dometerNeedle.setPoint(1, sf::Vector2f(5, 80)); dometerNeedle.setPoint(2, sf::Vector2f(-5, 80)); dometerNeedle.setPosition(915, 593); dometerNeedle.setFillColor(sf::Color::Red); sf::FloatRect dometerBounds = dometerNeedle.getLocalBounds(); dometerNeedle.setOrigin(dometerBounds.left + dometerBounds.width - 5, dometerBounds.top + dometerBounds.height - 5); dometerNeedle.setRotation(225); // Sounds sf::Music introMusic; if (!introMusic.openFromFile("C:/scs/Project7/assets/sounds/Intro.wav")) { std::cerr << "Error loading C:/scs/Project7/assets/sounds/Intro.wav" << std::endl; return 1; } introMusic.setLoop(true); introMusic.play(); sf::SoundBuffer crashSoundBuffer; if (!crashSoundBuffer.loadFromFile("C:/scs/Project7/assets/sounds/Crash.wav")) { std::cerr << "Error loading C:/scs/Project7/assets/sounds/Crash.wav" << std::endl; return 1; } sf::Sound crashSound; crashSound.setBuffer(crashSoundBuffer); sf::SoundBuffer carRevBuffer; if (!carRevBuffer.loadFromFile("C:/scs/Project7/assets/sounds/CarRev.wav")) { std::cerr << "Error loading C:/scs/Project7/assets/sounds/CarRev.wav" << std::endl; return 1; } sf::Sound carRevSound; carRevSound.setBuffer(carRevBuffer); sf::SoundBuffer carRevReverseBuffer; if (!carRevReverseBuffer.loadFromFile("C:/scs/Project7/assets/sounds/CarRevReverse.wav")) { std::cerr << "Error loading C:/scs/Project7/assets/sounds/CarRevReverse.wav" << std::endl; return 1; } sf::Sound carRevReverseSound; carRevReverseSound.setBuffer(carRevReverseBuffer); sf::SoundBuffer carIdleBuffer; if (!carIdleBuffer.loadFromFile("C:/scs/Project7/assets/sounds/CarIdle.wav")) { std::cerr << "Error loading C:/scs/Project7/assets/sounds/CarIdle.wav" << std::endl; return 1; } sf::Sound carIdleSound; carIdleSound.setBuffer(carIdleBuffer); carIdleSound.setLoop(true); enum class GameState { START, RUNNING, PAUSED, OVER }; GameState gameState = GameState::START; const float MAXGAMESPEED = 1100.0f; float gameSpeed = 0.0f; sf::Font font; if (!font.loadFromFile("C:/scs/Project7/assets/fonts/Kinder-Child.ttf")) { std::cerr << "Error loading C:/scs/Project7/assets/fonts/Kinder-Child.ttf" << std::endl; return 1; } sf::Text message; message.setFont(font); message.setCharacterSize(50); message.setFillColor(sf::Color::White); sf::FloatRect messageRect = message.getLocalBounds(); message.setOrigin(messageRect.left + messageRect.width / 2.0f, messageRect.top + messageRect.height / 2.0f); message.setPosition(sf::VideoMode::getDesktopMode().width - (sf::VideoMode::getDesktopMode().width / 1.3f), sf::VideoMode::getDesktopMode().height - (sf::VideoMode::getDesktopMode().height / 1.4f)); message.setString("Highway Racer"); sf::Text score; score.setFont(font); score.setCharacterSize(30); score.setFillColor(sf::Color::White); score.setPosition(20, 20); sf::Clock clock; try { while (window.isOpen()) { sf::Event event; while (window.pollEvent(event)) { if (event.type == sf::Event::Closed) { window.close(); } else if (event.type == sf::Event::KeyPressed) { if (event.key.code == sf::Keyboard::Return) { if (gameState == GameState::START || gameState == GameState::PAUSED) { gameState = GameState::RUNNING; if (carRevSound.getStatus() == sf::SoundSource::Status::Paused) { carRevSound.play(); } else if (carRevReverseSound.getStatus() == sf::SoundSource::Status::Paused) { carRevReverseSound.play(); } introMusic.stop(); } else if (gameState == GameState::RUNNING) { gameState = GameState::PAUSED; message.setString("Paused"); message.setPosition(sf::VideoMode::getDesktopMode().width - (sf::VideoMode::getDesktopMode().width / 1.45f), sf::VideoMode::getDesktopMode().height - (sf::VideoMode::getDesktopMode().height / 1.45f)); if (carRevSound.getStatus() == sf::SoundSource::Status::Playing) { carRevSound.pause(); } else if (carRevReverseSound.getStatus() == sf::SoundSource::Status::Playing) { carRevReverseSound.pause(); } } else if (gameState == GameState::OVER) { // Reset the game player.setPlayerPosition(575, 500); spriteNpc.setPosition((rand() % 345) + 344, (rand() % 1000) - 2000); gameSpeed = 0.0f; dometerNeedle.setRotation(225); player.setScore(0); introMusic.play(); gameState = GameState::START; message.setString("Highway Racer"); message.setPosition(sf::VideoMode::getDesktopMode().width - (sf::VideoMode::getDesktopMode().width / 1.3f), sf::VideoMode::getDesktopMode().height - (sf::VideoMode::getDesktopMode().height / 1.4f)); } } } } if (sf::Keyboard::isKeyPressed(sf::Keyboard::Escape)) { window.close(); } else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Space) && gameState == GameState::RUNNING) { if (!(player.getCarState() == Player::CarState::ACCELERATE)) { player.setCarState(Player::CarState::ACCELERATE); if (carRevReverseSound.getStatus() == sf::SoundSource::Status::Playing) { carRevReverseSound.stop(); } else if (carIdleSound.getStatus() == sf::SoundSource::Status::Playing) { carIdleSound.stop(); } if (gameSpeed > 50) { carRevSound.setPlayingOffset(sf::seconds(10)); } else { carRevSound.setPlayingOffset(sf::seconds(0)); } carRevSound.play(); } if (static_cast(carRevSound.getPlayingOffset().asSeconds()) == 30) { carRevSound.setPlayingOffset(sf::seconds(20)); } if (gameSpeed < MAXGAMESPEED) { gameSpeed += 0.55f; } } else if (!(sf::Keyboard::isKeyPressed(sf::Keyboard::Space)) && gameState == GameState::RUNNING) { if (player.getCarState() == Player::CarState::ACCELERATE) { player.setCarState(Player::CarState::DECELERATE); if (carRevSound.getStatus() == sf::SoundSource::Status::Playing) { carRevSound.stop(); } carRevReverseSound.play(); } if (gameSpeed > 0.0f) { gameSpeed -= 0.38f; } } if (gameSpeed <= 0.0f) { player.setCarState(Player::CarState::STOPPED); if (carRevReverseSound.getStatus() == sf::SoundSource::Status::Playing) { carRevReverseSound.stop(); } if (carIdleSound.getStatus() == sf::SoundSource::Status::Stopped) { carIdleSound.play(); } } // Control player car if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left) && gameState == GameState::RUNNING) { if (player.getPlayerPosition().x > 370) { player.setPlayerPosition(player.getPlayerPosition().x - 1.2f, player.getPlayerPosition().y); } } else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right) && gameState == GameState::RUNNING) { if (player.getPlayerPosition().x < 633) { player.setPlayerPosition(player.getPlayerPosition().x + 1.2f, player.getPlayerPosition().y); } } // Update the scene sf::Time dt = clock.restart(); std::stringstream ss; ss << "Score: " << player.getScore(); score.setString(ss.str()); if (gameState == GameState::RUNNING) { for (int i = 0; i < 5; i++) { spriteRoadStripe[i].setPosition(spriteRoadStripe[i].getPosition().x, (spriteRoadStripe[i].getPosition().y + (gameSpeed * dt.asSeconds()))); if (spriteRoadStripe[i].getPosition().y > 679) { spriteRoadStripe[i].setPosition(spriteRoadStripe[i].getPosition().x, -70); } } for (int i = 0; i < NUMBEROFROCKS; i++) { spriteRock[i].setPosition(spriteRock[i].getPosition().x, (spriteRock[i].getPosition().y + (gameSpeed / 1.5f * dt.asSeconds()))); if (spriteRock[i].getPosition().y > 679) { if (i == 0) { spriteRock[i].setPosition((rand() % 280), (rand() % 1000) - 1000); } else { spriteRock[i].setPosition((rand() % 810) + 780, (rand() % 1000) - 500); } } } for (int i = 0; i < NUMBEROFTREES; i++) { spriteTree[i].setPosition(spriteTree[i].getPosition().x, (spriteTree[i].getPosition().y + (gameSpeed / 1.5f * dt.asSeconds()))); if (spriteTree[i].getPosition().y > 800) { if (i % 2 == 0) { spriteTree[i].setPosition((rand() % 230), (rand() % 1000) - 200); } else { spriteTree[i].setPosition((rand() % 810) + 780, (rand() % 1000) - 200); } } } if (player.getCarState() == Player::CarState::ACCELERATE) { spriteNpc.setPosition(spriteNpc.getPosition().x, (spriteNpc.getPosition().y + (gameSpeed * dt.asSeconds()))); if ((dometerNeedle.getRotation() >= 0 && dometerNeedle.getRotation() <= 120) || (dometerNeedle.getRotation() <= 360 && dometerNeedle.getRotation() >= 190)) { dometerNeedle.setRotation(dometerNeedle.getRotation() + (10 * dt.asSeconds())); } } else if (player.getCarState() == Player::CarState::DECELERATE) { if (spriteNpc.getPosition().y > -1000) { spriteNpc.setPosition(spriteNpc.getPosition().x, (spriteNpc.getPosition().y - (800 * dt.asSeconds()))); } if ((dometerNeedle.getRotation() >= 0 && dometerNeedle.getRotation() <= 121) || (dometerNeedle.getRotation() <= 360 && dometerNeedle.getRotation() >= 225)) { dometerNeedle.setRotation(dometerNeedle.getRotation() - (47 * dt.asSeconds())); } } if (spriteNpc.getPosition().y > 800) { spriteNpc.setPosition((rand() % 345) + 344, (rand() % 1000) - 2000); int textureChoice = rand() % 8; spriteNpc.setTexture(textureCars[textureChoice]); player.setScore(player.getScore() + 1); } sf::FloatRect playerBounds = player.getSprite().getGlobalBounds(); sf::FloatRect playerModBounds = sf::FloatRect(playerBounds.left + 10, playerBounds.top + 10, playerBounds.width - 10, playerBounds.height - 10); if (spriteNpc.getGlobalBounds().intersects(playerModBounds)) { crashSound.play(); if (carRevSound.getStatus() == sf::SoundSource::Status::Playing) { carRevSound.stop(); } gameState = GameState::OVER; message.setString("Game Over!"); message.setPosition(sf::VideoMode::getDesktopMode().width - (sf::VideoMode::getDesktopMode().width / 1.4f), sf::VideoMode::getDesktopMode().height - (sf::VideoMode::getDesktopMode().height / 1.45f)); } } // Draw the scene window.clear(sf::Color::Black); // Thêm để tránh cửa sổ trắng window.draw(spriteRoad); for (int i = 0; i < 5; i++) { window.draw(spriteRoadStripe[i]); } window.draw(player.getSprite()); for (int i = 0; i < NUMBEROFROCKS; i++) { window.draw(spriteRock[i]); } for (int i = 0; i < NUMBEROFTREES; i++) { window.draw(spriteTree[i]); } window.draw(spriteSpeedometer); window.draw(dometerNeedle); window.draw(spriteNpc); window.draw(score); if (gameState == GameState::START || gameState == GameState::PAUSED || gameState == GameState::OVER) { window.draw(message); } window.display(); } } catch (const std::exception& e) { std::cerr << "Caught exception: " << e.what() << std::endl; window.close(); return 1; } window.close(); // Thêm để dọn dẹp đúng return 0; }