SUPER Space invader : Turbo edition DX - VS GOD 1.0.0
A simple space invader ripoff
gameBasics.cpp
Go to the documentation of this file.
1
12#include <chrono>
13#include <thread>
14#include "game.h"
15#include "playMode.h"
17
18#define WININIT window("SUPER Space Invader : Turbo Apocalypse DX - VS GOD", Position(1280, 720), Position(128, 128), nsGraphics::KBlack)
19
21
22 if(!reloadConfig()){ // Config
23 throw runtime_error("Initial config loading failed. Please check the error above and fix the configuration");
24 }
25
26 // Pixel Manager
27 if(confData.theme=="good"){
28 pm = std::make_unique<GoodPixelManager>(window);
29 }else if(confData.theme=="bad"){
30 pm = std::make_unique<PixelManager>(window);
31 }else throw runtime_error("Invalid theme value : "+confData.theme+
32 "\nValid values are : good,bad");
33
34 cout << "Loading sprites..." << endl;
35 vector<Task> tasks;
36 chrono::high_resolution_clock::time_point start = chrono::high_resolution_clock::now();
37
38 pm->loadSprites(tasks);
39 for(Task& f : tasks)f.wait();
40
41 // We just do that for one sprite, so I didn't bother creating an 'API' for that
42 pm->leftHand.mirror(pm->rightHand);
43
44 chrono::high_resolution_clock::duration elapsed = chrono::high_resolution_clock::now()-start;
45 cout << "Done ! Time : " << chrono::duration_cast<chrono::milliseconds>(elapsed).count() << "ms" << endl;
46
47 sm.readFile(); // Score manager
48}
49
50bool Game::areThereInvadersLeft(){
51 return grid.validColsNumber() > 0;
52}
53
54void Game::handleScoreSaving(){
55 for(unsigned i=0;i<players.size();++i){
56 string pName;
57 pm->askPlayerNameMenu(i, players[i].score, pName);
58 sm.inputScore(move(pName), players[i].score);
59 }
60 sm.writeFile();
61}
62
64
65 playMode = PlayMode::NONE;
66 WinValue whoWon;
67
68 while(playMode!=PlayMode::EXIT){
69 if(playMode==PlayMode::NONE){
70 playMode = pm->showInitialMenu();
71 }else{
72 DEBUG_MSG("Starting game")
73 initGame();
74 whoWon = enterGameLoop(); // will read the playMode
75 DEBUG_MSG("END End of game")
76 handleScoreSaving();
77 if(!pm->showDeathMenu(sm.scores, whoWon))playMode = PlayMode::NONE;
78 }
79 }
80}
81
82// we assume the game has been played before, and so we need to clean used members
84 grid = confData.grid; // will copy the grid
85
86 // we re-construct players objects, we don't have to clear all members and can rely on the construction value (set in .h file)
87 players.clear();
88
89 missiles.clear();
91 torpedos.clear();
92
93 if(playMode==PlayMode::SINGLE){
94 players.resize(1);
95 }else{
96 players.resize(2);
97 // mirror the start X Position for the other
98 players[1].x = pm->getScreenWidth() - confData.startXPosition - confData.playersWidth;
99 }
100 players[0].x = confData.startXPosition;
101
102 for(unsigned i=0;i<players.size();++i){
103 players[i].id = i;
104 players[i].lives = confData.playersLives;
105 }
106
107 baseInvPos = Position(200, 0);
108 direction = true;
109
110}
111
112#define START_TIMER() DEBUG_INSTR(debugTime = chrono::high_resolution_clock::now())
113#define PRINT_TIMER(X) DEBUG_MSG((X) << ": " << chrono::duration_cast<chrono::nanoseconds>(chrono::high_resolution_clock::now()-debugTime).count())
114
115WinValue Game::enterGameLoop(){ // returns when game is finished
116 // computed in advance for performance reasons
117 chrono::milliseconds maxFrameTime = chrono::milliseconds(1000/confData.maxFPS);
118
119 unsigned tmpFps = 0;
120 unsigned fps = 0;
121 typedef chrono::high_resolution_clock::time_point MyTimePoint;
122 MyTimePoint fpsStartTime = {};
123
124 while(window.isOpen()){
125
126 MyTimePoint startTime = chrono::high_resolution_clock::now();
127 if(fpsStartTime.time_since_epoch()==chrono::seconds(0)){
128 fpsStartTime = startTime;
129 }
130
131 pm->startFrame();
132
133 managePlayers();
134 if(manageInvaders()) { // if they went down
135 if (invadersTouchPlayer())return WinValue::INVADERS;
136 tryAwakeGod();
137 }
138
139 if(manageGod())return WinValue::PLAYERS;
140 if(arePlayersDead())return WinValue::GOD;
141
142 moveMissiles();
143 remCollidingProjectiles();
144 moveTorpedos();
145 remCollidingProjectiles();
146
147 checkMissilesAndPlayers();
148 if(checkTorpedosAndInvaders())return WinValue::PLAYERS;
149
151
152 displayAll(fps);
153
154 pm->endFrame();
155
156 MyTimePoint endTime = chrono::high_resolution_clock::now();
157
158 // This code is counted as part of frames, but that's not really something we can control
159 if(fpsStartTime+chrono::seconds(1) < endTime){
160 fps = tmpFps;
161 tmpFps = 0;
162 fpsStartTime = {};
163 }else ++tmpFps;
164
165 this_thread::sleep_until(startTime+maxFrameTime);
166 }
167
168 return WinValue::NOBODY;
169}
170
171Position Game::invIndexToPos(unsigned x, unsigned y) const {
172 return baseInvPos + Position(INV_GET_SINGLE_POS(x), INV_GET_SINGLE_POS(y));
173}
174
176 return all_of(players.begin(), players.end(), [](Player& p) -> bool {return p.isEliminated();});
177}
void managedGames()
start games managed by our class
Definition: gameBasics.cpp:63
WinValue enterGameLoop()
enter the main gameplay game loop. Will block until the game ends
Definition: gameBasics.cpp:115
void initGame()
Set or reset all the setting for a new game.
Definition: gameBasics.cpp:83
Game()
constructor for the game class
Definition: gameBasics.cpp:20
bool arePlayersDead()
tells if all players are dead
Definition: gameBasics.cpp:175
GodState state
god's current state
Definition: god.h:53
unsigned validColsNumber() const
Helper function for randomValidCol() that returns the number of valid column (at least one invader in...
vector< ScoreLink > scores
list of pairs of player names and their score
Definition: scoresManager.h:57
void writeFile() const
write the score list into the score file
void inputScore(string name, unsigned score)
add player name and their score in the list of scores
full game logic and display management
#define WININIT
Definition: gameBasics.cpp:18
Manages screen display with async sprite loading.
game mode options
unsigned startXPosition
players horizontal start position
Definition: configData.h:47
unsigned playersLives
player life points
Definition: configData.h:67
InvadersGrid grid
Invader type matrix.
Definition: configData.h:42
unsigned playersWidth
player horizontal size in pixel
Definition: configData.h:57
unsigned maxFPS
maximum framerate at which the game will run
Definition: configData.h:37
player data structure
Definition: player.h:19
#define INV_GET_SINGLE_POS(i)
Definition: utils.h:22
future< void > Task
Definition: utils.h:53
#define DEBUG_MSG(X)
Definition: utils.h:32
nsGraphics::Vec2D Position
Definition: utils.h:51
WinValue
list of win values
Definition: utils.h:43