SUPER Space invader : Turbo edition DX - VS GOD 1.0.0
A simple space invader ripoff
gameManagers.cpp
Go to the documentation of this file.
1
11#include "game.h"
12
13#define ISPRESSED(ID, X) window.isPressed({confData.playerDefs[ID].keys.X, false})
14void Game::manageOnePlayer(playerID pID){
15 Player& p = players[pID];
16 if(p.hasDeathAnimation()) {
18 if (p.deathAnimCounter == 75) {
19 p.deathAnimCounter = 0;
20 }
21 }
22 if(p.isEliminated())return;
23
24 if (ISPRESSED(pID, left)){
25 if(p.x < confData.playersSpeed) p.x = 0;
26 else p.x -= confData.playersSpeed;
27 }
28 if (ISPRESSED(pID, right)){
29 if(p.x + confData.playersWidth + confData.playersSpeed >= pm->getScreenWidth()) p.x = pm->getScreenWidth() - confData.playersWidth - 1;
30 else p.x += confData.playersSpeed;
31 }
32
33
34 if(!p.hasDeathAnimation()) {
35 if(p.fireCooldown==0) {
36 if (ISPRESSED(pID, shoot)) {
37 torpedos.emplace_back(p.x + confData.playersWidth / 2, pm->getScreenHeight() - PLAYER_HEIGHT, pID);
39 }
40 }else --p.fireCooldown;
41 }
42}
43
44void Game::managePlayers(){
45 for(unsigned i=0;i<players.size();++i)manageOnePlayer(i);
46}
47
48bool Game::manageInvaders(){
49 if(!areThereInvadersLeft())return false; // If there are no more invaders we don't need to manage them
50
51 // shoot
52 if(fireCooldown==0) {
53 fireCooldown = confData.invadersFireCooldown + rand() % 25;
54
55 unsigned rdCol = grid.randomValidCol();
56 // fire !
57 missiles.push_back(baseInvPos + Position(
58 confData.invadersSize * rdCol + confData.invadersDistance * (rdCol + 0.5),
59 confData.invadersSize * (grid[rdCol].size() - 1) + confData.invadersDistance * (grid[rdCol].size() - 1)
60 ));
61 }else --fireCooldown;
62
63
64 if(direction){ // go to the right
65 int end = baseInvPos.getX(); // start Position
66 end+= grid.size() * confData.invadersSize; // add the invaders
67 end+= (grid.size()-1) * confData.invadersDistance; // add the invadersDistance between invaders
68 // you got the end position of the invader crowd !
69
70 size_t i = grid.size()-1;
71 while (grid[i].hasNoValid()){
72 end -= (confData.invadersSize + confData.invadersDistance);
73 --i;
74 }
75
76 if(end + confData.invadersSpeed < pm->getScreenWidth()){
77 baseInvPos.setX(baseInvPos.getX() + confData.invadersSpeed);
78 }
79 else{
80 baseInvPos.setY(baseInvPos.getY() + confData.invadersSize + confData.invadersDistance);
81 direction = !direction;
82 return true;
83 }
84 }
85 else{
86 size_t i = 0;
87 unsigned relativeBasePos = baseInvPos.getX();
88 while (grid[i].hasNoValid()){
89 relativeBasePos += confData.invadersSize + confData.invadersDistance;
90 ++i;
91 }
92
93 if(relativeBasePos >= confData.invadersSpeed){
94 baseInvPos.setX(baseInvPos.getX() - confData.invadersSpeed);
95 }else{
96 baseInvPos.setY(baseInvPos.getY() + confData.invadersSize + confData.invadersDistance);
97 direction = !direction;
98 return true;
99 }
100 }
101 return false;
102
103}
104
105void Game::remCollidingProjectiles(){
106
107 auto miss = missiles.begin();
108 auto tor = torpedos.begin();
109
110 while(miss != missiles.end()){
111 bool wasColliding = false;
112 while(tor != torpedos.end()){
113
114 // missiles can't be right under torpedos, so that must means they are colliding in Y
115 if(miss->getY() + confData.missilesLength < tor->getY()){
116
117 }
118 if(areLinesColliding( // now check if they collide in X
119 miss->getX(), miss->getX() + confData.missilesWidth,
120 tor->getX(), tor->getX() + confData.torpedosWidth)){
121 missiles.erase(miss);
122 torpedos.erase(tor);
123 wasColliding = true;
124 break;
125 }
126 ++tor;
127 }
128 /* if it was colling, it was removed and his Position is now replaced by the next.
129 * else, go to the next */
130 if(!wasColliding)++miss;
131 }
132}
133
134void Game::moveMissiles() {
135 auto miss = missiles.begin();
136 while (miss != missiles.end()) {
137 if (miss->getY() >= pm->getScreenHeight())missiles.erase(miss);
138 else {
139 miss->setY(miss->getY()+confData.missilesSpeed);
140 ++miss;
141 }
142 }
143}
144
145void Game::moveTorpedos() {
146 auto tor = torpedos.begin();
147 while (tor != torpedos.end()) {
148 if (tor->getY()+confData.torpedosLength <= 0)torpedos.erase(tor);
149 else{
150 tor->setY(tor->getY()-confData.torpedosSpeed);
151 ++tor;
152 }
153 }
154}
155
156void Game::checkMissilesAndPlayers() {
157 auto miss_ite = missiles.begin();
158 while(miss_ite!=missiles.end()){
159 bool wasColliding = false;
160 if(miss_ite->getY()>=pm->getScreenHeight()-PLAYER_HEIGHT){ // check collision on Y
161 // now check collision on X (with both players)
162 for(Player& p : players){
163 if(p.isPlaying()){
165 miss_ite->getX(), miss_ite->getX() + confData.missilesWidth,
166 p.x, p.x + confData.playersWidth)){
167 wasColliding = true;
168 p.damage();
169 // do not break, the second player also deserves to be hit
170 }
171 }
172 }
173 }
174 if(wasColliding)missiles.erase(miss_ite);
175 else ++miss_ite;
176 }
177}
178
179bool Game::checkTorpedosAndInvaders() {
180 auto tor_ite = torpedos.begin();
181 while(tor_ite!=torpedos.end()){
182 unsigned i=0;
183 for(;i<grid.size();++i){
184
185 unsigned alienIndex = grid[i].getOutterInvader();
186 if(alienIndex==grid[i].size())continue;
187 // calculate top-left Position of invader
188 Position pos = baseInvPos + Position(
189 confData.invadersSize*i+confData.invadersDistance*i,
190 confData.invadersSize*alienIndex+confData.invadersDistance*alienIndex
191 );
192 // check collision on Y (invaders can actually be "under" torpedos, so we check both lower and upper bounds
193 if(pos.getY()+confData.invadersSize>=tor_ite->getY() &&
194 pos.getY()<=tor_ite->getY()+confData.torpedosLength){
195 // now check collision on X
196 if(areLinesColliding( // now check collision on X
197 tor_ite->getX(), tor_ite->getX() + confData.torpedosWidth,
198 pos.getX(), pos.getX() + confData.invadersSize)){
199
200
201 InvaderType invType = grid[i][alienIndex];
202 players[tor_ite->owner].score += confData.invadersDef.at(invType).points;
203 torpedos.erase(tor_ite);
204
205 grid[i][alienIndex] = InvaderType::NONE;
206
207 if(!areThereInvadersLeft()) return true;
208 break;
209 }
210 }
211 }
212 if(i==grid.size()) ++tor_ite;
213 }
214 return false;
215}
216
217bool Game::invadersTouchPlayer() const {
218 return any_of(grid.begin(), grid.end(), [this](const InvadersColumn& line) -> bool {
219 unsigned outter = line.getOutterInvader();
220 return this->baseInvPos.getY() + confData.invadersSize * (outter + 1)
221 +confData.invadersDistance*outter
222 >= pm->getScreenHeight() - PLAYER_HEIGHT;
223 });
224}
Column of invader.
Definition: invadersGrid.h:33
unsigned randomValidCol() const
Returns a random valid column in the grid.
full game logic and display management
#define ISPRESSED(ID, X)
InvaderType
List of all invader type.
Definition: invadersGrid.h:22
unsigned invadersFireCooldown
wait time between two invader missile
Definition: configData.h:92
unsigned playersSpeed
player movement speed
Definition: configData.h:52
unsigned missilesWidth
invaders missiles width in pixel
Definition: configData.h:102
unsigned torpedosLength
virtual value : players torpedos length in pixel - auto defined from width
Definition: configData.h:127
unsigned playersFireCooldown
player shooting wait time
Definition: configData.h:62
unsigned torpedosSpeed
players topedos movement speed
Definition: configData.h:132
unsigned invadersDistance
distance in pixel between two invader
Definition: configData.h:87
unsigned invadersSpeed
invader movement speed
Definition: configData.h:77
unsigned playersWidth
player horizontal size in pixel
Definition: configData.h:57
unsigned invadersSize
invader radius size in pixel
Definition: configData.h:82
unsigned missilesSpeed
invaders missiles movement speed
Definition: configData.h:112
unsigned missilesLength
virtual value : invaders missiles length in pixel - auto defined from width
Definition: configData.h:107
unsigned torpedosWidth
players torpedos width in pixel
Definition: configData.h:122
map< InvaderType, InvaderTypeDef > invadersDef
link between an invader type, and its data
Definition: configData.h:97
player data structure
Definition: player.h:19
unsigned deathAnimCounter
counter used for the death animation of players undefined once the player is eliminated
Definition: player.h:45
bool hasDeathAnimation() const
Tells if the player has a death animation ongoing.
Definition: player.cpp:18
unsigned fireCooldown
player's shooting cooldown
Definition: player.h:50
bool isEliminated() const
Tells if the player is eliminated (no more lives)
Definition: player.cpp:22
unsigned x
x coordinate of the player
Definition: player.h:29
unsigned playerID
Definition: utils.h:52
#define PLAYER_HEIGHT
Definition: utils.h:19
bool areLinesColliding(unsigned start1, unsigned end1, unsigned start2, unsigned end2)
tells if 2 lines are colliding in a 1 dimensional space. Didn't want to use Position because of the s...
Definition: utils.cpp:3
nsGraphics::Vec2D Position
Definition: utils.h:51