-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathalienArmy.cpp
More file actions
224 lines (197 loc) · 6.89 KB
/
alienArmy.cpp
File metadata and controls
224 lines (197 loc) · 6.89 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
// alienArmy.cpp
// Implementation of the AlienArmy class for managing alien entities in the
// game.
//
// MILTON ADINA
// Programming II Final Project
// alienArmy.cpp
// 13/04/2024
#include "alienArmy.h"
#include <algorithm> // For std::remove_if
#include <chrono>
#include <iostream>
#include <thread> // Include this for std::thread
// constructor for the alien army
/**
* @brief Constructs an instance of the AlienArmy class.
* Initializes the `alienTexture` to an empty texture, `timeSinceLastFire` to
* 0.0f, and `fireRate` to 1.0f.
*/
AlienArmy::AlienArmy()
: timeSinceLastFire(0.0f), fireRate(1.0f), score(0),
rng(std::random_device{}()), distribution(0.0f, 1.0f) {
loadMissileTexture("missile.png");
}
// load the missile texture
/**
* @brief Loads the missile texture from the specified file.
*
* @param filename The name of the file containing the missile texture.
* @return True if the texture is loaded successfully, false otherwise.
*/
bool AlienArmy::loadMissileTexture(const std::string &filename) {
return missileTexture.loadFromFile(filename);
}
// add an alien to the army
/**
* @brief Adds an alien to the alien army.
*
* @param alien The alien to be added.
*/
void AlienArmy::addAlien(const Pixie &alien) { aliens.push_back(alien); }
/**
* Moves the alien army horizontally and vertically.
* Reverses the direction of movement when the edge is reached.
*/
void AlienArmy::moveArmy(float deltaTime) {
static bool movingRight = true; // Bool to move right
bool edgeReached = false; // Bool to check if edge is reached
// Loop to move the aliens
for (auto &alien : aliens) {
float moveX =
movingRight
? ALIEN_SPEED * deltaTime
: -ALIEN_SPEED * deltaTime; // Calculate the horizontal movement
alien.move(moveX, 0); // Move the alien horizontally
// Check if the edge is reached
if (movingRight &&
alien.getX() + alien.getSprite().getGlobalBounds().size.x >=
WINDOW_WIDTH ||
!movingRight && alien.getX() <= 0) {
edgeReached = true; // Set edgeReached to true
}
}
// Move the aliens down and reverse the direction if the edge is reached
if (edgeReached) {
for (auto &alien : aliens) {
alien.move(0, 10); // Move the alien down by a step
}
movingRight = !movingRight; // Reverse the direction
}
}
/**
* Fires missiles from the alien army.
*
* @param deltaTime The time elapsed since the last frame.
*/
void AlienArmy::fireMissiles(float deltaTime) {
// Increase the time since the last shot
timeSinceLastFire += deltaTime;
// Check if it's time to fire based on the firing rate
if (timeSinceLastFire >= fireRate) {
timeSinceLastFire = 0.0f; // Reset the time since the last fire
// Iterate through each alien to determine if it should fire
for (const auto &alien : aliens) {
// Randomly determine whether the alien should fire
float randomValue = distribution(rng);
float firingProbability = 0.05f; // Adjust this probability as needed
if (randomValue < firingProbability) {
missiles.push_back(Pixie(
missileTexture,
alien.getX() + alien.getSprite().getGlobalBounds().size.x / 2,
alien.getY() + alien.getSprite().getGlobalBounds().size.y,
PLAYER_MISSILE_PIXIE)); // Create a missile and add it to the vector
}
}
}
}
/**
* Updates the position of the missiles fired by the alien army.
* Removes the missiles that have gone out of the window.
*/
void AlienArmy::updateMissiles() {
for (auto &missile : missiles) {
missile.move(0, MISSILE_SPEED); // Move the missile vertically
if (missile.getY() >
WINDOW_HEIGHT) { // Check if the missile is out of the window
missile.setVisible(false); // Mark for deletion
}
}
// Actually remove them
missiles.erase(std::remove_if(missiles.begin(), missiles.end(),
[](const Pixie &m) { return !m.isVisible(); }),
missiles.end());
}
/**
* Handles collisions between player missiles, aliens, and the ship.
*
* @param playerMissiles The vector of player missiles.
* @param ship The pointer to the ship object.
*/
void AlienArmy::handleCollisions(std::vector<Pixie> &playerMissiles,
Pixie *ship, float &respawnTimer) {
// Collision detection between player missiles and aliens
for (auto &alien : aliens) {
if (!alien.isVisible())
continue;
for (auto &missile : playerMissiles) {
if (!missile.isVisible())
continue;
if (alien.getSprite()
.getGlobalBounds()
.findIntersection(missile.getSprite().getGlobalBounds())
.has_value()) {
score += 10;
std::cout << "Alien hit! Score: " << score << std::endl;
// Mark both for deletion
alien.setVisible(false);
missile.setVisible(false);
break; // A missile can only hit one alien, and this alien is now dead
}
}
}
// Check collisions between alien missiles and the ship
if (ship && ship->isVisible()) {
for (auto &missile : missiles) {
if (!missile.isVisible())
continue;
if (missile.getSprite()
.getGlobalBounds()
.findIntersection(ship->getSprite().getGlobalBounds())
.has_value()) {
std::cout << "Ship hit by alien missile!" << std::endl;
ship->setVisible(false);
respawnTimer = 1.0f; // Set respawn delay to 1 second
missile.setVisible(false); // The missile is destroyed on impact
}
}
}
// Sweep the dead entities efficiently from vector memory
aliens.erase(std::remove_if(aliens.begin(), aliens.end(),
[](const Pixie &a) { return !a.isVisible(); }),
aliens.end());
missiles.erase(std::remove_if(missiles.begin(), missiles.end(),
[](const Pixie &m) { return !m.isVisible(); }),
missiles.end());
playerMissiles.erase(
std::remove_if(playerMissiles.begin(), playerMissiles.end(),
[](const Pixie &m) { return !m.isVisible(); }),
playerMissiles.end());
}
/**
* Draws the alien army on the specified window.
*
* @param window The SFML RenderWindow to draw the aliens on.
*/
void AlienArmy::drawArmy(sf::RenderWindow &window) {
// Loop through each alien in the army
for (auto &alien : aliens) {
alien.draw(window); // Draw the alien on the window
}
}
/**
* Draws the missiles fired by the alien army on the specified window.
*
* @param window The SFML RenderWindow to draw the missiles on.
*/
void AlienArmy::drawMissiles(sf::RenderWindow &window) {
for (auto &missile : missiles) {
missile.draw(window);
}
}
/**
* Checks if all aliens in the army have been destroyed.
*
* @return True if all aliens are destroyed, false otherwise.
*/
bool AlienArmy::isAllDestroyed() const { return aliens.empty(); }