diff --git a/CMakeLists.txt b/CMakeLists.txt index d09862e..56d75e3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -30,6 +30,8 @@ add_executable(LotoStatek main.cpp sources/ObjectItem.cpp sources/Enemy.cpp headers/Enemy.h + headers/EnemyBullet.h + sources/EnemyBullet.cpp ) if(WIN32) diff --git a/assets/img/bullets/enemy_bullet.png b/assets/img/bullets/enemy_bullet.png new file mode 100644 index 0000000..5574a54 Binary files /dev/null and b/assets/img/bullets/enemy_bullet.png differ diff --git a/headers/Bullet.h b/headers/Bullet.h index d6bc301..cc29809 100644 --- a/headers/Bullet.h +++ b/headers/Bullet.h @@ -8,6 +8,8 @@ class Bullet : public Projectile { public: Bullet(float x, float y, sf::Texture &texture) : Projectile(x,y, texture) {}; void update() override; +private: + float directionY; }; diff --git a/headers/Enemy.h b/headers/Enemy.h index c9ec2a3..4af000d 100644 --- a/headers/Enemy.h +++ b/headers/Enemy.h @@ -4,6 +4,13 @@ #include "Actor.h" #include "SFML/System/Clock.hpp" +enum class Direction { + Up, + Down, + Left, + Right +}; + class Enemy : public Actor { public: Enemy(int x, int y, std::string path); @@ -14,12 +21,19 @@ public: void moveRight() override; void moveUp() override; void moveDown() override; + + void update(); + bool isAlive() const; void takeDamage(); + void updateDirection(); private: sf::Clock shootClock; + sf::Texture enemyBulletTexture; + float movementSpeed = 2.0f; bool alive = true; + Direction direction = Direction::Down; }; #endif // ENEMY_H diff --git a/headers/EnemyBullet.h b/headers/EnemyBullet.h new file mode 100644 index 0000000..ce733db --- /dev/null +++ b/headers/EnemyBullet.h @@ -0,0 +1,14 @@ +#ifndef ENEMY_BULLET_H +#define ENEMY_BULLET_H + +#include "Projectile.h" + +class EnemyBullet : public Projectile { +public: + EnemyBullet(float x, float y, sf::Texture &texture); + void update() override; + + void setOutOfBounds(bool status); +}; + +#endif // ENEMY_BULLET_H diff --git a/headers/Plansza.h b/headers/Plansza.h index 9a46da7..1fb9d2a 100644 --- a/headers/Plansza.h +++ b/headers/Plansza.h @@ -25,6 +25,7 @@ public: void update_meteors(); void update(); void spawn_enemy(); + void setOutOfBounds(bool status); private: Size size; Background background; diff --git a/sources/Actor.cpp b/sources/Actor.cpp index 2170a24..6ee0d0b 100644 --- a/sources/Actor.cpp +++ b/sources/Actor.cpp @@ -1,5 +1,7 @@ #include "../headers/Actor.h" +#include + Actor::Actor(int x, int y, std::string path) { loadTexture(path); position.x = x; @@ -29,13 +31,17 @@ std::vector &Actor::getBullets() { } void Actor::updateBullets() { - for (auto& bullet : bullets) { - if(bullet.isOutOfBounds()) { - bullets.erase(bullets.begin()); + for (auto it = bullets.begin(); it != bullets.end(); ) { + if (it->isOutOfBounds()) { + it = bullets.erase(it); // Usuwa element i zwraca iterator na następny element + } else { + ++it; // Przechodzi do następnego elementu } } + std::cout << "Liczba pociskow: " << bullets.size() << std::endl; } + void Actor::setMovingSpeed(float speed) { moving_speed = speed; } diff --git a/sources/Enemy.cpp b/sources/Enemy.cpp index db69af5..7404e50 100644 --- a/sources/Enemy.cpp +++ b/sources/Enemy.cpp @@ -3,28 +3,71 @@ Enemy::Enemy(int x, int y, std::string path) : Actor(x, y, path) { hp = 1; // Przeciwnik ma 1 punkt życia - firerate = 1000; // Strzela co 1 sekundę + firerate = 2000; // Strzela co 1 sekundę moving_speed = 2.0f; // Prędkość ruchu przeciwnika + enemyBulletTexture.loadFromFile("../assets/img/bullets/enemy_bullet.png"); } void Enemy::shoot() { if (shootClock.getElapsedTime().asMilliseconds() >= firerate) { - bullets.emplace_back(position.x, position.y + 20, bulletTextureLeft); // Strzał w dół + Bullet bullet(position.x, position.y + actorSprite.getGlobalBounds().height / 2, enemyBulletTexture); + bullet.setSpeed(10.0f); // Prędkość w dół + bullets.emplace_back(std::move(bullet)); shootClock.restart(); } } +void Enemy::updateDirection() { + // Zmieniamy kierunek przeciwnika, gdy dotrze do krawędzi + if (position.y <= 0) { // Górna krawędź ekranu + direction = Direction::Down; // Zmieniamy na ruch w dół + } else if (position.y >= 800) { // Dolna krawędź ekranu + direction = Direction::Up; // Zmieniamy na ruch w górę + } + + // Podobna logika dla kierunku lewo/prawo, jeśli przeciwnik będzie się poruszał w poziomie + if (position.x <= 0) { // Lewa krawędź + direction = Direction::Right; // Zmieniamy na ruch w prawo + } else if (position.x >= 1200) { // Prawa krawędź + direction = Direction::Left; // Zmieniamy na ruch w lewo + } +} + void Enemy::move(float deltaX, float deltaY) { actorSprite.move(deltaX, deltaY); position.x += static_cast(deltaX); position.y += static_cast(deltaY); } + + void Enemy::moveLeft() { move(-moving_speed, 0.0f); } void Enemy::moveRight() { move(moving_speed, 0.0f); } void Enemy::moveUp() { move(0.0f, -moving_speed); } void Enemy::moveDown() { move(0.0f, moving_speed); } +void Enemy::update() { + // Sprawdzamy, czy przeciwnik dotarł do krawędzi i zmieniamy kierunek + updateDirection(); + + // Zgodnie z kierunkiem, poruszamy przeciwnikiem + switch (direction) { + case Direction::Up: + moveUp(); + break; + case Direction::Down: + moveDown(); + break; + case Direction::Left: + moveLeft(); + break; + case Direction::Right: + moveRight(); + break; + } +} + + bool Enemy::isAlive() const { return alive; } diff --git a/sources/EnemyBullet.cpp b/sources/EnemyBullet.cpp new file mode 100644 index 0000000..67955fd --- /dev/null +++ b/sources/EnemyBullet.cpp @@ -0,0 +1,18 @@ +#include "../headers/EnemyBullet.h" + +EnemyBullet::EnemyBullet(float x, float y, sf::Texture &texture) + : Projectile(x, y, texture) { + speed = 5.0f; // Ruch w dół (dodatnia prędkość) +} + +void EnemyBullet::update() { + sprite.move(0.0f, speed); // Przesuwanie pocisku w dół + position.y += speed; + + if (position.y > 800) { + outOfBounds = true; + } +} +void EnemyBullet::setOutOfBounds(bool status) { + outOfBounds = status; +} \ No newline at end of file diff --git a/sources/Plansza.cpp b/sources/Plansza.cpp index 8e62473..d9f3a7b 100644 --- a/sources/Plansza.cpp +++ b/sources/Plansza.cpp @@ -159,7 +159,7 @@ void Plansza::update() { } // Ruch i renderowanie przeciwników for (auto it = enemies.begin(); it != enemies.end();) { - it->moveDown(); // Przeciwnicy poruszają się w dół + it->update(); // Aktualizacja kierunku i ruchu przeciwnika it->shoot(); // Rysowanie przeciwników @@ -173,6 +173,28 @@ void Plansza::update() { } } + for (auto& enemy : enemies) { // Lista przeciwników w grze + 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;