From 41399e6c19c7377aa899cfa4e27b6a208d60e193 Mon Sep 17 00:00:00 2001 From: Thomas Date: Tue, 4 Jan 2022 12:04:04 +0100 Subject: [PATCH] We now have FPS --- QUESTIONS.md | 2 +- headers/game.h | 5 ++-- headers/god.h | 2 +- headers/pixelManager.h | 4 ++- headers/utils.h | 7 ++++-- src/game/display.cpp | 33 ++++++++++++++----------- src/gameBasics.cpp | 33 +++++++++++++++++++++---- src/godThings.cpp | 7 +++++- src/pixelManager.cpp | 56 ++++++++++++++++++++++++------------------ 9 files changed, 98 insertions(+), 51 deletions(-) diff --git a/QUESTIONS.md b/QUESTIONS.md index 191a9eb..e38f30f 100644 --- a/QUESTIONS.md +++ b/QUESTIONS.md @@ -16,4 +16,4 @@ Questions que je (Thomas Rubini) voudrais poser - Pour import MinGL, il vaut mieux utiliser "" ou <> ? * <> tout le temps, "" à éviter - copier ou ref constante pour Position (Vec2D) ? -* ref constante (vau tmieux se dire "dès qu'on a une structure on copie" pour pas compliquer) \ No newline at end of file +* ref constante (vaut mieux se dire "dès qu'on a une structure on copie" pour pas compliquer) \ No newline at end of file diff --git a/headers/game.h b/headers/game.h index 99f10df..6df452c 100644 --- a/headers/game.h +++ b/headers/game.h @@ -40,9 +40,9 @@ private: void handleScoreSaving(); // drawing methods - void display() const; + void display(unsigned fps) const; void displayGod() const; - void displayInvader(const Position& basePos, unsigned size, InvaderType type) const; + void displayInvader(const Position& basePos, InvaderType type) const; // managers @@ -59,6 +59,7 @@ private: bool invadersTouchPlayer() const; // god things + void awakeGod(); void manageGod(); void _manageGod_retrieve(bool back); diff --git a/headers/god.h b/headers/god.h index 1195f7f..8ff3539 100644 --- a/headers/god.h +++ b/headers/god.h @@ -5,7 +5,7 @@ enum class GodState{ NONE, - LOAD, + AWAKE, WAIT, RETRIEVE1, RETRIEVE2, diff --git a/headers/pixelManager.h b/headers/pixelManager.h index b659679..c6c17f7 100644 --- a/headers/pixelManager.h +++ b/headers/pixelManager.h @@ -8,11 +8,11 @@ #include "mingl/shape/rectangle.h" #include "mingl/shape/circle.h" #include "mingl/gui/sprite.h" +#include "mingl/gui/text.h" #include "utils.h" #include "playMode.h" using namespace std; -using namespace nsGraphics; class PixelManager{ public: @@ -39,6 +39,8 @@ public: void drawSprite(nsGui::Sprite& sprite, const Position& pos) const; void drawBackground() const; + void drawFPS(unsigned fps) const; + PlayMode showInitialMenu() const; bool showDeathMenu() const; unsigned getScreenHeight() const; diff --git a/headers/utils.h b/headers/utils.h index b4d805e..002b372 100644 --- a/headers/utils.h +++ b/headers/utils.h @@ -11,14 +11,17 @@ // ou alors faire une method dans Game ? #define INV_POS(i) confData.invadersSize*(i)+confData.invadersDistance*(i) + +using namespace std; +using nsGraphics::RGBAcolor; + + enum class WinValue{ NOBODY, // should never be used PLAYERS, INVADERS, }; -using namespace std; - enum class InvaderType { TYPEA, TYPEB, diff --git a/src/game/display.cpp b/src/game/display.cpp index 5e95024..31300e2 100644 --- a/src/game/display.cpp +++ b/src/game/display.cpp @@ -2,9 +2,9 @@ /** Displays the screen once, and returns - * + * The more important stuff must be drawn last */ -void Game::display() const { +void Game::display(unsigned fps) const { pm.drawBackground(); for (unsigned i = 0; i < this->grid.size(); ++i){ for (unsigned j = 0; j < this->grid[i].size(); ++j){ @@ -12,7 +12,7 @@ void Game::display() const { basePos.getX() + i * confData.invadersSize + i * confData.invadersDistance, basePos.getY() + j * confData.invadersSize + j * confData.invadersDistance ); - displayInvader(vec, confData.invadersSize, grid[i][j]); + displayInvader(vec, grid[i][j]); } } @@ -28,22 +28,25 @@ void Game::display() const { } displayGod(); + + pm.drawFPS(fps); + } -void Game::displayInvader(const Position& pos, unsigned size, InvaderType type) const { +void Game::displayInvader(const Position& pos, InvaderType type) const { if(type==InvaderType::NONE)return; InvaderTypeDef invDef = confData.invadersDef.at(type); switch(type){ case InvaderType::TYPEA:{ - pm.drawInvaderA(pos, size, invDef.color); + pm.drawInvaderA(pos, confData.invadersSize, invDef.color); return; } case InvaderType::TYPEB:{ - pm.drawInvaderB(pos, size, invDef.color); + pm.drawInvaderB(pos, confData.invadersSize, invDef.color); return; } case InvaderType::TYPEC:{ - pm.drawInvaderC(pos, size, invDef.color); + pm.drawInvaderC(pos, confData.invadersSize, invDef.color); return; } } @@ -58,7 +61,7 @@ void Game::displayGod() const { switch (god.state) { case GodState::NONE: return; - case GodState::LOAD: { + case GodState::AWAKE: { pm.displayGodBench(god.counter - GOD_BENCH_SIZE); Position leftHand = Position(pm.getScreenWidth()-GOD_HAND_DISTANCE-GOD_HAND_SIZE, god.counter - GOD_BENCH_SIZE); @@ -93,17 +96,19 @@ void Game::displayGod() const { } case GodState::RETRIEVE2:{ // similar with RETRIEVE1 - Position startPos(GOD_HAND_DISTANCE, 0); + Position pos(GOD_HAND_DISTANCE, 0); Position endPos = basePos+Position(INV_POS(god.throwedInvPos.getX()), INV_POS(god.throwedInvPos.getY())); - applyBezier(startPos, god.thrownTransition, 1-(god.counter/100)); - applyBezier(startPos, endPos, 1-(god.counter/100)); + applyBezier(pos, god.thrownTransition, 1 - (god.counter / 100)); + applyBezier(pos, endPos, 1 - (god.counter / 100)); - pm.displayGodRightHand(startPos); + pm.displayGodRightHand(pos); pm.displayGodLeftHand(Position(GOD_HAND_DISTANCE, 0)); - // but now, you come with me you invader ! -// pm.drawInvader1(); + // TODO maybe a little transition to pos to better reflect the invader's position ? + +// but now, you come with me you invader ! + displayInvader(pos, god.thrownInvType); break; } case GodState::THROW:{ diff --git a/src/gameBasics.cpp b/src/gameBasics.cpp index 1a62896..c5a5b14 100644 --- a/src/gameBasics.cpp +++ b/src/gameBasics.cpp @@ -83,14 +83,25 @@ WinValue Game::playGame(){ // returns when game is finished basePos = Position(200, 0); // GAMELOOP -#define MAX_FPS 1000 +#define MAX_FPS 60 + + chrono::milliseconds fpsTime; + unsigned tmpFps = 0; + unsigned fps = 0; while(window.isOpen()){ - auto targetTime = chrono::high_resolution_clock::now() + chrono::duration>(1); + chrono::time_point startTime = chrono::high_resolution_clock::now(); pm.startFrame(); managePlayers(); - if(manageInvaders() && invadersTouchPlayer())return WinValue::INVADERS; + if(manageInvaders()) { // if they went down + if (invadersTouchPlayer())return WinValue::INVADERS; + // TODO abstract this ? + if (basePos.getY() > 200 /*lambda value*/ && god.state==GodState::NONE) { + cout << "hey" << endl; + awakeGod(); + } + } moveMissiles(); remCollidingProjectiles(); @@ -100,11 +111,23 @@ WinValue Game::playGame(){ // returns when game is finished if(checkMissilesAndPlayers())return WinValue::INVADERS; if(checkTorpedosAndInvaders())return WinValue::PLAYERS; - display(); + display(fps); pm.endFrame(); - this_thread::sleep_until(targetTime); + chrono::time_point endTime = chrono::high_resolution_clock::now(); + chrono::milliseconds frameTime = chrono::duration_cast(endTime-startTime); + fpsTime = fpsTime + frameTime; + if(fpsTime>chrono::seconds(1)){ + fps = tmpFps; + tmpFps = 0; + fpsTime = chrono::milliseconds(0); + }else ++tmpFps; + + // old implementation, too volatile +// cout << "FPS : " << chrono::milliseconds(1000)/frameTime << endl; + + this_thread::sleep_until(startTime+chrono::duration>(1)); } return WinValue::NOBODY; } diff --git a/src/godThings.cpp b/src/godThings.cpp index 847e0e1..b2cc587 100644 --- a/src/godThings.cpp +++ b/src/godThings.cpp @@ -1,11 +1,16 @@ #include "game.h" +void Game::awakeGod() { + god.counter = 0; + god.state = GodState::AWAKE; +} + void Game::manageGod(){ switch(god.state){ case GodState::NONE:{ return; } - case GodState::LOAD:{ + case GodState::AWAKE:{ if(god.counter==GOD_BENCH_SIZE){ god.counter = 0; god.state = GodState::WAIT; diff --git a/src/pixelManager.cpp b/src/pixelManager.cpp index 4553f11..0a4fdbb 100644 --- a/src/pixelManager.cpp +++ b/src/pixelManager.cpp @@ -1,6 +1,10 @@ #include #include "pixelManager.h" #include "utils.h" +#include "god.h" + + +using namespace nsShape; PixelManager::PixelManager(MinGL& a) : window(a) { window.initGlut(); @@ -9,40 +13,40 @@ PixelManager::PixelManager(MinGL& a) : window(a) { void PixelManager::drawInvaderA(const Position& baseVector, unsigned size, const RGBAcolor& color) const { float scale = size/(float)100; - window << nsShape::Circle(Position(50*scale, 50*scale)+baseVector, 50*scale, nsGraphics::KGray); - window << nsShape::Triangle(Position(35*scale, 50*scale)+baseVector, Position(15*scale, 25*scale)+baseVector, Position(15*scale, 75*scale)+baseVector, nsGraphics::KBlack); - window << nsShape::Triangle(Position(25*scale, 50*scale)+baseVector, Position(10*scale, 25*scale)+baseVector, Position(10*scale, 75*scale)+baseVector, nsGraphics::KGray); - window << nsShape::Triangle(Position(65*scale, 50*scale)+baseVector, Position(85*scale, 25*scale)+baseVector, Position(85*scale, 75*scale)+baseVector, nsGraphics::KBlack); - window << nsShape::Triangle(Position(75*scale, 50*scale)+baseVector, Position(90*scale, 25*scale)+baseVector, Position(90*scale, 75*scale)+baseVector, nsGraphics::KGray); - window << nsShape::Rectangle(Position(35*scale, 65*scale)+baseVector, Position(65*scale, 72*scale)+baseVector, nsGraphics::KBlack); + window << Circle(Position(50*scale, 50*scale)+baseVector, 50*scale, nsGraphics::KGray); + window << Triangle(Position(35*scale, 50*scale)+baseVector, Position(15*scale, 25*scale)+baseVector, Position(15*scale, 75*scale)+baseVector, nsGraphics::KBlack); + window << Triangle(Position(25*scale, 50*scale)+baseVector, Position(10*scale, 25*scale)+baseVector, Position(10*scale, 75*scale)+baseVector, nsGraphics::KGray); + window << Triangle(Position(65*scale, 50*scale)+baseVector, Position(85*scale, 25*scale)+baseVector, Position(85*scale, 75*scale)+baseVector, nsGraphics::KBlack); + window << Triangle(Position(75*scale, 50*scale)+baseVector, Position(90*scale, 25*scale)+baseVector, Position(90*scale, 75*scale)+baseVector, nsGraphics::KGray); + window << Rectangle(Position(35*scale, 65*scale)+baseVector, Position(65*scale, 72*scale)+baseVector, nsGraphics::KBlack); } void PixelManager::drawInvaderB(const Position& baseVector, unsigned size, const RGBAcolor& color) const { float scale = size/(float)100; - window << nsShape::Circle(Position(50*scale, 50*scale)+baseVector, 50*scale, nsGraphics::KRed); - window << nsShape::Rectangle(Position(25*scale, 30*scale)+baseVector, Position(45*scale, 40*scale)+baseVector, nsGraphics::KBlack); - window << nsShape::Rectangle(Position(55*scale, 30*scale)+baseVector, Position(75*scale, 40*scale)+baseVector, nsGraphics::KBlack); - window << nsShape::Rectangle(Position(35*scale, 65*scale)+baseVector, Position(65*scale, 72*scale)+baseVector, nsGraphics::KBlack); + window << Circle(Position(50*scale, 50*scale)+baseVector, 50*scale, nsGraphics::KRed); + window << Rectangle(Position(25*scale, 30*scale)+baseVector, Position(45*scale, 40*scale)+baseVector, nsGraphics::KBlack); + window << Rectangle(Position(55*scale, 30*scale)+baseVector, Position(75*scale, 40*scale)+baseVector, nsGraphics::KBlack); + window << Rectangle(Position(35*scale, 65*scale)+baseVector, Position(65*scale, 72*scale)+baseVector, nsGraphics::KBlack); } void PixelManager::drawInvaderC(const Position& baseVector, unsigned size, const RGBAcolor& color) const { float scale = size/(float)100; - window << nsShape::Circle(Position(50*scale, 50*scale)+baseVector, 50*scale, nsGraphics::KGreen); - window << nsShape::Circle(Position(35*scale, 35*scale)+baseVector, 10*scale, nsGraphics::KBlack); - window << nsShape::Circle(Position(65*scale, 35*scale)+baseVector, 10*scale, nsGraphics::KBlack); - window << nsShape::Rectangle(Position(35*scale, 65*scale)+baseVector, Position(65*scale, 72*scale)+baseVector, nsGraphics::KBlack); + window << Circle(Position(50*scale, 50*scale)+baseVector, 50*scale, nsGraphics::KGreen); + window << Circle(Position(35*scale, 35*scale)+baseVector, 10*scale, nsGraphics::KBlack); + window << Circle(Position(65*scale, 35*scale)+baseVector, 10*scale, nsGraphics::KBlack); + window << Rectangle(Position(35*scale, 65*scale)+baseVector, Position(65*scale, 72*scale)+baseVector, nsGraphics::KBlack); } void PixelManager::drawPlayer(unsigned x, unsigned width, const nsGraphics::RGBAcolor& color) const { width = width-10-10; width = width/2; - window << nsShape::Triangle(Position(0+x, 720), Position(5+x, 720), Position(5+x, 720-PLAYER_HEIGHT/2), color); - window << nsShape::Rectangle(Position(5+x, 720), Position(5+width+x, 720-PLAYER_HEIGHT/2), color); - window << nsShape::Rectangle(Position(5+width+x, 720), Position(15+width+x, 720-PLAYER_HEIGHT), color); - window << nsShape::Rectangle(Position(15+width+x, 720), Position(15+width*2+x, 720-PLAYER_HEIGHT/2), color); - window << nsShape::Triangle(Position(15+width*2+x, 720), Position(15+width*2+x, 720-PLAYER_HEIGHT/2), Position(20+width*2+x, 720), color); - window << nsShape::Triangle(Position(5+x,720-PLAYER_HEIGHT/2), Position(5+width+x,720-PLAYER_HEIGHT/2), Position(5+width+x,720-PLAYER_HEIGHT*0.9), color); - window << nsShape::Triangle(Position(15+width+x,720-PLAYER_HEIGHT/2), Position(15+width*2+x,720-PLAYER_HEIGHT/2), Position(15+width+x,720-PLAYER_HEIGHT*0.9), color); + window << Triangle(Position(0+x, 720), Position(5+x, 720), Position(5+x, 720-PLAYER_HEIGHT/2), color); + window << Rectangle(Position(5+x, 720), Position(5+width+x, 720-PLAYER_HEIGHT/2), color); + window << Rectangle(Position(5+width+x, 720), Position(15+width+x, 720-PLAYER_HEIGHT), color); + window << Rectangle(Position(15+width+x, 720), Position(15+width*2+x, 720-PLAYER_HEIGHT/2), color); + window << Triangle(Position(15+width*2+x, 720), Position(15+width*2+x, 720-PLAYER_HEIGHT/2), Position(20+width*2+x, 720), color); + window << Triangle(Position(5+x,720-PLAYER_HEIGHT/2), Position(5+width+x,720-PLAYER_HEIGHT/2), Position(5+width+x,720-PLAYER_HEIGHT*0.9), color); + window << Triangle(Position(15+width+x,720-PLAYER_HEIGHT/2), Position(15+width*2+x,720-PLAYER_HEIGHT/2), Position(15+width+x,720-PLAYER_HEIGHT*0.9), color); } void PixelManager::askPlayerNameMenu(playerID pID, string& name) const { @@ -51,11 +55,11 @@ void PixelManager::askPlayerNameMenu(playerID pID, string& name) const { } void PixelManager::drawMissile(const Position& baseVector, unsigned width, const nsGraphics::RGBAcolor& color) const { - window << nsShape::Rectangle(baseVector, baseVector + Position(width, width * PROJ_LENGTH_FACTOR), color); + window << Rectangle(baseVector, baseVector + Position(width, width * PROJ_LENGTH_FACTOR), color); } void PixelManager::drawTorpedo(const Position& baseVector, unsigned width, const nsGraphics::RGBAcolor& color) const { - window << nsShape::Rectangle(baseVector, baseVector + Position(width, width * PROJ_LENGTH_FACTOR), color); + window << Rectangle(baseVector, baseVector + Position(width, width * PROJ_LENGTH_FACTOR), color); } void PixelManager::drawSprite(nsGui::Sprite& sprite, const Position& pos) const { @@ -97,7 +101,7 @@ void PixelManager::endFrame() const { } void PixelManager::displayGodBench(int y) const { - + window << Rectangle(Position(0, y), Position(0, y+GOD_BENCH_SIZE), nsGraphics::KBlack); } void PixelManager::displayGodRightHand(const Position& pos) const { @@ -107,3 +111,7 @@ void PixelManager::displayGodRightHand(const Position& pos) const { void PixelManager::displayGodLeftHand(const Position& pos) const { } + +void PixelManager::drawFPS(unsigned fps) const { + window << nsGui::Text(Position(getScreenWidth()-100, 10), "FPS : "+ to_string(fps), nsGraphics::KWhite); +}