did a shitload of things that 50% work

This commit is contained in:
Thomas 2021-12-31 17:18:23 +01:00
parent b0518e9539
commit e70def8e83
No known key found for this signature in database
GPG Key ID: E538821A6CDFDAD7
15 changed files with 197 additions and 93 deletions

4
README
View File

@ -1,8 +1,10 @@
Conventions à suivre : Conventions à suivre :
camelCase pour les noms de variables/fonctions/fichiers camelCase pour les noms de variables/fonctions
PascalCase pour les noms de classes/structures PascalCase pour les noms de classes/structures
snake case pour les noms de fichiers
Nommage en anglais Nommage en anglais
Pas de fonctions de +100 lignes Pas de fonctions de +100 lignes
Les guards sont de cette forme : GUARD_<filename>_H
écran : constante 1280x720 écran : constante 1280x720

View File

@ -1,5 +1,5 @@
# User config # Players config
users: players:
width: 250 width: 250
startPositionX: 0 startPositionX: 0
speed: 5 speed: 5

View File

@ -1,11 +1,14 @@
#ifndef GUARD_CONFIG #ifndef GUARD_CONFIG_H
#define GUARD_CONFIG #define GUARD_CONFIG_H
#include<vector> #include<vector>
#include "utils.h" #include "utils.h"
#include "player_def.h"
using namespace std; using namespace std;
typedef string configKey;
class Config{ class Config{
public: public:
aliensGrid grid; aliensGrid grid;
@ -22,7 +25,14 @@ public:
unsigned alien_speed; unsigned alien_speed;
unsigned player_speed; unsigned player_speed;
PlayerDef p1Def;
PlayerDef p2Def;
unsigned startXPosition;
bool loadConfig(); bool loadConfig();
string getString(configKey& key);
int getInt(configKey& key);
nsGraphics::RGBAcolor getColor(configKey& key);
}; };
#endif #endif

View File

@ -6,6 +6,9 @@
#include "config.h" #include "config.h"
#include "utils.h" #include "utils.h"
#include "position.h" #include "position.h"
#include "player_def.h"
#include "player.h"
#include "play_mode.h"
using namespace std; using namespace std;
@ -21,27 +24,31 @@ private:
vector<missile> missiles; vector<missile> missiles;
vector<torpedo> torpedos; vector<torpedo> torpedos;
unsigned playerX;
void managePlayer(); PlayMode playMode;
Player p1;
Player p2;
void managePlayers();
bool manageInvaders(); bool manageInvaders();
void display(); void display();
// collision thingies // collision thingies
unsigned manageAllCollisions();
void remCollidingProjectiles(); void remCollidingProjectiles();
void moveMissiles(); void moveMissiles();
void moveTorpedos(); void moveTorpedos();
bool checkMissilesAndPlayer(); bool checkMissilesAndPlayers();
bool checkTorpedosAndInvaders(); bool checkTorpedosAndInvaders();
bool invadersTouchFloor(); bool invadersTouchPlayer();
void managePlayerMoves(PlayerDef&, unsigned&);
public: public:
// in case someone wants to mess with the code, here's a minimal API, costs nothing to us // in case someone wants to mess with the code, here's a minimal API, costs nothing to us
Game(); Game();
void managedGames(); void managedGames();
unsigned playGame(); WinValue playGame();
void initialMenuHandler(); PlayMode initialMenuHandler();
void deathMenuHandler(); bool deathMenuHandler();
}; };

View File

@ -1,5 +1,5 @@
#ifndef GUARD_DRAWENGINE #ifndef GUARD_DRAWENGINE_H
#define GUARD_DRAWENGINE #define GUARD_DRAWENGINE_H
#include "mingl/mingl.h" #include "mingl/mingl.h"
#include "mingl/shape/line.h" #include "mingl/shape/line.h"
@ -14,7 +14,7 @@ public:
void dessinerInvader1(const nsGraphics::Vec2D& baseVector, unsigned size); void dessinerInvader1(const nsGraphics::Vec2D& baseVector, unsigned size);
void dessinerInvader2(const nsGraphics::Vec2D& baseVector, unsigned size); void dessinerInvader2(const nsGraphics::Vec2D& baseVector, unsigned size);
void dessinerInvader3(const nsGraphics::Vec2D& baseVector, unsigned size); void dessinerInvader3(const nsGraphics::Vec2D& baseVector, unsigned size);
void dessinerJoueur(const nsGraphics::Vec2D& baseVector, unsigned size); void dessinerJoueur(const nsGraphics::Vec2D& baseVector, unsigned size, const nsGraphics::RGBAcolor&);
unsigned showInitialMenu(); unsigned showInitialMenu();
unsigned showDeathMenu(); unsigned showDeathMenu();

13
headers/play_mode.h Normal file
View File

@ -0,0 +1,13 @@
#ifndef GUARD_PLAYMODE_H
#define GUARD_PLAYMODE_H
enum PlayMode {
NONE,
SINGLE,
TWO_LOCAL,
TWO_TCPIP,
EXIT,
};
#endif

9
headers/player.h Normal file
View File

@ -0,0 +1,9 @@
#ifndef GUARD_PLAYER_H
#define GUARD_PLAYER_H
struct Player{
unsigned lives;
unsigned x;
};
#endif

17
headers/player_def.h Normal file
View File

@ -0,0 +1,17 @@
#ifndef GUARD_PLAYER_DEF_H
#define GUARD_PLAYER_DEF_H
#include "mingl/graphics/rgbacolor.h"
struct PlayerKeys {
char right;
char left;
char shoot;
};
struct PlayerDef {
nsGraphics::RGBAcolor color;
PlayerKeys keys;
};
#endif

View File

@ -1,5 +1,5 @@
#ifndef SPACE_POSITION_H #ifndef GUARD_POSITION_H
#define SPACE_POSITION_H #define GUARD_POSITION_H
#include<mingl/mingl.h> #include<mingl/mingl.h>
@ -10,4 +10,4 @@ public:
bool isColliding(position& p, int rx, int ry); bool isColliding(position& p, int rx, int ry);
}; };
#endif //SPACE_POSITION_H #endif

View File

@ -1,17 +1,20 @@
#ifndef SPACE_STRUCTS_H #ifndef GUARD_STRUCTS_H
#define SPACE_STRUCTS_H #define GUARD_STRUCTS_H
#include<vector> #include<vector>
#include<mingl/mingl.h> #include<mingl/mingl.h>
#include "position.h" #include "position.h"
// hardcoded values // hardcoded values
#define PLAYER_WINS 1
#define INVADERS_WINS 2
#define PLAYER_HEIGHT 100
#define PLAYER_HEIGHT 100 #define PLAYER_HEIGHT 100
#define PROJ_LENGTH_FACTOR 2 #define PROJ_LENGTH_FACTOR 2
enum WinValue{
NOBODY, // should never be used, but hey
PLAYERS,
INVADERS,
};
using namespace std; using namespace std;
typedef unsigned Alien; typedef unsigned Alien;

View File

@ -18,6 +18,36 @@ bool Config::loadConfig() {
torpedo_length = 15; torpedo_length = 15;
player_width = 1000; player_width = 1000;
startXPosition = 0;
p1Def.color = nsGraphics::KTeal;
return true; return true;
} }
int Config::getInt(configKey& key) {
}
string Config::getString(configKey& key) {
}
nsGraphics::RGBAcolor Config::getColor(configKey& key) {
// switch do not work with strings, and I don't want to implement a constexpr hash function
string colorStr = getString(key);
if (colorStr == "black")return nsGraphics::KBlack;
else if (colorStr == "white")return nsGraphics::KWhite;
else if (colorStr == "red")return nsGraphics::KRed;
else if (colorStr == "lime")return nsGraphics::KLime;
else if (colorStr == "blue")return nsGraphics::KBlue;
else if (colorStr == "yellow")return nsGraphics::KYellow;
else if (colorStr == "cyan")return nsGraphics::KCyan;
else if (colorStr == "magenta")return nsGraphics::KMagenta;
else if (colorStr == "silver")return nsGraphics::KSilver;
else if (colorStr == "gray")return nsGraphics::KGray;
else if (colorStr == "maroon")return nsGraphics::KMaroon;
else if (colorStr == "olive")return nsGraphics::KOlive;
else if (colorStr == "green")return nsGraphics::KGreen;
else if (colorStr == "purple")return nsGraphics::KPurple;
else if (colorStr == "teal")return nsGraphics::KTeal;
else if (colorStr == "navy")return nsGraphics::KNavy;
else throw runtime_error("Invalid color string : "+colorStr);
}

View File

@ -1,8 +1,9 @@
#include <chrono> #include <chrono>
#include <thread> #include <thread>
#include "game.h" #include "game.h"
#include "play_mode.h"
#define WININIT window("space invader du turfu ma gueule", nsGraphics::Vec2D(1280, 720), nsGraphics::Vec2D(128, 128), nsGraphics::KBlack) #define WININIT window("space invader du turfu", nsGraphics::Vec2D(1280, 720), nsGraphics::Vec2D(128, 128), nsGraphics::KBlack)
Game::Game() : WININIT, pm(window) { Game::Game() : WININIT, pm(window) {
@ -11,37 +12,47 @@ Game::Game() : WININIT, pm(window) {
void Game::managedGames() { void Game::managedGames() {
initialMenuHandler(); // returns when user clicked plays playMode = NONE;
while(true){ while(playMode!=EXIT){
playGame(); if(playMode==NONE){
cout << "END OF GAME" << endl; playMode = initialMenuHandler();
break; }else{
deathMenuHandler(); // returns when user clicked replay playGame(); // will read the playMode
cout << "END OF GAME" << endl;
break; // TODO remove
if(!deathMenuHandler()) playMode = NONE; // back to the main menu
}
} }
} }
void Game::initialMenuHandler(){
// TODO maybe directly call theses from pm and do not use getters ?
/**
* @return the mode the use chose, we he clicks it
*/
PlayMode Game::initialMenuHandler(){
switch(pm.showInitialMenu()){ switch(pm.showInitialMenu()){
case 0:{ // play case 0:{
return; return PlayMode::SINGLE;
} }
// potential options... // potential options...
} }
return PlayMode::EXIT;
} }
void Game::deathMenuHandler(){ /**
switch(pm.showDeathMenu()){ * @return if true, the user wants to play again, same mode, false if he wants to go back to the main menu
case 0:{ // play */
return; bool Game::deathMenuHandler(){
} return pm.showDeathMenu();
// potential options...
}
} }
bool Game::invadersTouchFloor(){ bool Game::invadersTouchPlayer(){
for(aliensLine& line : grid){ for(aliensLine& line : grid){
if(basePos.getY()+line.size()*conf.alien_size>=pm.getScreenHeight()){ if(basePos.getY()+line.size()*conf.alien_size>=pm.getScreenHeight()-PLAYER_HEIGHT){
return true; return true;
} }
} }
@ -51,31 +62,46 @@ bool Game::invadersTouchFloor(){
/** /**
* Plays the game, and returns once the game is finished * Plays the game, and returns once the game is finished
* *
* @return 1 if the player won, 2 is the invaders won, any other value can be returned in case of a problem * @return WinValue::PLAYERS if the players won, WinValue::INVADERS is the invaders won, WinValue::NOBODY else (also in case of error)
*/ */
unsigned Game::playGame(){ // returns when game is finished WinValue Game::playGame(){ // returns when game is finished
// INIT // INIT
// we assume the game has been played before, and so we need to clean used members
grid = conf.grid; // will copy the vector grid = conf.grid; // will copy the vector
playerX = 0;
p1.x = conf.startXPosition;
if(playMode!=SINGLE){
// mirror the start X position for the other
p2.x = pm.getScreenWidth()-conf.startXPosition-conf.player_width;
}
basePos = position(0,0); basePos = position(0,0);
// GAMELOOP // GAMELOOP
#define FPS 1000 #define FPS 1000
while(true){ while(true){
auto target = chrono::high_resolution_clock::now() + chrono::duration<double, ratio<1, FPS>>(1); auto targetTime = chrono::high_resolution_clock::now() + chrono::duration<double, ratio<1, FPS>>(1);
pm.startFrame(); pm.startFrame();
managePlayer(); managePlayers();
if(manageInvaders() && invadersTouchFloor())return INVADERS_WINS; if(manageInvaders() && invadersTouchPlayer())return WinValue::INVADERS;
unsigned res = manageAllCollisions(); // also moves missiles + torpedos
if(res!=0)return res; moveMissiles();
remCollidingProjectiles();
moveTorpedos();
remCollidingProjectiles();
if(checkMissilesAndPlayers())return INVADERS;
if(checkTorpedosAndInvaders())return PLAYERS;
display(); display();
pm.endFrame(); pm.endFrame();
this_thread::sleep_until(target); this_thread::sleep_until(targetTime);
} }
} }
@ -105,5 +131,7 @@ void Game::display() {
} }
} }
} }
pm.dessinerJoueur(position(playerX, 0), conf.player_width); cout << p1.x << endl;
pm.dessinerJoueur(position(p1.x, 0), conf.player_width, conf.p1Def.color);
if(playMode!=SINGLE)pm.dessinerJoueur(position(p2.x, 0), conf.player_width, conf.p2Def.color);
} }

View File

@ -4,22 +4,29 @@
#define MISSILE_SPEED 5 #define MISSILE_SPEED 5
#define TORPEDO_SPEED MISSILE_SPEED #define TORPEDO_SPEED MISSILE_SPEED
/** Makes the player play once #define ISPRESSED(X) window.isPressed({X, false})
*/
void Game::managePlayer(){ void Game::managePlayerMoves(PlayerDef& pdef, unsigned& playerX){
if (window.isPressed({'q', false})){ if (ISPRESSED(pdef.keys.left)){
if(playerX < conf.player_speed) playerX = 0; if(playerX < conf.player_speed) playerX = 0;
else playerX = playerX-conf.player_speed; else playerX = playerX-conf.player_speed;
} }
if (window.isPressed({'d', false})){ if (ISPRESSED(pdef.keys.right)){
if(playerX+conf.player_speed>=pm.getScreenWidth()) playerX = pm.getScreenWidth()-1; if(playerX+conf.player_speed>=pm.getScreenWidth()) playerX = pm.getScreenWidth()-1;
else playerX = playerX+conf.player_speed; else playerX = playerX+conf.player_speed;
} }
if(window.isPressed({' ', false})){ if(ISPRESSED(pdef.keys.shoot)){
torpedos.emplace_back(playerX+conf.player_width/2, pm.getScreenHeight()-PLAYER_HEIGHT); torpedos.emplace_back(playerX+conf.player_width/2, pm.getScreenHeight()-PLAYER_HEIGHT);
} }
} }
/** Makes the players play once
*/
void Game::managePlayers(){
managePlayerMoves(conf.p1Def, p1.x);
if(playMode==PlayMode::TWO_LOCAL)managePlayerMoves(conf.p2Def, p2.x);
}
/** Makes the invaders play once, and check lower bounds /** Makes the invaders play once, and check lower bounds
* *
* @return true if the invaders went down from one line (and we should check lower boundary), else false * @return true if the invaders went down from one line (and we should check lower boundary), else false
@ -30,7 +37,7 @@ bool Game::manageInvaders(){
end+= grid.size()*conf.alien_size; // add the aliens end+= grid.size()*conf.alien_size; // add the aliens
end+= (grid.size()-1)*conf.distance; // add the distance between aliens end+= (grid.size()-1)*conf.distance; // add the distance between aliens
// you got the end ! // you got the end position of the alien crowd !
if(end+conf.alien_speed<pm.getScreenWidth()){ if(end+conf.alien_speed<pm.getScreenWidth()){
basePos.setX(basePos.getX()+conf.alien_speed); basePos.setX(basePos.getX()+conf.alien_speed);
@ -52,7 +59,7 @@ bool Game::manageInvaders(){
} }
/** makes projectiles move, and manage collisions between everything /** makes projectiles move, and manage collisions between them and everything
* *
* @return 1 if the invaders are all dead, 2 if the player is dead, else 0 * @return 1 if the invaders are all dead, 2 if the player is dead, else 0
*/ */
@ -108,12 +115,12 @@ void Game::moveTorpedos() {
} }
} }
bool Game::checkMissilesAndPlayer() { bool Game::checkMissilesAndPlayers() {
for(missile& miss : missiles){ for(missile& miss : missiles){
if(miss.getY()<=PLAYER_HEIGHT){ // colliding on Y if(miss.getY()<=PLAYER_HEIGHT){ // colliding on Y
if(lineCollideCheck( // now check collision on X if(lineCollideCheck( // now check collision on X
miss.getX(), miss.getX()+conf.missile_width, miss.getX(), miss.getX()+conf.missile_width,
playerX, playerX+conf.player_width)){ p1.x, p1.x+conf.player_width)){
return true; return true;
} }
} }
@ -124,15 +131,3 @@ bool Game::checkMissilesAndPlayer() {
bool Game::checkTorpedosAndInvaders() { bool Game::checkTorpedosAndInvaders() {
return false; return false;
} }
unsigned Game::manageAllCollisions() {
moveMissiles();
remCollidingProjectiles();
moveTorpedos();
remCollidingProjectiles();
if(checkMissilesAndPlayer())return INVADERS_WINS;
if(checkTorpedosAndInvaders())return PLAYER_WINS;
return 0;
}

View File

@ -2,16 +2,6 @@
#include "game.h" #include "game.h"
using namespace std; using namespace std;
#define C "space invader du turfu ma gueule", nsGraphics::Vec2D(1280, 720), nsGraphics::Vec2D(128, 128), nsGraphics::KBlack
class Test{
public:
MinGL a;
PixelManager pm;
Test() : a(C), pm(a) {
}
};
int main(){ int main(){
Game g; Game g;
g.managedGames(); g.managedGames();

View File

@ -32,16 +32,16 @@ void PixelManager::dessinerInvader3(const nsGraphics::Vec2D& baseVector, unsigne
window << nsShape::Rectangle(nsGraphics::Vec2D(35*scale, 65*scale)+baseVector, nsGraphics::Vec2D(65*scale, 72*scale)+baseVector, nsGraphics::KBlack); window << nsShape::Rectangle(nsGraphics::Vec2D(35*scale, 65*scale)+baseVector, nsGraphics::Vec2D(65*scale, 72*scale)+baseVector, nsGraphics::KBlack);
} }
void PixelManager::dessinerJoueur(const nsGraphics::Vec2D& baseVector, unsigned width){ void PixelManager::dessinerJoueur(const nsGraphics::Vec2D& baseVector, unsigned width, const nsGraphics::RGBAcolor& color){
width = width-10-10; width = width-10-10;
width = width/2; width = width/2;
window << nsShape::Triangle(nsGraphics::Vec2D(0, 720)+baseVector, nsGraphics::Vec2D(5, 720)+baseVector, nsGraphics::Vec2D(5, 720-PLAYER_HEIGHT/2)+baseVector, nsGraphics::KCyan); window << nsShape::Triangle(nsGraphics::Vec2D(0, 720)+baseVector, nsGraphics::Vec2D(5, 720)+baseVector, nsGraphics::Vec2D(5, 720-PLAYER_HEIGHT/2)+baseVector, color);
window << nsShape::Rectangle(nsGraphics::Vec2D(5, 720)+baseVector, nsGraphics::Vec2D(5+width, 720-PLAYER_HEIGHT/2)+baseVector, nsGraphics::KCyan); window << nsShape::Rectangle(nsGraphics::Vec2D(5, 720)+baseVector, nsGraphics::Vec2D(5+width, 720-PLAYER_HEIGHT/2)+baseVector, color);
window << nsShape::Rectangle(nsGraphics::Vec2D(5+width, 720)+baseVector, nsGraphics::Vec2D(15+width, 720-PLAYER_HEIGHT)+baseVector, nsGraphics::KCyan); window << nsShape::Rectangle(nsGraphics::Vec2D(5+width, 720)+baseVector, nsGraphics::Vec2D(15+width, 720-PLAYER_HEIGHT)+baseVector, color);
window << nsShape::Rectangle(nsGraphics::Vec2D(15+width, 720)+baseVector, nsGraphics::Vec2D(15+width*2, 720-PLAYER_HEIGHT/2)+baseVector, nsGraphics::KCyan); window << nsShape::Rectangle(nsGraphics::Vec2D(15+width, 720)+baseVector, nsGraphics::Vec2D(15+width*2, 720-PLAYER_HEIGHT/2)+baseVector, color);
window << nsShape::Triangle(nsGraphics::Vec2D(15+width*2, 720)+baseVector, nsGraphics::Vec2D(15+width*2, 720-PLAYER_HEIGHT/2)+baseVector, nsGraphics::Vec2D(20+width*2, 720)+baseVector, nsGraphics::KCyan); window << nsShape::Triangle(nsGraphics::Vec2D(15+width*2, 720)+baseVector, nsGraphics::Vec2D(15+width*2, 720-PLAYER_HEIGHT/2)+baseVector, nsGraphics::Vec2D(20+width*2, 720)+baseVector, color);
window << nsShape::Triangle(nsGraphics::Vec2D(5,720-PLAYER_HEIGHT/2)+baseVector, nsGraphics::Vec2D(5+width,720-PLAYER_HEIGHT/2)+baseVector, nsGraphics::Vec2D(5+width,720-PLAYER_HEIGHT*0.9)+baseVector, nsGraphics::KCyan); window << nsShape::Triangle(nsGraphics::Vec2D(5,720-PLAYER_HEIGHT/2)+baseVector, nsGraphics::Vec2D(5+width,720-PLAYER_HEIGHT/2)+baseVector, nsGraphics::Vec2D(5+width,720-PLAYER_HEIGHT*0.9)+baseVector, color);
window << nsShape::Triangle(nsGraphics::Vec2D(15+width,720-PLAYER_HEIGHT/2)+baseVector, nsGraphics::Vec2D(15+width*2,720-PLAYER_HEIGHT/2)+baseVector, nsGraphics::Vec2D(15+width,720-PLAYER_HEIGHT*0.9)+baseVector, nsGraphics::KCyan); window << nsShape::Triangle(nsGraphics::Vec2D(15+width,720-PLAYER_HEIGHT/2)+baseVector, nsGraphics::Vec2D(15+width*2,720-PLAYER_HEIGHT/2)+baseVector, nsGraphics::Vec2D(15+width,720-PLAYER_HEIGHT*0.9)+baseVector, color);
} }