Fork Copy #include #include #include #include #include #include #include #include // Kích thước màn hình const int WINDOW_WIDTH = 800; const int WINDOW_HEIGHT = 600; // Tốc độ cơ bản const float BASE_SPEED = 5.0f; // Lớp xe người chơi class Car { public: sf::Sprite sprite; float speed = 0.0f; float maxSpeed = 10.0f; float acceleration = 0.2f; float traction = 1.0f; // Độ bám đường (1.0 = bình thường) bool turboActive = false; float turboBoost = 2.0f; // Tăng tốc turbo sf::Clock turboClock; float turboDuration = 3.0f; // Thời gian turbo (giây) float turboCooldown = 10.0f; // Thời gian cooldown (giây) sf::Clock cooldownClock; bool inCooldown = false; Car(sf::Texture& texture) { sprite.setTexture(texture); sprite.setPosition(WINDOW_WIDTH / 2 - sprite.getGlobalBounds().width / 2, WINDOW_HEIGHT - 100); } void update(float deltaTime, float terrainFactor, float weatherFactor) { traction = weatherFactor; // Thời tiết ảnh hưởng độ bám // Xử lý turbo if (turboActive) { speed += acceleration * turboBoost * terrainFactor; if (turboClock.getElapsedTime().asSeconds() > turboDuration) { turboActive = false; inCooldown = true; cooldownClock.restart(); } } else { speed += acceleration * terrainFactor; } if (speed > maxSpeed * terrainFactor) speed = maxSpeed * terrainFactor; // Di chuyển xe if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left)) { sprite.move(-speed * traction * deltaTime, 0); } if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right)) { sprite.move(speed * traction * deltaTime, 0); } if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up)) { sprite.move(0, -speed * deltaTime); } if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down)) { sprite.move(0, speed * deltaTime); } // Giới hạn xe trong màn hình if (sprite.getPosition().x < 0) sprite.setPosition(0, sprite.getPosition().y); if (sprite.getPosition().x > WINDOW_WIDTH - sprite.getGlobalBounds().width) sprite.setPosition(WINDOW_WIDTH - sprite.getGlobalBounds().width, sprite.getPosition().y); if (sprite.getPosition().y < 0) sprite.setPosition(sprite.getPosition().x, 0); if (sprite.getPosition().y > WINDOW_HEIGHT - sprite.getGlobalBounds().height) sprite.setPosition(sprite.getPosition().x, WINDOW_HEIGHT - sprite.getGlobalBounds().height); // Kiểm tra cooldown turbo if (inCooldown && cooldownClock.getElapsedTime().asSeconds() > turboCooldown) { inCooldown = false; } } void activateTurbo() { if (!turboActive && !inCooldown) { turboActive = true; turboClock.restart(); } } }; // Lớp chướng ngại vật class Obstacle { public: sf::Sprite sprite; float speed = 5.0f; Obstacle(sf::Texture& texture, float posX) { sprite.setTexture(texture); sprite.setPosition(posX, -sprite.getGlobalBounds().height); } void update(float deltaTime) { sprite.move(0, speed * deltaTime); } bool isOffScreen() { return sprite.getPosition().y > WINDOW_HEIGHT; } }; // Enum cho địa hình và thời tiết enum TerrainType { ROAD, DIRT, SAND }; enum WeatherType { SUNNY, RAINY, SNOWY }; int main() { // Khởi tạo random std::srand(std::time(nullptr)); // Tạo cửa sổ sf::RenderWindow window(sf::VideoMode(WINDOW_WIDTH, WINDOW_HEIGHT), "Racing Game SFML"); window.setFramerateLimit(60); // Tải texture (thay bằng đường dẫn thực tế của bạn) sf::Texture carTexture; if (!carTexture.loadFromFile("car.png")) { // Tải ảnh xe std::cerr << "Không tải được car.png" << std::endl; return 1; } sf::Texture obstacleTexture; if (!obstacleTexture.loadFromFile("obstacle.png")) { // Tải ảnh chướng ngại vật std::cerr << "Không tải được obstacle.png" << std::endl; return 1; } // Font cho text sf::Font font; if (!font.loadFromFile("arial.ttf")) { // Tải font (thay bằng font có sẵn) std::cerr << "Không tải được font" << std::endl; return 1; } // Xe người chơi Car car(carTexture); // Danh sách chướng ngại vật std::vector obstacles; // Thời gian để sinh chướng ngại vật sf::Clock obstacleClock; float obstacleSpawnTime = 1.0f; // Giây // Điểm số int score = 0; sf::Text scoreText; scoreText.setFont(font); scoreText.setCharacterSize(24); scoreText.setFillColor(sf::Color::White); scoreText.setPosition(10, 10); // Địa hình và thời tiết TerrainType currentTerrain = ROAD; WeatherType currentWeather = SUNNY; sf::Clock terrainClock; sf::Clock weatherClock; float terrainChangeTime = 10.0f; // Thay địa hình mỗi 10 giây float weatherChangeTime = 15.0f; // Thay thời tiết mỗi 15 giây // Background (đường) sf::RectangleShape background(sf::Vector2f(WINDOW_WIDTH, WINDOW_HEIGHT)); background.setFillColor(sf::Color::Green); // Màu nền cơ bản // Vòng lặp chính sf::Clock clock; while (window.isOpen()) { float deltaTime = clock.restart().asSeconds() * 60.0f; // Delta time cho tốc độ ổn định // Xử lý sự kiện sf::Event event; while (window.pollEvent(event)) { if (event.type == sf::Event::Closed) window.close(); if (event.type == sf::Event::KeyPressed) { if (event.key.code == sf::Keyboard::Space) { car.activateTurbo(); } } } // Thay đổi địa hình ngẫu nhiên if (terrainClock.getElapsedTime().asSeconds() > terrainChangeTime) { currentTerrain = static_cast(std::rand() % 3); terrainClock.restart(); } // Thay đổi thời tiết ngẫu nhiên if (weatherClock.getElapsedTime().asSeconds() > weatherChangeTime) { currentWeather = static_cast(std::rand() % 3); weatherClock.restart(); } // Xác định yếu tố địa hình float terrainFactor = 1.0f; switch (currentTerrain) { case ROAD: terrainFactor = 1.0f; break; // Tốc độ bình thường case DIRT: terrainFactor = 0.8f; break; // Chậm hơn case SAND: terrainFactor = 0.6f; break; // Chậm nhất } // Xác định yếu tố thời tiết (ảnh hưởng độ bám) float weatherFactor = 1.0f; switch (currentWeather) { case SUNNY: weatherFactor = 1.0f; break; case RAINY: weatherFactor = 0.7f; break; // Trượt hơn case SNOWY: weatherFactor = 0.5f; break; // Trượt nhiều } // Cập nhật xe car.update(deltaTime, terrainFactor, weatherFactor); // Sinh chướng ngại vật if (obstacleClock.getElapsedTime().asSeconds() > obstacleSpawnTime) { float posX = std::rand() % (WINDOW_WIDTH - 50); obstacles.push_back(Obstacle(obstacleTexture, posX)); obstacleClock.restart(); } // Cập nhật chướng ngại vật for (auto& obs : obstacles) { obs.update(deltaTime); } // Xóa chướng ngại vật ra khỏi màn hình và tăng điểm for (auto it = obstacles.begin(); it != obstacles.end(); ) { if (it->isOffScreen()) { score += 10; // Tăng điểm khi vượt qua it = obstacles.erase(it); } else { ++it; } } // Kiểm tra va chạm bool gameOver = false; for (const auto& obs : obstacles) { if (car.sprite.getGlobalBounds().intersects(obs.sprite.getGlobalBounds())) { gameOver = true; break; } } if (gameOver) { std::cout << "Game Over! Điểm: " << score << std::endl; window.close(); } // Cập nhật text điểm scoreText.setString("Điểm: " + std::to_string(score) + "\nĐịa hình: " + (currentTerrain == ROAD ? "Đường" : currentTerrain == DIRT ? "Đất" : "Cát") + "\nThời tiết: " + (currentWeather == SUNNY ? "Nắng" : currentWeather == RAINY ? "Mưa" : "Tuyết") + "\nTurbo: " + (car.turboActive ? "Active" : car.inCooldown ? "Cooldown" : "Ready")); // Vẽ window.clear(); window.draw(background); window.draw(car.sprite); for (const auto& obs : obstacles) { window.draw(obs.sprite); } window.draw(scoreText); window.display(); // Tăng điểm theo thời gian score += static_cast(deltaTime / 60.0f); } return 0; }