diff --git a/assets/img/hearts/heart_gray.png b/assets/img/hearts/heart_gray.png new file mode 100644 index 0000000..851ca81 Binary files /dev/null and b/assets/img/hearts/heart_gray.png differ diff --git a/headers/Actor.h b/headers/Actor.h index 7fc1ec6..f7735c0 100644 --- a/headers/Actor.h +++ b/headers/Actor.h @@ -5,6 +5,7 @@ #include "SFML/Graphics/Texture.hpp" #include "Bullet.h" #include "Position.h" +#include "SFML/System/Clock.hpp" class Actor { @@ -14,8 +15,9 @@ public: void loadTexture(std::string path); sf::Sprite& getSprite(); - + unsigned int getHP(); Position getPosition(); + std::vector& getBullets(); virtual void move(float deltaX, float deltaY) = 0; virtual void moveLeft() = 0; @@ -24,19 +26,19 @@ public: virtual void moveDown() = 0; virtual void shoot() = 0; - std::vector& getBullets(); - void updateBullets(); - void setMovingSpeed(float speed); + void dealDamage(); + void healUP(); protected: sf::Sprite actorSprite; sf::Texture actorTexture; sf::Texture bulletTextureLeft; sf::Texture bulletTextureRight; + sf::Clock damageDealClock; Position position; - unsigned int hp; + int hp; unsigned int damage; unsigned int firerate; float moving_speed; diff --git a/headers/Plansza.h b/headers/Plansza.h index 76dc689..9c3af19 100644 --- a/headers/Plansza.h +++ b/headers/Plansza.h @@ -25,19 +25,21 @@ public: void update_hearts(); void update(); private: - Size size; + sf::RenderWindow *window; Background background; Player ship; AudioManager audioManager; + Size size; sf::Texture meteorTexture1; sf::Texture meteorTexture2; sf::Texture heartTexture; + sf::Texture heartTextureGray; sf::Clock meteorSpawnClock; sf::Clock heartSpawnClock; std::vector meteors; std::vector hearts; - sf::RenderWindow *window; - + std::vector heartStats; + bool gameOver = false; }; #endif //PLANSZA_H diff --git a/sources/Actor.cpp b/sources/Actor.cpp index 2170a24..9a3daf5 100644 --- a/sources/Actor.cpp +++ b/sources/Actor.cpp @@ -24,6 +24,25 @@ Position Actor::getPosition() { return {position.x, position.y}; } +unsigned int Actor::getHP() { + return hp; +} + +void Actor::dealDamage() { + if(damageDealClock.getElapsedTime().asSeconds() > 1) { + if(hp > 0) { + hp--; + } + damageDealClock.restart(); + } +} + +void Actor::healUP() { + if(hp < 3){ + hp++; + } +} + std::vector &Actor::getBullets() { return bullets; } @@ -38,4 +57,4 @@ void Actor::updateBullets() { void Actor::setMovingSpeed(float speed) { moving_speed = speed; -} +} \ No newline at end of file diff --git a/sources/Plansza.cpp b/sources/Plansza.cpp index 93bd57a..5ca9831 100644 --- a/sources/Plansza.cpp +++ b/sources/Plansza.cpp @@ -1,13 +1,11 @@ #include #include #include "../headers/Plansza.h" -#include "../headers/ObjectItem.hpp" Plansza::Plansza(unsigned int windowHeight, unsigned int windowWidth, sf::RenderWindow *mainWindow) : background("../assets/img/background/background.png", 2.0f), ship(static_cast(mainWindow->getSize().x) / 2, static_cast(mainWindow->getSize().y) - 100, "../assets/ship/Dreadnought-Base.png") { - window = mainWindow; size.height = static_cast(windowHeight); size.width = static_cast(windowWidth); @@ -26,6 +24,14 @@ ship(static_cast(mainWindow->getSize().x) / 2, static_cast(mainWindow- meteorTexture2.loadFromFile("../assets/img/meteors/meteor-2.png"); heartTexture.loadFromFile("../assets/img/hearts/heart.png"); + heartTextureGray.loadFromFile("../assets/img/hearts/heart_gray.png"); + + heartStats.emplace_back(sf::Sprite(heartTexture)); + heartStats.emplace_back(sf::Sprite(heartTexture)); + heartStats.emplace_back(sf::Sprite(heartTexture)); + heartStats[0].setPosition(10, 10); + heartStats[1].setPosition(45, 10); + heartStats[2].setPosition(80, 10); meteorSpawnClock.restart(); } @@ -33,145 +39,188 @@ ship(static_cast(mainWindow->getSize().x) / 2, static_cast(mainWindow- void Plansza::update() { // tło - background.update(); - background.draw(*window); + background.update(); + background.draw(*window); - // poruszanie się statkiem - if(sf::Keyboard::isKeyPressed(sf::Keyboard::A)) { - if(ship.getPosition().x > 50) { - ship.moveLeft(); + // 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 i serduszka + spawn_meteor(); + spawn_hearts(); + + + // 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 &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(); + ship.updateBullets(); + + window->draw(ship.getSprite()); + + + // trochę dziwny sposób ale jednak działa + for (auto &meteor: meteors) { + if (ship.getSprite().getGlobalBounds().intersects(meteor.getSprite().getGlobalBounds())) { + ship.dealDamage(); + } + } + + for (auto heartIt = hearts.begin(); heartIt != hearts.end();) { + if (ship.getSprite().getGlobalBounds().intersects(heartIt->getSprite().getGlobalBounds())) { + ship.healUP(); + heartIt = hearts.erase(heartIt); + } else { + ++heartIt; + } + } + + 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 (sf::Keyboard::isKeyPressed(sf::Keyboard::W)) { - if(ship.getPosition().y > 80) { - ship.moveUp(); + 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 (sf::Keyboard::isKeyPressed(sf::Keyboard::S)) { - if(ship.getPosition().y < 720) { - ship.moveDown(); - } + if (!meteorHit) { + ++meteorIt; } - if (sf::Keyboard::isKeyPressed(sf::Keyboard::D)) { - if(ship.getPosition().x < 550) { - ship.moveRight(); - } + } + + + // Warunek przeganej + if (gameOver) { + 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); - // 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_hearts(); - - - // 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& 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(); - 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(); + // 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; - } - } + // 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; + } - 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 heart: heartStats) { + window->draw(heart); + } } - // Meteor-related niżej - void Plansza::spawn_meteor() { if (meteorSpawnClock.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 diff --git a/sources/Player.cpp b/sources/Player.cpp index 91117cf..12582e5 100644 --- a/sources/Player.cpp +++ b/sources/Player.cpp @@ -1,9 +1,12 @@ -#include "../headers/Player.h" -#include "../headers/Bullet.h" +#include -Player::Player(int x, int y, std::string path) : Actor(x, y, path) { +#include "../headers/Player.h" + +Player::Player(int x, int y, std::string path) : Actor(x, y, std::move(path)) { bulletTexture.loadFromFile("../assets/img/bullets/bullet_pink.png"); rocketTexture.loadFromFile("../assets/img/rockets/Rocket_111.png"); + hp = 3; + damageDealClock.restart(); }; void Player::shoot() {