#include #include #include "../headers/Plansza.h" #include "../headers/ObjectItem.hpp" Plansza::Plansza(unsigned int windowHeight, unsigned int windowWidth, sf::RenderWindow *mainWindow, const sf::Texture& playerTexture, const sf::Texture& playerBulletTexture, const sf::Texture& playerRocketTexture) : background("../assets/img/background/background.png", 2.0f), ship(static_cast(mainWindow->getSize().x) / 2, static_cast(mainWindow->getSize().y) - 100, playerTexture, playerBulletTexture, playerRocketTexture) { window = mainWindow; size.height = static_cast(windowHeight); size.width = static_cast(windowWidth); ship.setMovingSpeed(8); ship.setFirerate(200); audioManager.loadBackgroundMusic("../assets/music/background.ogg"); audioManager.playBackgroundMusic(); audioManager.loadSoundEffect("shoot", "../assets/sounds/shoot.ogg"); audioManager.loadSoundEffect("shoot_alt", "../assets/sounds/shoot_alt.ogg"); audioManager.loadSoundEffect("fail", "../assets/sounds/fail.mp3"); meteorTexture1.loadFromFile("../assets/img/meteors/meteor-1.png"); meteorTexture2.loadFromFile("../assets/img/meteors/meteor-2.png"); // Ładowanie tekstur wrogów if (!enemyTexture.loadFromFile("../assets/img/enemy/enemy.png")) { std::cerr << "Failed to load enemy texture!" << std::endl; exit(-1); } if (!advancedEnemyTexture.loadFromFile("../assets/img/enemy/advanced_enemy.png")) { std::cerr << "Failed to load advanced enemy texture!" << std::endl; exit(-1); } spawnClock.restart(); } void Plansza::update() { // tło background.update(); background.draw(*window); // poruszanie się statkiem if(sf::Keyboard::isKeyPressed(sf::Keyboard::A)) { if(ship.getPosition().x > 50) { ship.moveLeft(); } } if (sf::Keyboard::isKeyPressed(sf::Keyboard::W)) { if(ship.getPosition().y > 80) { ship.moveUp(); } } if (sf::Keyboard::isKeyPressed(sf::Keyboard::S)) { if(ship.getPosition().y < 720) { ship.moveDown(); } } if (sf::Keyboard::isKeyPressed(sf::Keyboard::D)) { if(ship.getPosition().x < 550) { ship.moveRight(); } } // TODO: Przenieść obiekt dźwięku wewnątrz klasy Bullet if (sf::Mouse::isButtonPressed(sf::Mouse::Left)) { ship.shoot(); audioManager.playSoundEffect("shoot", 70.f); // Odtworzenie dźwięku wystrzału } if (sf::Mouse::isButtonPressed(sf::Mouse::Right)) { ship.alternate_shoot(); audioManager.playSoundEffect("shoot_alt", 70.f); // Odtworzenie dźwięku dla alternatywnego strzału } // generowanie nowego meteoru spawn_meteor(); spawn_enemy(); spawn_advanced_enemy(); // utrzymanie meteorów i pocisków w ruchu for (auto& meteor : getMeteors()) { meteor.update(); window->draw(meteor.getSprite()); } for (auto& bullet : ship.getBullets()) { bullet.update(); window->draw(bullet.getSprite()); } for (auto& rocket : ship.getRockets()) { rocket.update(); window->draw(rocket.getSprite()); } // Sprawdzenie czy meteory i pociski są poza granicami ekranu update_meteors(); ship.updateBullets(); window->draw(ship.getSprite()); // trochę dziwny sposób ale jednak działa for (auto& meteor : getMeteors()) { if(ship.getSprite().getGlobalBounds().intersects(meteor.getSprite().getGlobalBounds())) { std::cout << "You lost the game!\n"; sf::RenderWindow errorWindow(sf::VideoMode(350, 200), "The end"); sf::Font font; if (!font.loadFromFile("../assets/fonts/arial.ttf")) { std::cerr << "Error loading font\n"; exit(-500); } sf::Text text("Your ship is destroyed!", font, 24); text.setFillColor(sf::Color::Red); text.setPosition(50, 80); // zatrzymanie muzyki i odtworzenie dźwięku przegranej audioManager.playSoundEffect("fail", 70.f); audioManager.stopBackgroundMusic(); sf::Event event{}; while (errorWindow.isOpen()) { while (errorWindow.pollEvent(event)) { if (event.type == sf::Event::Closed || sf::Keyboard::isKeyPressed(sf::Keyboard::Escape)) { errorWindow.close(); window->close(); exit(-2); } } errorWindow.clear(); errorWindow.draw(text); errorWindow.display(); } } } if (!ship.isAlive()) { std::cout << "Game Over! Player is dead." << std::endl; std::cout << "You lost the game!\n"; sf::RenderWindow errorWindow(sf::VideoMode(350, 200), "The end"); sf::Font font; if (!font.loadFromFile("../assets/fonts/arial.ttf")) { std::cerr << "Error loading font\n"; exit(-500); } sf::Text text("Your ship is destroyed!", font, 24); text.setFillColor(sf::Color::Red); text.setPosition(50, 80); // zatrzymanie muzyki i odtworzenie dźwięku przegranej audioManager.playSoundEffect("fail", 70.f); audioManager.stopBackgroundMusic(); sf::Event event{}; while (errorWindow.isOpen()) { while (errorWindow.pollEvent(event)) { if (event.type == sf::Event::Closed || sf::Keyboard::isKeyPressed(sf::Keyboard::Escape)) { errorWindow.close(); window->close(); exit(-2); } } errorWindow.clear(); errorWindow.draw(text); errorWindow.display(); } } for (auto meteorIt = getMeteors().begin(); meteorIt != getMeteors().end(); ) { bool meteorHit = false; for (auto rocketIt = ship.getBullets().begin(); rocketIt != ship.getBullets().end(); ) { if (meteorIt->getSprite().getGlobalBounds().intersects(rocketIt->getSprite().getGlobalBounds())) { ship.getBullets().erase(rocketIt); meteorIt = getMeteors().erase(meteorIt); meteorHit = true; break; } else { ++rocketIt; } } if (!meteorHit) { ++meteorIt; } } for (auto meteorIt = getMeteors().begin(); meteorIt != getMeteors().end(); ) { bool meteorHit = false; for (auto rocketIt = ship.getRockets().begin(); rocketIt != ship.getRockets().end(); ) { if (meteorIt->getSprite().getGlobalBounds().intersects(rocketIt->getSprite().getGlobalBounds())) { ship.getRockets().erase(rocketIt); meteorIt = getMeteors().erase(meteorIt); meteorHit = true; break; } else { ++rocketIt; } } if (!meteorHit) { ++meteorIt; } } // Ruch i render przeciwnika for (auto it = enemies.begin(); it != enemies.end();) { it->update(); // Aktualizacja kierunku i ruchu it->shoot(); window->draw(it->getSprite()); // Usunięcie martwych przeciwników if (!it->isAlive()) { it = enemies.erase(it); } else { ++it; } } for (auto it = AEnemies.begin(); it != AEnemies.end();) { it->update(); // Ruch zaawansowanego przeciwnika it->shoot(); // Strzał przeciwnika window->draw(it->getSprite()); // Rysowanie na ekranie if (!it->isAlive()) { std::cout << "Advanced Enemy has been eliminated." << std::endl; it = AEnemies.erase(it); // Usunięcie martwych przeciwników } else { ++it; } } // std::cout << "Current AEnemies size: " << AEnemies.size() << std::endl; // Obsługa pocisków zaawansowanych przeciwników for (auto& aEnemy : AEnemies) { for (auto it = aEnemy.getBullets().begin(); it != aEnemy.getBullets().end();) { if (ship.getSprite().getGlobalBounds().intersects(it->getSprite().getGlobalBounds())) { ship.takeDamage(); // Zadanie obrażeń graczowi it = aEnemy.getBullets().erase(it); // Usuwanie pocisku po trafieniu } else { ++it; } } } for (auto advancedIt = AEnemies.begin(); advancedIt != AEnemies.end();) { bool hit = false; for (auto bulletIt = ship.getBullets().begin(); bulletIt != ship.getBullets().end();) { if (advancedIt->getSprite().getGlobalBounds().intersects(bulletIt->getSprite().getGlobalBounds())) { bulletIt = ship.getBullets().erase(bulletIt); advancedIt->takeDamage(); hit = true; break; } else { ++bulletIt; } } if (hit && !advancedIt->isAlive()) { advancedIt = AEnemies.erase(advancedIt); // Usunięcie przeciwnika AdvancedEnemy } else { ++advancedIt; } } for (auto& advancedEnemy : AEnemies) { advancedEnemy.updateBullets(); // Obsługuje pociski zaawansowanych przeciwników for (auto& bullet : advancedEnemy.getBullets()) { bullet.update(); window->draw(bullet.getSprite()); } } for (auto& enemy : enemies) { for (auto it = enemy.getBullets().begin(); it != enemy.getBullets().end();) { if (ship.getSprite().getGlobalBounds().intersects(it->getSprite().getGlobalBounds())) { // Kolizja wykryta std::cout << "Player hit by enemy bullet!\n"; ship.takeDamage(); // Usuwanie pocisku it = enemy.getBullets().erase(it); } else { ++it; // Brak kolizji, przechodzimy do kolejnego pocisku } } } for (auto& enemy : enemies) { enemy.shoot(); enemy.updateBullets(); for (auto& bullet : enemy.getBullets()) { bullet.update(); window->draw(bullet.getSprite()); } } // Usuwanie pocisków, które są poza ekranem for (auto enemyIt = enemies.begin(); enemyIt != enemies.end(); ) { for (auto bulletIt = enemyIt->getBullets().begin(); bulletIt != enemyIt->getBullets().end();) { if (bulletIt->isOutOfBounds()) { bulletIt = enemyIt->getBullets().erase(bulletIt); // Usuwamy pocisk, który wyszedł poza ekran } else { ++bulletIt; } } ++enemyIt; } // Kolizje między pociskami gracza a przeciwnikami for (auto enemyIt = enemies.begin(); enemyIt != enemies.end();) { bool hit = false; for (auto bulletIt = ship.getBullets().begin(); bulletIt != ship.getBullets().end();) { if (enemyIt->getSprite().getGlobalBounds().intersects(bulletIt->getSprite().getGlobalBounds())) { bulletIt = ship.getBullets().erase(bulletIt); enemyIt->takeDamage(); hit = true; break; } else { ++bulletIt; } } if (hit && !enemyIt->isAlive()) { enemyIt = enemies.erase(enemyIt); } else { ++enemyIt; } } //oblsuga dla rakiety for (auto enemyIt = enemies.begin(); enemyIt != enemies.end();) { bool hit = false; for (auto rocketIt = ship.getRockets().begin(); rocketIt != ship.getRockets().end();) { if (enemyIt->getSprite().getGlobalBounds().intersects(rocketIt->getSprite().getGlobalBounds())) { rocketIt = ship.getRockets().erase(rocketIt); enemyIt->takeDamage(); hit = true; break; } else { ++rocketIt; } } if (hit && !enemyIt->isAlive()) { enemyIt = enemies.erase(enemyIt); } else { ++enemyIt; } } for (auto advancedIt = AEnemies.begin(); advancedIt != AEnemies.end();) { bool hit = false; for (auto rocketIt = ship.getRockets().begin(); rocketIt != ship.getRockets().end();) { if (advancedIt->getSprite().getGlobalBounds().intersects(rocketIt->getSprite().getGlobalBounds())) { rocketIt = ship.getRockets().erase(rocketIt); advancedIt->takeDamage(); hit = true; break; } else { ++rocketIt; } } if (hit && !advancedIt->isAlive()) { advancedIt = AEnemies.erase(advancedIt); } else { ++advancedIt; } } } // Meteor-related niżej void Plansza::spawn_meteor() { if (spawnClock.getElapsedTime().asSeconds() > rand() % 10 + 1) { // randomowy spawn meteorytów od 10 do 1 sekundy if (meteors.size() < 5) { // jeśli jest mniej niż 5 meteorów na planszy if(rand() % 2 == 1) { meteors.emplace_back(RandomNumberGenerator::getRandomNumber(50,499), -100, meteorTexture2); } else { meteors.emplace_back(RandomNumberGenerator::getRandomNumber(50,499), -100, meteorTexture1); } } spawnClock.restart(); } } void Plansza::update_meteors() { // usuwanie meteorów które wyleciały poza ekran for (auto& meteor : meteors) { if(meteor.getStatus()) { meteors.erase(meteors.begin()); } } } void Plansza::spawn_enemy() { if (enemySpawnClock.getElapsedTime().asSeconds() >= 6) { // Spawn co 10 sekund int spawnX = RandomNumberGenerator::getRandomNumber(50, size.width - 50); enemies.emplace_back(spawnX, -50, enemyTexture); enemySpawnClock.restart(); } } void Plansza::spawn_advanced_enemy() { if (AenemySpawnClock.getElapsedTime().asSeconds() >= 5) { // Spawn co 10 sekund int spawnX = RandomNumberGenerator::getRandomNumber(50, size.width - 50); AEnemies.emplace_back(spawnX, 50, advancedEnemyTexture, enemyBulletTexture); std::cout << "Spawned Advanced Enemy at X: " << spawnX << std::endl; AenemySpawnClock.restart(); } } Size Plansza::getSize() { return size; } std::vector &Plansza::getMeteors() { return meteors; }