From 3b637508e1559ad38fbf0f2cb7d10fcdca94d4d4 Mon Sep 17 00:00:00 2001 From: Andrii Solianyk Date: Thu, 5 Dec 2024 14:52:00 +0100 Subject: [PATCH 1/4] Added heart and spawn of them --- CMakeLists.txt | 4 +++- headers/Heart.hpp | 14 ++++++++++++++ headers/Plansza.h | 9 ++++++++- sources/Heart.cpp | 23 +++++++++++++++++++++++ sources/Plansza.cpp | 37 +++++++++++++++++++++++++++++++++---- 5 files changed, 81 insertions(+), 6 deletions(-) create mode 100644 headers/Heart.hpp create mode 100644 sources/Heart.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 1a16cba..8877bca 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -27,7 +27,9 @@ add_executable(LotoStatek main.cpp headers/Size.h headers/Position.h headers/ObjectItem.hpp - sources/ObjectItem.cpp) + sources/ObjectItem.cpp + headers/Heart.hpp + sources/Heart.cpp) if(WIN32) set(SFML_ROOT "${CMAKE_SOURCE_DIR}/lib/SFML") diff --git a/headers/Heart.hpp b/headers/Heart.hpp new file mode 100644 index 0000000..ecaf8b6 --- /dev/null +++ b/headers/Heart.hpp @@ -0,0 +1,14 @@ +#ifndef LOTOSTATEK_HEART_HPP +#define LOTOSTATEK_HEART_HPP + +#include "SFML/Graphics/Texture.hpp" +#include "SFML/Graphics/Sprite.hpp" +#include "ObjectItem.hpp" + +class Heart : public ObjectItem { +public: + Heart(float x, float y, sf::Texture &texture); + void update(); +}; + +#endif //LOTOSTATEK_HEART_HPP diff --git a/headers/Plansza.h b/headers/Plansza.h index 0971823..76dc689 100644 --- a/headers/Plansza.h +++ b/headers/Plansza.h @@ -12,6 +12,7 @@ #include "AudioManager.h" #include "Meteor.h" #include "Plansza.h" +#include "Heart.hpp" class Plansza { public: @@ -19,7 +20,9 @@ public: Size getSize(); std::vector &getMeteors(); void spawn_meteor(); + void spawn_hearts(); void update_meteors(); + void update_hearts(); void update(); private: Size size; @@ -28,9 +31,13 @@ private: AudioManager audioManager; sf::Texture meteorTexture1; sf::Texture meteorTexture2; - sf::Clock spawnClock; + sf::Texture heartTexture; + sf::Clock meteorSpawnClock; + sf::Clock heartSpawnClock; std::vector meteors; + std::vector hearts; sf::RenderWindow *window; + }; #endif //PLANSZA_H diff --git a/sources/Heart.cpp b/sources/Heart.cpp new file mode 100644 index 0000000..4a61998 --- /dev/null +++ b/sources/Heart.cpp @@ -0,0 +1,23 @@ +#include "../headers/Heart.hpp" + +Heart::Heart(float x, float y, sf::Texture &texture) : ObjectItem(x,y,texture) { + outOfBounds = false; + texture = texture; + sprite.setTexture(texture); + sprite.setOrigin(sprite.getLocalBounds().width / 2, sprite.getLocalBounds().height / 2); // wycentrowanie sprite + sprite.setPosition(x, y); + movingSpeed = 3.0f; +// sprite.scale(0.05f, 0.05f); + position.x = x; + position.y = y; + rotationSpeed = 0; +} + +void Heart::update() { + sprite.move(0.0f, movingSpeed); // przesunięcie sprajta + position.y += int(movingSpeed); // przesunięcie pozycji +// sprite.rotate(rotationSpeed); // obracanie tym meteorkiem pięknym + if(position.y > 900) { + outOfBounds = true; // jeżeli wyszedł poza granice ekranu ustaw tą zmienną + } +} \ No newline at end of file diff --git a/sources/Plansza.cpp b/sources/Plansza.cpp index 5183a91..93bd57a 100644 --- a/sources/Plansza.cpp +++ b/sources/Plansza.cpp @@ -24,7 +24,10 @@ ship(static_cast(mainWindow->getSize().x) / 2, static_cast(mainWindow- meteorTexture1.loadFromFile("../assets/img/meteors/meteor-1.png"); meteorTexture2.loadFromFile("../assets/img/meteors/meteor-2.png"); - spawnClock.restart(); + + heartTexture.loadFromFile("../assets/img/hearts/heart.png"); + + meteorSpawnClock.restart(); } @@ -67,14 +70,20 @@ void Plansza::update() { // generowanie nowego meteoru spawn_meteor(); + spawn_hearts(); // utrzymanie meteorów i pocisków w ruchu - for (auto& meteor : getMeteors()) { + 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()); @@ -87,10 +96,12 @@ void Plansza::update() { // 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())) { @@ -162,7 +173,7 @@ void Plansza::update() { // 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 (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 if(rand() % 2 == 1) { meteors.emplace_back(RandomNumberGenerator::getRandomNumber(50,499), -100, meteorTexture2); @@ -170,7 +181,16 @@ void Plansza::spawn_meteor() { meteors.emplace_back(RandomNumberGenerator::getRandomNumber(50,499), -100, meteorTexture1); } } - spawnClock.restart(); + meteorSpawnClock.restart(); + } +} + +void Plansza::spawn_hearts() { + if (heartSpawnClock.getElapsedTime().asSeconds() > rand() % 10 + 1) { // randomowy spawn meteorytów od 10 do 1 sekundy + if (hearts.size() < 5) { // jeśli jest mniej niż 5 meteorów na planszy + hearts.emplace_back(RandomNumberGenerator::getRandomNumber(50, 499), -100, heartTexture); + } + heartSpawnClock.restart(); } } @@ -183,6 +203,15 @@ void Plansza::update_meteors() { } } +void Plansza::update_hearts() { + // usuwanie serduszek które wyleciały poza ekran + for (auto& heart : hearts) { + if(heart.getStatus()) { + hearts.erase(hearts.begin()); + } + } +} + Size Plansza::getSize() { return size; } From 2f9e0ba236140d54b78977c50a0188aeae797e13 Mon Sep 17 00:00:00 2001 From: Andrii Solianyk Date: Fri, 6 Dec 2024 12:24:39 +0100 Subject: [PATCH 2/4] =?UTF-8?q?Serduszka=20dzia=C5=82aj=C4=85=20do=20zrobi?= =?UTF-8?q?enia=20jeszcze=20animacja=20uderzenia=20si=C4=99=20w=20meteoryt?= =?UTF-8?q?=20(miganie)=20i=20wybuch=20statku=20przy=20uderzeniu=20si?= =?UTF-8?q?=C4=99=20w=20meteoryt=20po=20raz=20trzeci?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- assets/img/hearts/heart_gray.png | Bin 0 -> 958 bytes headers/Actor.h | 12 +- headers/Plansza.h | 8 +- sources/Actor.cpp | 21 ++- sources/Plansza.cpp | 301 ++++++++++++++++++------------- sources/Player.cpp | 9 +- 6 files changed, 213 insertions(+), 138 deletions(-) create mode 100644 assets/img/hearts/heart_gray.png diff --git a/assets/img/hearts/heart_gray.png b/assets/img/hearts/heart_gray.png new file mode 100644 index 0000000000000000000000000000000000000000..851ca811e69e3f41c27121e68db49d1bc5e1d8e2 GIT binary patch literal 958 zcmV;v13~Px&cu7P-R9HvNS3ye~K@|RW(@iu6lZH?fTdlq5rQpF*R74Q;B1nEg3(XJk-2Q;} zM@S2;rwD@J*@LGV8bK(iQ4=GL8e^!NnvI*7?9?}AB(WQlSS6W*PTstk`QG>5y!TeZ zzvCT%&n9vqie0WhtFZnHz|&jy`T%?>U6+~(z#@PlMNuC0^z^t1m?TMzF;)grRn=@V znM?sl0C-t6;3t459*@WAa=C0IbGzNNpQbFI&+|zr6#A1+r*#0|0eJZxB@7e*$Tph| z)6>%xSquh)*xTC^>ta76L2qv_1_uYr_NuCics$N!u~-bJr>8VE09cv^07pMCFu*!H zJBf4j_4RR?&1PeUVMv)whMk<8$RwkAQHGV36>izs*cj|~J7igAcDudIWw~6A>AKEk z2L}f*41=E$jYheQ{_x92M@P}o(ZLU#pP%Rd4Z|qNvTRvcSYUp?zwF?Piwi6+QrG}q zuNR7<+!Fj(OQBE*WT39=*xA|PvW5USKR?Ir?yfliid?_n&li0@AI{Fss#;d7LO2`- zF&B@=$))Blct`+STU#6}85NC2%NZCR9%fx#U6RFO;Xy?s5C||$({3g!iW##6MqA9* zu4N(ya=9Fjhl(*!E2Z`72?h#<0yZ`_8V4Ys&tr3Q)7%9PhXXS+GkkG*d6})QuHKsq z=;@L57K??gudka2q0{Na?CdNDFgG`crKP2MnXafWUV+tW#oF4MxeFc=KqL|Y1>j8p z0&z{ns9riK>xm~vekcF`S221>0KWk|rUEoRKF$M#=8B@+DF{=k6fZp4Y?dVw34TU6 z92UI+)#R(5!^EQNmTY2T0xp-UUZc6bNIIo?pR#*hEm@-gyePIz=iJs=<l(t`# zbm#>X>jQ6Q%tq4#5TL(aQul^_OifMk_N#PkZ*TL6r&=!x4uEd}-d3Zn8UsxO;5~qk zgl1%9gtfP~OO(;5zoT(&-(f)juj;w@ gPX4-a!My& 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() { From 71f8ebe285bb662c881b582cfb2f306a4d3e439b Mon Sep 17 00:00:00 2001 From: Andrii Solianyk Date: Fri, 6 Dec 2024 15:16:57 +0100 Subject: [PATCH 3/4] Statek miga przy uderzeniu w meteoryt --- headers/Player.h | 5 +++++ sources/Actor.cpp | 2 +- sources/Plansza.cpp | 3 ++- sources/Player.cpp | 22 ++++++++++++++++++++++ 4 files changed, 30 insertions(+), 2 deletions(-) diff --git a/headers/Player.h b/headers/Player.h index e6b4c01..d466f17 100644 --- a/headers/Player.h +++ b/headers/Player.h @@ -17,12 +17,17 @@ public: void moveRight() override; void moveUp() override; void moveDown() override; + void onHit(); + void update(); std::vector& getRockets(); private: std::chrono::steady_clock::time_point lastShotTime = std::chrono::steady_clock::now(); std::vector rockets; sf::Texture rocketTexture; sf::Texture bulletTexture; + bool isBlinking = false; + sf::Color originalColor; + }; diff --git a/sources/Actor.cpp b/sources/Actor.cpp index 9a3daf5..429c459 100644 --- a/sources/Actor.cpp +++ b/sources/Actor.cpp @@ -29,7 +29,7 @@ unsigned int Actor::getHP() { } void Actor::dealDamage() { - if(damageDealClock.getElapsedTime().asSeconds() > 1) { + if(damageDealClock.getElapsedTime().asSeconds() > 1.5) { if(hp > 0) { hp--; } diff --git a/sources/Plansza.cpp b/sources/Plansza.cpp index 5ca9831..0708094 100644 --- a/sources/Plansza.cpp +++ b/sources/Plansza.cpp @@ -105,13 +105,14 @@ void Plansza::update() { update_hearts(); ship.updateBullets(); + ship.update(); 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(); + ship.onHit(); } } diff --git a/sources/Player.cpp b/sources/Player.cpp index 12582e5..c26eba8 100644 --- a/sources/Player.cpp +++ b/sources/Player.cpp @@ -7,6 +7,7 @@ Player::Player(int x, int y, std::string path) : Actor(x, y, std::move(path)) { rocketTexture.loadFromFile("../assets/img/rockets/Rocket_111.png"); hp = 3; damageDealClock.restart(); + originalColor = actorSprite.getColor(); }; void Player::shoot() { @@ -25,6 +26,27 @@ void Player::alternate_shoot() { } } +void Player::onHit() { + dealDamage(); + isBlinking = true; +} + +void Player::update() { + if (isBlinking) { + auto elapsed = damageDealClock.getElapsedTime().asMilliseconds(); + if (elapsed < 1000) { // miganie przez 1 sekundę + if ((elapsed / 100) % 2 == 0) { + actorSprite.setColor(sf::Color(255, 255, 255, 128)); // półprzeźroczysty + } else { + actorSprite.setColor(originalColor); // oryginalny kolor + } + } else { + isBlinking = false; + actorSprite.setColor(originalColor); // przywróć oryginalny kolor + } + } +} + void Player::setFirerate(unsigned int firerate) { this->firerate = firerate; } From da33fcc71865379268610442bef6bc97774da2ab Mon Sep 17 00:00:00 2001 From: Andrii Solianyk Date: Tue, 10 Dec 2024 20:37:10 +0100 Subject: [PATCH 4/4] Adjustin hearts to be in right upper corner due to score counter in left upper corner --- sources/Plansza.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sources/Plansza.cpp b/sources/Plansza.cpp index 0708094..6a484cc 100644 --- a/sources/Plansza.cpp +++ b/sources/Plansza.cpp @@ -29,9 +29,9 @@ ship(static_cast(mainWindow->getSize().x) / 2, static_cast(mainWindow- 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); + heartStats[0].setPosition(565, 10); + heartStats[1].setPosition(530, 10); + heartStats[2].setPosition(495, 10); meteorSpawnClock.restart(); } @@ -217,7 +217,7 @@ void Plansza::update() { } - for (auto heart: heartStats) { + for (const auto& heart: heartStats) { window->draw(heart); } }