New Projectiles class

Refactor of Bullet class
Different method of shooting.
This commit is contained in:
2024-12-01 17:44:25 +01:00
parent 2f6c98f4be
commit 2341c2fa6d
11 changed files with 127 additions and 62 deletions

View File

@@ -19,7 +19,11 @@ add_executable(LotoStatek main.cpp
sources/Bullet.cpp sources/Bullet.cpp
headers/Meteor.h headers/Meteor.h
sources/Meteor.cpp sources/Meteor.cpp
headers/RandomNumberGenerator.h) headers/RandomNumberGenerator.h
headers/Projectile.h
sources/Projectile.cpp
headers/Rocket.h
sources/Rocket.cpp)
if(WIN32) if(WIN32)
set(SFML_ROOT "${CMAKE_SOURCE_DIR}/SFML") set(SFML_ROOT "${CMAKE_SOURCE_DIR}/SFML")

View File

@@ -1,28 +1,13 @@
#ifndef LOTOSTATEK_BULLET_H #ifndef LOTOSTATEK_BULLET_H
#define LOTOSTATEK_BULLET_H #define LOTOSTATEK_BULLET_H
#include "SFML/Graphics/Sprite.hpp" #include "Projectile.h"
#include "SFML/Graphics/Texture.hpp" #include "SFML/Graphics/Texture.hpp"
class Bullet { class Bullet : public Projectile {
struct Position {
int x;
int y;
};
public: public:
Bullet(float x, float y); Bullet(float x, float y, sf::Texture &texture) : Projectile(x,y, texture) {};
sf::Sprite &getSprite(); void update() override;
void setSpeed(float speed);
bool getStatus() const;
void update();
static sf::Texture bulletTexture;
static sf::Texture rocketTexture;
private:
sf::Sprite bulletSprite;
Position bulletPosition;
float bulletSpeed;
bool outOfBounds;
}; };

View File

@@ -4,6 +4,7 @@
#include <chrono> #include <chrono>
#include "Actor.h" #include "Actor.h"
#include "Rocket.h"
class Player : public Actor { class Player : public Actor {
public: public:
@@ -16,10 +17,12 @@ public:
void moveRight() override; void moveRight() override;
void moveUp() override; void moveUp() override;
void moveDown() override; void moveDown() override;
std::vector<Rocket>& getRockets();
private: private:
std::chrono::steady_clock::time_point lastShotTime = std::chrono::steady_clock::now(); std::chrono::steady_clock::time_point lastShotTime = std::chrono::steady_clock::now();
std::vector<Bullet> rightBullets; std::vector<Rocket> rockets;
sf::Texture rocketTexture;
sf::Texture bulletTexture;
}; };

27
headers/Projectile.h Normal file
View File

@@ -0,0 +1,27 @@
#ifndef PROJECTILE_H
#define PROJECTILE_H
#include <SFML/Graphics/Sprite.hpp>
class Projectile {
struct Position {
int x;
int y;
};
public:
Projectile(float x, float y, sf::Texture &texture);
sf::Sprite &getSprite();
void setSpeed(float speed);
bool isOutOfBounds() const;
virtual void update() = 0;
static sf::Texture texture;
protected:
~Projectile() = default;
sf::Sprite sprite;
Position position{};
float speed;
bool outOfBounds;
};
#endif //PROJECTILE_H

14
headers/Rocket.h Normal file
View File

@@ -0,0 +1,14 @@
#ifndef ROCKET_H
#define ROCKET_H
#include "Projectile.h"
class Rocket : public Projectile{
public:
Rocket(float x, float y, sf::Texture &texture) : Projectile(x,y, texture) {};
void update() override;
};
#endif //ROCKET_H

View File

@@ -102,6 +102,11 @@ int main()
mainWindow.draw(bullet.getSprite()); mainWindow.draw(bullet.getSprite());
} }
for (auto& rocket : ship.getRockets()) {
rocket.update();
mainWindow.draw(rocket.getSprite());
}
// Sprawdzenie czy meteory i pociski są poza granicami ekranu // Sprawdzenie czy meteory i pociski są poza granicami ekranu
plansza.update_meteors(); plansza.update_meteors();
ship.updateBullets(); ship.updateBullets();
@@ -143,14 +148,31 @@ int main()
for (auto meteorIt = plansza.getMeteors().begin(); meteorIt != plansza.getMeteors().end(); ) { for (auto meteorIt = plansza.getMeteors().begin(); meteorIt != plansza.getMeteors().end(); ) {
bool meteorHit = false; bool meteorHit = false;
for (auto bulletIt = ship.getBullets().begin(); bulletIt != ship.getBullets().end(); ) { for (auto rocketIt = ship.getBullets().begin(); rocketIt != ship.getBullets().end(); ) {
if (meteorIt->getSprite().getGlobalBounds().intersects(bulletIt->getSprite().getGlobalBounds())) { if (meteorIt->getSprite().getGlobalBounds().intersects(rocketIt->getSprite().getGlobalBounds())) {
bulletIt = ship.getBullets().erase(bulletIt); ship.getBullets().erase(rocketIt);
meteorIt = plansza.getMeteors().erase(meteorIt); meteorIt = plansza.getMeteors().erase(meteorIt);
meteorHit = true; meteorHit = true;
break; break;
} else { } else {
++bulletIt; ++rocketIt;
}
}
if (!meteorHit) {
++meteorIt;
}
}
for (auto meteorIt = plansza.getMeteors().begin(); meteorIt != plansza.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 = plansza.getMeteors().erase(meteorIt);
meteorHit = true;
break;
} else {
++rocketIt;
} }
} }
if (!meteorHit) { if (!meteorHit) {

View File

@@ -30,7 +30,7 @@ std::vector<Bullet> &Actor::getBullets() {
void Actor::updateBullets() { void Actor::updateBullets() {
for (auto& bullet : bullets) { for (auto& bullet : bullets) {
if(bullet.getStatus()) { if(bullet.isOutOfBounds()) {
bullets.erase(bullets.begin()); bullets.erase(bullets.begin());
} }
} }

View File

@@ -1,35 +1,9 @@
#include <iostream>
#include "../headers/Bullet.h" #include "../headers/Bullet.h"
Bullet::Bullet(float x, float y) {
bulletPosition.x = x;
bulletPosition.y = y;
outOfBounds = false;
bulletSprite.setTexture(Bullet::bulletTexture);
bulletSprite.setOrigin(bulletSprite.getLocalBounds().width/2, bulletSprite.getLocalBounds().height/2);
bulletSprite.setPosition(x, y);
bulletSpeed = -10.0f;
}
void Bullet::setSpeed(float speed) {
bulletSpeed = speed;
}
sf::Sprite &Bullet::getSprite() {
return bulletSprite;
}
void Bullet::update() { void Bullet::update() {
bulletSprite.move(0.0f, bulletSpeed); sprite.move(0.0f, speed);
bulletPosition.y += int(bulletSpeed); position.y += int(speed);
if(bulletPosition.y < -100) { if(position.y < -100) {
outOfBounds = true; outOfBounds = true;
} }
} }
bool Bullet::getStatus() const {
return outOfBounds;
}
sf::Texture Bullet::bulletTexture = sf::Texture(); // plain init of static field
sf::Texture Bullet::rocketTexture = sf::Texture();

View File

@@ -3,22 +3,22 @@
// TODO: Podzielić na klasy Bullet i Rocket. // TODO: Podzielić na klasy Bullet i Rocket.
Player::Player(int x, int y, std::string path) : Actor(x, y, path) { Player::Player(int x, int y, std::string path) : Actor(x, y, path) {
Bullet::bulletTexture.loadFromFile("../assets/img/bullet_left.png"); bulletTexture.loadFromFile("../assets/img/bullet_left.png");
rocketTexture.loadFromFile("../assets/img/Rocket_111.png");
}; };
void Player::shoot() { void Player::shoot() {
auto now = std::chrono::steady_clock::now(); auto now = std::chrono::steady_clock::now();
if (std::chrono::duration_cast<std::chrono::milliseconds>(now - lastShotTime).count() >= firerate) { if (std::chrono::duration_cast<std::chrono::milliseconds>(now - lastShotTime).count() >= firerate) {
bullets.emplace_back(position.x, position.y); bullets.emplace_back(position.x, position.y, bulletTexture);
lastShotTime = now; lastShotTime = now;
} }
} }
// TODO: Czy strzał prawym musi mieć osobną tablicę z pociskami?
void Player::alternate_shoot() { void Player::alternate_shoot() {
auto now = std::chrono::steady_clock::now(); auto now = std::chrono::steady_clock::now();
if (std::chrono::duration_cast<std::chrono::milliseconds>(now - lastShotTime).count() >= firerate) { if (std::chrono::duration_cast<std::chrono::milliseconds>(now - lastShotTime).count() >= firerate) {
rightBullets.emplace_back(position.x, position.y).getSprite().scale(1.5f, 1.5f); rockets.emplace_back(position.x, position.y, rocketTexture).getSprite().scale(1.5f, 1.5f);
lastShotTime = now; lastShotTime = now;
} }
} }
@@ -49,4 +49,8 @@ void Player::moveUp() {
void Player::moveDown() { void Player::moveDown() {
move(0.0f, moving_speed); move(0.0f, moving_speed);
position.y += static_cast<int>(moving_speed); position.y += static_cast<int>(moving_speed);
} }
std::vector<Rocket> &Player::getRockets() {
return rockets;
}

23
sources/Projectile.cpp Normal file
View File

@@ -0,0 +1,23 @@
#include "../headers/Projectile.h"
Projectile::Projectile(float x, float y, sf::Texture &texture) {
position.x = x;
position.y = y;
outOfBounds = false;
sprite.setTexture(texture);
sprite.setOrigin(sprite.getLocalBounds().width/2, sprite.getLocalBounds().height/2);
sprite.setPosition(x, y);
speed = -10.0f;
}
sf::Sprite &Projectile::getSprite() {
return sprite;
}
void Projectile::setSpeed(float speed) {
this->speed = speed;
}
bool Projectile::isOutOfBounds() const {
return outOfBounds;
}

9
sources/Rocket.cpp Normal file
View File

@@ -0,0 +1,9 @@
#include "../headers/Rocket.h"
void Rocket::update() {
sprite.move(0.0f, speed);
position.y += int(speed);
if(position.y < -100) {
outOfBounds = true;
}
}