did things

This commit is contained in:
Thomas R 2022-01-01 12:57:19 +01:00
parent 978f0e4df7
commit e4b719bd73
No known key found for this signature in database
GPG Key ID: E538821A6CDFDAD7
14 changed files with 111 additions and 84 deletions

View File

@ -8,9 +8,8 @@
typedef string configKey;
struct ConfigData {
map<string, string> internalValues;
aliensGrid grid;
invadersGrid grid;
unsigned invadersSize;
unsigned invadersDistance;
@ -24,8 +23,7 @@ struct ConfigData {
unsigned invadersSpeed;
unsigned playersSpeed;
PlayerDef p1Def;
PlayerDef p2Def;
vector<PlayerDef> playerDefs;
unsigned startXPosition;
};

View File

@ -1,6 +0,0 @@
#ifndef SPACE_ERRORS_H
#define SPACE_ERRORS_H
#endif

View File

@ -4,11 +4,11 @@
#include "mingl/mingl.h"
#include "pixel_manager.h"
#include "utils.h"
#include "position.h"
#include "player_def.h"
#include "player.h"
#include "play_mode.h"
#include "configData.h"
#include "projectiles.h"
using namespace std;
@ -19,15 +19,14 @@ private:
ConfigData confData;
position basePos;
aliensGrid grid;
invadersGrid grid;
bool direction = true;
vector<missile> missiles;
vector<torpedo> torpedos;
PlayMode playMode;
Player p1;
Player p2;
vector<Player> players;
void managePlayers();
bool manageInvaders();
@ -41,7 +40,7 @@ private:
bool checkTorpedosAndInvaders();
bool invadersTouchPlayer();
void managePlayerMoves(PlayerDef&, unsigned&);
void managePlayerMoves(PlayerDef&, unsigned&, unsigned);
public:
// in case someone wants to mess with the code, here's a minimal API, costs nothing to us

View File

@ -5,7 +5,9 @@ struct Player{
unsigned lives;
unsigned x;
unsigned id;
unsigned score;
unsigned score=0;
unsigned deathAnimCounter=0;
};
#endif

View File

@ -1,13 +0,0 @@
#ifndef GUARD_POSITION_H
#define GUARD_POSITION_H
#include<mingl/mingl.h>
class position : public nsGraphics::Vec2D {
public:
position() = default;
position(int x, int y);
bool isColliding(position& p, int rx, int ry);
};
#endif

14
headers/projectiles.h Normal file
View File

@ -0,0 +1,14 @@
#ifndef GUARD_PROJECTILES_H
#define GUARD_PROJECTILES_H
#include "utils.h"
typedef position missile;
class torpedo : public position {
public:
playerID owner;
torpedo(int x, int y, playerID owner);
};
#endif

View File

@ -1,9 +1,8 @@
#ifndef GUARD_STRUCTS_H
#define GUARD_STRUCTS_H
#ifndef GUARD_UTILS_H
#define GUARD_UTILS_H
#include<vector>
#include<mingl/mingl.h>
#include"position.h"
// hardcoded values
#define PLAYER_HEIGHT 100
@ -17,17 +16,11 @@ enum WinValue{
using namespace std;
typedef unsigned Alien;
typedef vector<Alien> aliensLine;
typedef vector<aliensLine> aliensGrid;
typedef position missile;
class torpedo : public nsGraphics::Vec2D {
public:
topedo(int x, int y);
unsigned playerID;
};
typedef unsigned Invader;
typedef vector<Invader> invadersColumn;
typedef vector<invadersColumn> invadersGrid;
typedef nsGraphics::Vec2D position;
typedef unsigned playerID;
// didn't want to use position because of the semantic with x and y
bool lineCollideCheck(unsigned start1, unsigned end1, unsigned start2, unsigned end2);

View File

@ -78,15 +78,18 @@ void ConfigBuilder::readConfig() {
collectedData.startXPosition = getInt("players.startXPosition");
collectedData.playersSpeed = getInt("players.speed");
collectedData.p1Def.color = getColor("players.user1.color");
collectedData.p1Def.keys.left = getChar("players.user1.keys.left");
collectedData.p1Def.keys.right = getChar("players.user1.keys.right");
collectedData.p1Def.keys.shoot = getChar("players.user1.keys.shoot");
// the scalability behind the vector of players is only an illusion, because we force player count to be 1 or 2
// It was done so the 2+ players implementation could be easier in the future, if wanted
collectedData.playerDefs.resize(2);
collectedData.playerDefs[1].color = getColor("players.user1.color");
collectedData.playerDefs[1].keys.left = getChar("players.user1.keys.left");
collectedData.playerDefs[1].keys.right = getChar("players.user1.keys.right");
collectedData.playerDefs[1].keys.shoot = getChar("players.user1.keys.shoot");
collectedData.p2Def.color = getColor("players.user2.color");
collectedData.p2Def.keys.left = getChar("players.user2.keys.left");
collectedData.p2Def.keys.right = getChar("players.user2.keys.right");
collectedData.p2Def.keys.shoot = getChar("players.user2.keys.shoot");
collectedData.playerDefs[2].color = getColor("players.user2.color");
collectedData.playerDefs[2].keys.left = getChar("players.user2.keys.left");
collectedData.playerDefs[2].keys.right = getChar("players.user2.keys.right");
collectedData.playerDefs[2].keys.shoot = getChar("players.user2.keys.shoot");
// invaders
collectedData.invadersSize = getInt("invaders.size");

View File

@ -58,7 +58,7 @@ bool Game::deathMenuHandler(){
}
bool Game::invadersTouchPlayer(){
for(aliensLine& line : grid){
for(invadersColumn& line : grid){
if(basePos.getY()+ line.size() * confData.invadersSize >= pm.getScreenHeight() - PLAYER_HEIGHT){
return true;
}
@ -76,12 +76,15 @@ WinValue Game::playGame(){ // returns when game is finished
// we assume the game has been played before, and so we need to clean used members
grid = confData.grid; // will copy the vector
p1.x = confData.startXPosition;
if(playMode!=SINGLE){
if(playMode==SINGLE){
players.resize(1);
}else{
players.resize(2);
// mirror the start X position for the other
p2.x = pm.getScreenWidth() - confData.startXPosition - confData.playersWidth;
players[1].x = pm.getScreenWidth() - confData.startXPosition - confData.playersWidth;
}
players[0].x = confData.startXPosition;
basePos = position(0,0);
@ -118,7 +121,7 @@ WinValue Game::playGame(){ // returns when game is finished
void Game::display() {
for (unsigned i = 0; i < this->grid.size(); ++i){
for (unsigned j = 0; j < this->grid[i].size(); ++j){
nsGraphics::Vec2D vec =nsGraphics::Vec2D(
nsGraphics::Vec2D vec(
basePos.getX() + i * confData.invadersSize + i * confData.invadersDistance,
basePos.getY() + j * confData.invadersSize + j * confData.invadersDistance
);
@ -138,6 +141,8 @@ void Game::display() {
}
}
}
pm.dessinerJoueur(position(p1.x, 0), confData.playersWidth, confData.p1Def.color);
if(playMode!=SINGLE)pm.dessinerJoueur(position(p2.x, 0), confData.playersWidth, confData.p2Def.color);
for(size_t i=0;i<players.size();++i){
pm.dessinerJoueur(position(players[i].x, 0), confData.playersWidth, confData.playerDefs[i].color);
}
}

View File

@ -16,15 +16,18 @@ void Game::managePlayerMoves(PlayerDef& pdef, unsigned& playerX, unsigned player
else playerX = playerX + confData.playersSpeed;
}
if(ISPRESSED(pdef.keys.shoot)){
torpedos.emplace_back(playerX + confData.playersWidth / 2, pm.getScreenHeight() - PLAYER_HEIGHT, playerId );
torpedos.emplace_back(playerX + confData.playersWidth / 2, pm.getScreenHeight() - PLAYER_HEIGHT, playerId);
}
}
/** Makes the players play once
*/
void Game::managePlayers(){
managePlayerMoves(confData.p1Def, p1.x,p1.id);
if(playMode==PlayMode::TWO_LOCAL)managePlayerMoves(confData.p2Def, p2.x, p2.id);
managePlayerMoves(confData.playerDefs[0], players[0].x,0);
if(playMode==PlayMode::TWO_LOCAL)managePlayerMoves(confData.playerDefs[1], players[1].x, 1);
else if(playMode==PlayMode::TWO_TCPIP){
// TODO TCPIP
}
}
/** Makes the invaders play once, and check lower bounds
@ -34,10 +37,10 @@ void Game::managePlayers(){
bool Game::manageInvaders(){
if(direction){ // go to the right
int end = basePos.getX(); // start position
end+= grid.size() * confData.invadersSize; // add the aliens
end+= (grid.size()-1) * confData.invadersDistance; // add the invadersDistance between aliens
end+= grid.size() * confData.invadersSize; // add the invaders
end+= (grid.size()-1) * confData.invadersDistance; // add the invadersDistance between invaders
// you got the end position of the alien crowd !
// you got the end position of the invader crowd !
if(end + confData.invadersSpeed < pm.getScreenWidth()){
basePos.setX(basePos.getX() + confData.invadersSpeed);
@ -69,7 +72,7 @@ void Game::remCollidingProjectiles(){
auto tor = torpedos.begin();
while(miss != missiles.end()){
bool wasColling = false;
bool wasColliding = false;
while(tor != torpedos.end()){
// missiles can't be right under torpedos, so that must means they are colliding in Y
@ -81,7 +84,7 @@ void Game::remCollidingProjectiles(){
tor->getX(), tor->getX() + confData.torpedosWidth)){
missiles.erase(miss);
torpedos.erase(tor);
wasColling = true;
wasColliding = true;
break;
}
++tor;
@ -89,7 +92,7 @@ void Game::remCollidingProjectiles(){
/* if it was colling, it was removed and his position is now replaced by the next.
* else, go to the next
*/
if(!wasColling)++miss;
if(!wasColliding)++miss;
}
}
@ -116,18 +119,51 @@ void Game::moveTorpedos() {
}
bool Game::checkMissilesAndPlayers() {
for(missile& miss : missiles){
if(miss.getY()<=PLAYER_HEIGHT){ // colliding on Y
if(lineCollideCheck( // now check collision on X
miss.getX(), miss.getX() + confData.missilesWidth,
p1.x, p1.x + confData.playersWidth)){
return true;
auto miss_ite = missiles.begin();
while(miss_ite!=missiles.end()){
if(miss_ite->getY()<=PLAYER_HEIGHT){ // check collision on Y
// now check collision on X (with both players)
bool wasColliding = false;
for(Player& p : players){
if(lineCollideCheck(
miss_ite->getX(), miss_ite->getX() + confData.missilesWidth,
p.x, p.x + confData.playersWidth)){
wasColliding = true;
if(p.deathAnimCounter)p.deathAnimCounter = 1;
// do not break, the second player also deserves to be hit
}
}
if(wasColliding)missiles.erase(miss_ite);
else ++miss_ite;
}
}
return false;
}
bool Game::checkTorpedosAndInvaders() {
auto tor_ite = torpedos.begin();
while(tor_ite!=torpedos.end()){
unsigned i=0;
for(;i<grid.size();++i){
// calculate top-left position of invader
position pos = basePos+position(
confData.invadersSize*(grid[i].size()-1)+confData.invadersDistance*(grid[i].size()-1),
confData.invadersSize*(grid[i].size()-1)+confData.invadersDistance*(grid[i].size()-1));
// check collision on Y (invaders can actually be "under" torpedos, so we check both lower and upper bounds
if(pos.getY()+confData.invadersSize>=tor_ite->getY() &&
pos.getY()<=tor_ite->getY()+confData.torpedosLength){
// now check collision on X
if(lineCollideCheck( // now check collision on X
tor_ite->getX(), tor_ite->getX() + confData.torpedosWidth,
pos.getX(), pos.getX() + confData.invadersSize)){
break;
}
}
}
if(i==grid.size()) ++tor_ite;
else{
torpedos.erase(tor_ite);
grid[i].pop_back();
}
}
return false;
}

View File

@ -2,6 +2,7 @@
#include "game.h"
using namespace std;
// TODO changer tout les unsigned par des size_t dans les boucles
int main(){
Game g;
g.managedGames();

View File

@ -1,8 +0,0 @@
#include "position.h"
#include <mingl/mingl.h>
bool position::isColliding(position& p, int rx, int ry) {
return nsGraphics::Vec2D::isColliding(p, p+nsGraphics::Vec2D(rx, ry));
}
position::position(int x, int y) : Vec2D(x, y) {}

5
src/projectiles.cpp Normal file
View File

@ -0,0 +1,5 @@
#include "projectiles.h"
torpedo::torpedo(int x, int y, playerID owner) : position(x, y) {
this->owner = owner;
}

View File

@ -1,7 +1,5 @@
#include "utils.h"
torpedo::torpedo(int x, int y) : position(x, y) {}
bool lineCollideCheck(unsigned start1, unsigned end1, unsigned start2, unsigned end2){
return start1 < end2 != start2 < end1;
// if true, are colliding. I like truth tables