#include #include #include "../headers/Plansza.h" #include "../headers/RandomNumberGenerator.h" #include Plansza::Plansza(unsigned int windowHeight, unsigned int windowWidth, sf::RenderWindow *mainWindow, ships selectedShip) : background("../assets/img/background/background.png", 2.0f) { window = mainWindow; size.height = static_cast(windowHeight); size.width = static_cast(windowWidth); Plansza::selectedShip = selectedShip; try { if(selectedShip == nova) { playerTexture.loadFromFile("../assets/ship/nova.png"); } else if(selectedShip == pulsar) { playerTexture.loadFromFile("../assets/ship/pulsar.png"); } else if(selectedShip == zenith) { playerTexture.loadFromFile("../assets/ship/zenith.png"); } else { playerTexture.loadFromFile("../assets/ship/Dreadnought-Base.png"); } // Ładowanie tekstur itemów meteorTexture1.loadFromFile("../assets/img/meteors/meteor-1.png"); meteorTexture2.loadFromFile("../assets/img/meteors/meteor-2.png"); heartTexture.loadFromFile("../assets/img/hearts/heart.png"); heartTextureGray.loadFromFile("../assets/img/hearts/heart_gray.png"); movingSpeedPowerUpTexture.loadFromFile("../assets/img/powerups/movingSpeedPU.png"); fireratePowerUpTexture.loadFromFile("../assets/img/powerups/fireratePU.png"); tripleShotPowerUpTexture.loadFromFile("../assets/img/powerups/TripleShotPU.png"); movingSpeedDebuffTexture.loadFromFile("../assets/img/debuffs/movingSpeedDBF.png"); firerateDebuffTexture.loadFromFile("../assets/img/debuffs/firerateDBF.png"); bulletSpeedDebuffTexture.loadFromFile("../assets/img/debuffs/BulletSpeedDBF.png"); // Ładowanie tekstur wrogów enemyTexture.loadFromFile("../assets/img/enemy/enemy.png"); advancedEnemyTexture.loadFromFile("../assets/img/enemy/advanced_enemy.png"); BomberEnemyTexture.loadFromFile("../assets/img/enemy/bomber.png"); KamikadzeTexture.loadFromFile("../assets/img/enemy/kamikadze.png"); BombaTexture.loadFromFile("../assets/img/bullets/bomba.png"); WiazkowiecTexture.loadFromFile("../assets/img/enemy/wiazkowiec.png"); enemyBulletTexture.loadFromFile("../assets/img/bullets/enemy_bullet.png"); BossTexture.loadFromFile("../assets/img/boss/boss.png"); } catch (std::exception &e) { std::cerr << "Failed to load textures: " << e.what() << std::endl; exit(-500); } loadUltimateIndicators(); score = 0; // Wczytywanie czcionki dla licznika punktów if (!font.loadFromFile("../assets/fonts/arial.ttf")) { std::cerr << "Error loading font\n"; exit(-500); } 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"); heartStats.emplace_back(heartTexture); heartStats.emplace_back(heartTexture); heartStats.emplace_back(heartTexture); heartStats[0].setPosition(565, 10); heartStats[1].setPosition(530, 10); heartStats[2].setPosition(495, 10); meteorSpawnClock.restart(); powerUpSpawnClock.restart(); debuffSpawnClock.restart(); spawn_player(); // spawnClock.restart(); } void Plansza::loadUltimateIndicators() { const std::string texturePaths[11] = { "../assets/img/ultimate/ultimate_0.png", "../assets/img/ultimate/ultimate_10.png", "../assets/img/ultimate/ultimate_20.png", "../assets/img/ultimate/ultimate_30.png", "../assets/img/ultimate/ultimate_40.png", "../assets/img/ultimate/ultimate_50.png", "../assets/img/ultimate/ultimate_60.png", "../assets/img/ultimate/ultimate_70.png", "../assets/img/ultimate/ultimate_80.png", "../assets/img/ultimate/ultimate_90.png", "../assets/img/ultimate/ultimate_100.png" }; for (int i = 0; i < 11; ++i) { if (!ultimateIndicatorTextures[i].loadFromFile(texturePaths[i])) { std::cerr << "Failed to load ultimate indicator texture: " << texturePaths[i] << std::endl; exit(-1); } sf::Sprite sprite; sprite.setTexture(ultimateIndicatorTextures[i]); sprite.setPosition(10, window->getSize().y - 60); sprite.setScale(0.5f, 0.5f); ultimateIndicators.push_back(sprite); } } // TODO: Refactor tej metody bo rozrosła się za bardzo już void Plansza::update() { srand(time(0)); // generacja innego ziarna na podstawie zegara systemowego // 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(); } } if (sf::Keyboard::isKeyPressed(sf::Keyboard::Space) && !ship->getUltimateStatus() && ultimateCounter >= 200) { ultimateClock.restart(); ship->ultimate_shoot(); } int indicatorIndex = ultimateCounter / 20; indicatorIndex = std::min(indicatorIndex, 10); // Zapobiegaj przekroczeniu zakresu window->draw(ultimateIndicators[indicatorIndex]); // 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 } ship->update(); // migotanie statku update_score(); // naliczanie punktów // Sprawnowanie wszystkich rodzajów wrogów spawn_meteor(); spawn_hearts(); spawn_power_up(); spawn_debuff(); spawn_enemy(); spawn_advanced_enemy(); spawn_wiazkowiec(); spawn_bomber(); spawn_kamikadze(); // spawn_boss(); // utrzymanie meteorów i pocisków w ruchu for (auto &meteor: meteors) { meteor.update(); window->draw(meteor.getSprite()); } for (auto &heart: hearts) { heart.update(); window->draw(heart.getSprite()); } for (auto &powerUp: powerUps) { powerUp.update(); window->draw(powerUp.getSprite()); } for (auto &debuff: debuffs) { debuff.update(); window->draw(debuff.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(); update_hearts(); update_power_ups(); update_debuffs(); ship->updateBullets(); window->draw(ship->getSprite()); check_Meteor_collisions(); check_Heart_collisions(); check_PowerUp_collisions(); check_Debuff_collisions(); // TODO: Dodać flagę aby warunek był sprawdzany nie tylko pod kątem Timeru ale również pod kątem ustawionej flagi if (movingSpeedPUTimer.getElapsedTime().asSeconds() >= 5.0f && powerUpCollected.movingSpeed) { powerUpCollected.movingSpeed = false; ship->setMovingSpeed(8.0f); } if (fireratePUTimer.getElapsedTime().asSeconds() >= 10.0f && powerUpCollected.firerate) { powerUpCollected.firerate = false; ship->setFirerate(200); } if (tripleShotPUTimer.getElapsedTime().asSeconds() >= 5.0f && powerUpCollected.tripleShot) { powerUpCollected.tripleShot = false; ship->setTripleShot(false); } if (movingSpeedDebuffTimer.getElapsedTime().asSeconds() >= 5.0f && debuffCollected.movingSpeed) { debuffCollected.movingSpeed = false; ship->setMovingSpeed(8.0f); } if (firerateDebuffTimer.getElapsedTime().asSeconds() >= 5.0f && debuffCollected.firerate) { debuffCollected.firerate = false; ship->setFirerate(200); } if (bulletSpeedDebuffTimer.getElapsedTime().asSeconds() >= 5.0f && debuffCollected.bulletSpeed) { debuffCollected.bulletSpeed = false; ship->setBulletSpeed(10.0f); } handleUltimate(); if (gameOver) { 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 bulletIt = ship->getBullets().begin(); bulletIt != ship->getBullets().end();) { if (meteorIt->getSprite().getGlobalBounds().intersects(bulletIt->getSprite().getGlobalBounds())) { ship->getBullets().erase(bulletIt); meteorIt = getMeteors().erase(meteorIt); meteorHit = true; break; } else { ++bulletIt; } } 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; } } for (auto meteorIt = getMeteors().begin(); meteorIt != getMeteors().end();) { bool meteorHit = false; for (auto bulletIt = ship->getBullets().begin(); bulletIt != ship->getBullets().end();) { if (meteorIt->getSprite().getGlobalBounds().intersects(bulletIt->getSprite().getGlobalBounds())) { ship->getBullets().erase(bulletIt); meteorIt = getMeteors().erase(meteorIt); meteorHit = true; break; } else { ++bulletIt; } } 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()) { std::cout << "Basic Enemy has been eliminated." << std::endl; 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; } } for (auto it = BEnemies.begin(); it != BEnemies.end();) { it->update(); // Ruch bombera it->shoot(); // Strzał przeciwnika window->draw(it->getSprite()); // Rysowanie na ekranie if (!it->isAlive()) { std::cout << "Bomber has been eliminated." << std::endl; it = BEnemies.erase(it); // Usunięcie martwych przeciwników } else { ++it; } } for (auto it = KEnemies.begin(); it != KEnemies.end();) { sf::Vector2f playerPosition = ship->getSprite().getPosition(); // Aktualna pozycja gracza bool playerHit = false; it->update(playerPosition); // Wybuch, gdy Kamikadze dotknie gracza if (ship->getSprite().getGlobalBounds().intersects(it->getSprite().getGlobalBounds())) { it->explode(playerPosition, playerHit); if (playerHit) { ship->takeDamage(); // Gracz otrzymuje obrażenia std::cout << "Gracz został trafiony przez eksplozję Kamikadze!" << std::endl; } } // Kamikadze eksploduje po aktywacji niezależnie od obecności gracza if (it->isExploding()) { it->explode(playerPosition, playerHit); // Eksplozja trwa } // Usunięcie martwego Kamikadze if (it->isAlive()) { window->draw(it->getSprite()); ++it; } else { std::cout << "Kamikadze exploded!" << std::endl; it = KEnemies.erase(it); } } // 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; } } } // Obsługa bomb for (auto &aEnemy: BEnemies) { 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; } } } // Aktualizacja bossa if (boss && boss->isAlive()) { boss->update(); window->draw(boss->getSprite()); // Kolizje bossa z pociskami for (auto bulletIt = ship->getBullets().begin(); bulletIt != ship->getBullets().end();) { if (boss->getSprite().getGlobalBounds().intersects(bulletIt->getSprite().getGlobalBounds())) { boss->takeDamage(); bulletIt = ship->getBullets().erase(bulletIt); } else { ++bulletIt; } } for (auto rocketIt = ship->getRockets().begin(); rocketIt != ship->getRockets().end();) { if (boss->getSprite().getGlobalBounds().intersects(rocketIt->getSprite().getGlobalBounds())) { boss->takeDamage(); rocketIt = ship->getRockets().erase(rocketIt); std::cout << "Rocket hit boss! Boss HP: " << boss->getHP() << std::endl; } else { ++rocketIt; } } // Kolizja bossa z graczem // if (ship->getSprite().getGlobalBounds().intersects(boss->getSprite().getGlobalBounds())) { // ship->takeDamage(); // } } else if (bossSpawned && (!boss || !boss->isAlive())) { std::cout << "Boss defeated!" << std::endl; delete boss; boss = nullptr; bossSpawned = false; // Resetowanie flagi, jeśli boss został pokonany } // Obsługa pocisków bossa if (boss && boss->isAlive()) { for (auto it = boss->getBullets().begin(); it != boss->getBullets().end();) { if (ship->getSprite().getGlobalBounds().intersects(it->getSprite().getGlobalBounds())) { ship->takeDamage(); it = boss->getBullets().erase(it); // Usuwanie pocisku po trafieniu } else { ++it; } } // Obsługa bomb bossa for (auto it = boss->getBombs().begin(); it != boss->getBombs().end();) { if (ship->getSprite().getGlobalBounds().intersects(it->getSprite().getGlobalBounds())) { ship->takeDamage(); it = boss->getBombs().erase(it); // Usuwanie bomby po trafieniu } else { ++it; } } if (boss->isShooting() && boss->getBeam() != nullptr) { if (ship->getSprite().getGlobalBounds().intersects(boss->getBeam()->getSprite().getGlobalBounds())) { ship->takeDamage(); // Gracz otrzymuje obrażenia } } // Sprawdzenie kolizji pocisków gracza z bombami Bossa for (auto bombIt = boss->getBombs().begin(); bombIt != boss->getBombs().end();) { bool bombHit = false; for (auto bulletIt = ship->getBullets().begin(); bulletIt != ship->getBullets().end();) { if (bombIt->getSprite().getGlobalBounds().intersects(bulletIt->getSprite().getGlobalBounds())) { ship->getBullets().erase(bulletIt); bombIt = boss->getBombs().erase(bombIt); bombHit = true; break; } else { ++bulletIt; } } if (!bombHit) { ++bombIt; } } // Sprawdzenie kolizji rakiet gracza z bombami Bossa for (auto bombIt = boss->getBombs().begin(); bombIt != boss->getBombs().end();) { bool bombHit = false; for (auto rocketIt = ship->getRockets().begin(); rocketIt != ship->getRockets().end();) { if (bombIt->getSprite().getGlobalBounds().intersects(rocketIt->getSprite().getGlobalBounds())) { ship->getRockets().erase(rocketIt); bombIt = boss->getBombs().erase(bombIt); bombHit = true; break; } else { ++rocketIt; } } if (!bombHit) { ++bombIt; } } } for (auto &enemy: enemies) { enemy.shoot(); enemy.updateBullets(); for (auto &bullet: enemy.getBullets()) { bullet.update(); window->draw(bullet.getSprite()); } } 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 &bomberEnemy: BEnemies) { bomberEnemy.updateBullets(); // Obsługuje bomby for (auto &bullet: bomberEnemy.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 ship->takeDamage(); // Usuwanie pocisku it = enemy.getBullets().erase(it); } else { ++it; // Brak kolizji, przechodzimy do kolejnego pocisku } } } for (auto &bomberEnemy: BEnemies) { for (auto it = bomberEnemy.getBullets().begin(); it != bomberEnemy.getBullets().end();) { bool bulletDestroyed = false; // Kolizja pocisku gracza z pociskiem Bombera for (auto playerBulletIt = ship->getBullets().begin(); playerBulletIt != ship->getBullets().end();) { if (playerBulletIt->getSprite().getGlobalBounds().intersects(it->getSprite().getGlobalBounds())) { // Usuń pocisk Bombera i pocisk gracza it = bomberEnemy.getBullets().erase(it); ship->getBullets().erase(playerBulletIt); bulletDestroyed = true; break; } else { ++playerBulletIt; } } // Kolizja rakiety gracza z pociskiem Bombera if (!bulletDestroyed) { for (auto rocketIt = ship->getRockets().begin(); rocketIt != ship->getRockets().end();) { if (rocketIt->getSprite().getGlobalBounds().intersects(it->getSprite().getGlobalBounds())) { // Usuń pocisk Bombera i rakietę gracza it = bomberEnemy.getBullets().erase(it); ship->getRockets().erase(rocketIt); bulletDestroyed = true; break; } else { ++rocketIt; } } } // Jeśli pocisk Bombera przetrwał dotychczasowe sprawdzenia, wykonaj inne działania if (!bulletDestroyed) { if (ship->getSprite().getGlobalBounds().intersects(it->getSprite().getGlobalBounds())) { // Kolizja pocisku Bombera z graczem ship->takeDamage(); it = bomberEnemy.getBullets().erase(it); } else { ++it; } } } } for (auto &wiazkowiec: WEnemies) { wiazkowiec.update(); if (wiazkowiec.isShooting()) { if (ship->getSprite().getGlobalBounds().intersects(wiazkowiec.getBeam()->getSprite().getGlobalBounds())) { ship->takeDamage(); // Gracz otrzymuje obrażenia } } window->draw(wiazkowiec.getSprite()); } // TODO: naprawić to co średnio działa // Usuwanie pocisków, które są poza ekranem srednio to dziala 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())) { ship->getBullets().erase(bulletIt); enemyIt->takeDamage(); hit = true; break; } else { ++bulletIt; } } if (hit && !enemyIt->isAlive()) { enemyIt = enemies.erase(enemyIt); } else { ++enemyIt; } } 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())) { 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 bomberIt = BEnemies.begin(); bomberIt != BEnemies.end();) { bool hit = false; for (auto bulletIt = ship->getBullets().begin(); bulletIt != ship->getBullets().end();) { if (bomberIt->getSprite().getGlobalBounds().intersects(bulletIt->getSprite().getGlobalBounds())) { ship->getBullets().erase(bulletIt); bomberIt->takeDamage(); hit = true; break; } else { ++bulletIt; } } if (hit && !bomberIt->isAlive()) { bomberIt = BEnemies.erase(bomberIt); // Usunięcie przeciwnika Bomber } else { ++bomberIt; } } for (auto kamikadzeIt = KEnemies.begin(); kamikadzeIt != KEnemies.end();) { bool hit = false; for (auto bulletIt = ship->getBullets().begin(); bulletIt != ship->getBullets().end();) { if (kamikadzeIt->getSprite().getGlobalBounds().intersects(bulletIt->getSprite().getGlobalBounds())) { ship->getBullets().erase(bulletIt); kamikadzeIt->takeDamage(); hit = true; break; } else { ++bulletIt; } } if (hit && !kamikadzeIt->isAlive()) { kamikadzeIt = KEnemies.erase(kamikadzeIt); // Usunięcie przeciwnika Kamikadze } else { ++kamikadzeIt; } } for (auto wiazkowiecIt = WEnemies.begin(); wiazkowiecIt != WEnemies.end();) { bool hit = false; for (auto bulletIt = ship->getBullets().begin(); bulletIt != ship->getBullets().end();) { if (wiazkowiecIt->getSprite().getGlobalBounds().intersects(bulletIt->getSprite().getGlobalBounds())) { ship->getBullets().erase(bulletIt); wiazkowiecIt->takeDamage(); hit = true; break; } else { ++bulletIt; } } if (hit && !wiazkowiecIt->isAlive()) { wiazkowiecIt = WEnemies.erase(wiazkowiecIt); // Usunięcie przeciwnika Wiazkowiec } else { ++wiazkowiecIt; } } //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())) { 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())) { ship->getRockets().erase(rocketIt); advancedIt->takeDamage(); hit = true; break; } else { ++rocketIt; } } if (hit && !advancedIt->isAlive()) { advancedIt = AEnemies.erase(advancedIt); } else { ++advancedIt; } } for (auto bomberIt = BEnemies.begin(); bomberIt != BEnemies.end();) { bool hit = false; for (auto rocketIt = ship->getRockets().begin(); rocketIt != ship->getRockets().end();) { if (bomberIt->getSprite().getGlobalBounds().intersects(rocketIt->getSprite().getGlobalBounds())) { ship->getRockets().erase(rocketIt); bomberIt->takeDamage(); hit = true; break; } else { ++rocketIt; } } if (hit && !bomberIt->isAlive()) { bomberIt = BEnemies.erase(bomberIt); } else { ++bomberIt; } } for (auto kamikadzeIt = KEnemies.begin(); kamikadzeIt != KEnemies.end();) { bool hit = false; for (auto rocketIt = ship->getRockets().begin(); rocketIt != ship->getRockets().end();) { if (kamikadzeIt->getSprite().getGlobalBounds().intersects(rocketIt->getSprite().getGlobalBounds())) { ship->getRockets().erase(rocketIt); kamikadzeIt->takeDamage(); hit = true; break; } else { ++rocketIt; } } if (hit && !kamikadzeIt->isAlive()) { kamikadzeIt = KEnemies.erase(kamikadzeIt); } else { ++kamikadzeIt; } } for (auto wiazkowiecIt = WEnemies.begin(); wiazkowiecIt != WEnemies.end();) { bool hit = false; for (auto rocketIt = ship->getRockets().begin(); rocketIt != ship->getRockets().end();) { if (wiazkowiecIt->getSprite().getGlobalBounds().intersects(rocketIt->getSprite().getGlobalBounds())) { ship->getRockets().erase(rocketIt); wiazkowiecIt->takeDamage(); hit = true; break; } else { ++rocketIt; } } if (hit && !wiazkowiecIt->isAlive()) { wiazkowiecIt = WEnemies.erase(wiazkowiecIt); } else { ++wiazkowiecIt; } } // Statystyka życia gracza (wyświetlanie) switch (ship->getHP()) { case 0: heartStats[0].setTexture(heartTextureGray); heartStats[1].setTexture(heartTextureGray); heartStats[2].setTexture(heartTextureGray); gameOver = true; break; case 1: heartStats[0].setTexture(heartTexture); heartStats[1].setTexture(heartTextureGray); heartStats[2].setTexture(heartTextureGray); break; case 2: heartStats[0].setTexture(heartTexture); heartStats[1].setTexture(heartTexture); heartStats[2].setTexture(heartTextureGray); break; case 3: heartStats[0].setTexture(heartTexture); heartStats[1].setTexture(heartTexture); heartStats[2].setTexture(heartTexture); break; default: break; } for (const auto& heart: heartStats) { window->draw(heart); } } // Meteor-related niżej 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::update_hearts() { // usuwanie serduszek, które wyleciały poza ekran for (auto& heart : hearts) { if(heart.getStatus()) { hearts.erase(hearts.begin()); } } } void Plansza::update_power_ups() { for (auto& power : powerUps) { if(power.getStatus()) { powerUps.erase(powerUps.begin()); } } } void Plansza::update_debuffs() { for (auto& debuff : debuffs) { if(debuff.getStatus()) { debuffs.erase(debuffs.begin()); } } } void Plansza::spawn_meteor() { if (meteorSpawnClock.getElapsedTime().asSeconds() > rand() % 30 + 5) { // randomowy spawn meteorytów od 10 do 1 sekundy if (meteors.size() < 3) { // 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); } } meteorSpawnClock.restart(); } } void Plansza::spawn_hearts() { if (heartSpawnClock.getElapsedTime().asSeconds() > rand() % 26 + 5) { // randomowy spawn serduszek od 5 do 30 sekundy if (hearts.size() < 5) { // jeśli jest mniej niż 5 serduszek na planszy hearts.emplace_back(RandomNumberGenerator::getRandomNumber(50, 499), -100, heartTexture); } heartSpawnClock.restart(); } } void Plansza::spawn_power_up() { if (powerUpSpawnClock.getElapsedTime().asSeconds() > 15) { if (powerUps.size() < 2) { auto powerUpRand = rand() % 3; switch (powerUpRand) { case 0: powerUps.emplace_back(RandomNumberGenerator::getRandomNumber(50, 499), -100, movingSpeedPowerUpTexture, PowerUp::movingSpeedUp); break; case 1: powerUps.emplace_back(RandomNumberGenerator::getRandomNumber(50, 499), -100, fireratePowerUpTexture, PowerUp::firerateUp); break; case 2: powerUps.emplace_back(RandomNumberGenerator::getRandomNumber(50,499), -100, tripleShotPowerUpTexture, PowerUp::tripleShotUp); break; } } powerUpSpawnClock.restart(); } } void Plansza::spawn_debuff() { if (debuffSpawnClock.getElapsedTime().asSeconds() > 30) { if (debuffs.size() < 1) { switch (rand() % 3) { case 0: debuffs.emplace_back(RandomNumberGenerator::getRandomNumber(50, 499), -100, movingSpeedDebuffTexture, Debuff::movingSpeedDbf); break; case 1: debuffs.emplace_back(RandomNumberGenerator::getRandomNumber(50, 499), -100, firerateDebuffTexture, Debuff::firerateDbf); break; case 2: debuffs.emplace_back(RandomNumberGenerator::getRandomNumber(50,499), -100, bulletSpeedDebuffTexture, Debuff::bulletSpeedDbf); break; } } debuffSpawnClock.restart(); } } void Plansza::spawn_player() { ship = Player::getInstance(static_cast(window->getSize().x) / 2, static_cast(window->getSize().y) - 100, this->playerTexture); ship->loadTexture(); ship->setMovingSpeed(8); ship->setFirerate(200); } void Plansza::spawn_enemy() { if (enemySpawnClock.getElapsedTime().asSeconds() >= 10) { // Spawn co 10 sekund int spawnX = RandomNumberGenerator::getRandomNumber(50, size.width - 50); enemies.emplace_back(spawnX, -50, enemyTexture); std::cout << "Spawned Basic Enemy at X: " << spawnX << std::endl; enemySpawnClock.restart(); } } void Plansza::spawn_advanced_enemy() { if (AenemySpawnClock.getElapsedTime().asSeconds() >= 8) { // 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(); } } void Plansza::spawn_bomber() { if (BomberSpawnClock.getElapsedTime().asSeconds() >= 5) { // Spawn co 10 sekund int spawnX = RandomNumberGenerator::getRandomNumber(50, size.width - 50); Bomber bomber(spawnX, -50, BomberEnemyTexture, BombaTexture); bomber.setPlanszaHeight(size.height, size.width); // Przekazanie wysokości i szerokości okna BEnemies.push_back(bomber); std::cout << "Spawned Bomber Enemy at X: " << spawnX << std::endl; BomberSpawnClock.restart(); } } void Plansza::spawn_kamikadze() { if (KamikadzeSpawnClock.getElapsedTime().asSeconds() >= 40) { // Spawn co 10 sekund int spawnX = RandomNumberGenerator::getRandomNumber(50, size.width - 50); KEnemies.emplace_back(spawnX, -50, KamikadzeTexture); std::cout << "Spawned Kamikadze Enemy at X: " << spawnX << std::endl; KamikadzeSpawnClock.restart(); } } void Plansza::spawn_wiazkowiec() { if (WiazkowiecSpawnClock.getElapsedTime().asSeconds() >= 3) { // Spawn co 10 sekund if (WEnemies.size() < 1) { int spawnX = RandomNumberGenerator::getRandomNumber(50, size.width - 50); Wiazkowiec wiazkowiec(spawnX, -50, WiazkowiecTexture, window); wiazkowiec.setPlanszaHeight(size.height, size.width); // Przekazanie wysokości i szerokosci okna WEnemies.push_back(wiazkowiec); std::cout << "Spawned Wiazkowiec Enemy at X: " << spawnX << std::endl; WiazkowiecSpawnClock.restart(); } } } void Plansza::spawn_boss() { if (!bossSpawned && score >= nextBossScoreThreshold) { // Spawn po 60 sekundach boss = new Boss(size.width / 2, -100, BossTexture, enemyBulletTexture, BombaTexture, window); boss->setPlanszaHeight(size.width, size.height); bossSpawned = true; nextBossScoreThreshold += 1000; std::cout << "Boss spawned at score: " << score << std::endl; } } Size Plansza::getSize() { return size; } std::vector &Plansza::getMeteors() { return meteors; } void Plansza::update_score() { if (scoreClock.getElapsedTime().asMilliseconds() > 500) { score++; ultimateCounter++; if (ultimateCounter >= 200) { ultimateCounter = 200; } scoreClock.restart(); } sf::Text text(std::to_string(score), font, 24); text.setFillColor(sf::Color::White); text.setPosition(25, 25); window->draw(text); } void Plansza::check_PowerUp_collisions() { for (auto powerUpIt = powerUps.begin(); powerUpIt != powerUps.end();) { if (ship->getSprite().getGlobalBounds().intersects(powerUpIt->getSprite().getGlobalBounds())) { if (powerUpIt->getType() == PowerUp::movingSpeedUp) { ship->setMovingSpeed(15.0f); powerUpCollected.movingSpeed = true; movingSpeedPUTimer.restart(); } if (powerUpIt->getType() == PowerUp::firerateUp) { ship->setFirerate(100); powerUpCollected.firerate = true; fireratePUTimer.restart(); } if (powerUpIt->getType() == PowerUp::tripleShotUp) { ship->setTripleShot(true); powerUpCollected.tripleShot = true; tripleShotPUTimer.restart(); } powerUpIt = powerUps.erase(powerUpIt); } else { ++powerUpIt; } } } void Plansza::check_Debuff_collisions() { for (auto debuffIt = debuffs.begin(); debuffIt != debuffs.end();) { if (ship->getSprite().getGlobalBounds().intersects(debuffIt->getSprite().getGlobalBounds())) { if (debuffIt->getType() == Debuff::movingSpeedDbf) { ship->setMovingSpeed(4.0f); debuffCollected.movingSpeed = true; movingSpeedDebuffTimer.restart(); } if (debuffIt->getType() == Debuff::firerateDbf) { ship->setFirerate(500); debuffCollected.firerate = true; firerateDebuffTimer.restart(); } if (debuffIt->getType() == Debuff::bulletSpeedDbf) { ship->setBulletSpeed(5.0f); debuffCollected.bulletSpeed = true; bulletSpeedDebuffTimer.restart(); } debuffIt = debuffs.erase(debuffIt); } else { ++debuffIt; } } } void Plansza::check_Heart_collisions() { for (auto heartIt = hearts.begin(); heartIt != hearts.end();) { if (ship->getSprite().getGlobalBounds().intersects(heartIt->getSprite().getGlobalBounds())) { ship->healUP(); heartIt = hearts.erase(heartIt); } else { ++heartIt; } } } void Plansza::check_Meteor_collisions() { for (auto &meteor: meteors) { if (ship->getSprite().getGlobalBounds().intersects(meteor.getSprite().getGlobalBounds())) { ship->takeDamage(); } } } ships Plansza::selectedShip = none; unsigned int Plansza::score = 0; unsigned int Plansza::ultimateCounter = 0; void Plansza::handleUltimate() { if (ship->getUltimateStatus() && ultimateCounter >= 200) { float elapsedTime = ultimateClock.getElapsedTime().asSeconds(); if (ship->getUltimateStatus() && ultimateClock.getElapsedTime().asSeconds() >= 1) { ultimateCounter = 0; } if (elapsedTime < 1) { sf::RectangleShape ultimateShape(sf::Vector2f(600, 800)); int alpha = static_cast(255 * (1 - elapsedTime)); ultimateShape.setFillColor(sf::Color(255, 255, 255, alpha)); meteors.clear(); debuffs.clear(); enemies.clear(); AEnemies.clear(); BEnemies.clear(); KEnemies.clear(); WEnemies.clear(); window->draw(ultimateShape); } else { ship->setUltimateStatus(false); } } }