From bf5ec3cfe56585806981815826a21bd14e9ee7d6 Mon Sep 17 00:00:00 2001 From: manzerbredes Date: Sun, 3 May 2015 10:07:39 +0200 Subject: [PATCH 01/11] Add fixed white space --- .../ConsoleController/ConsoleController.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/Controllers/ConsoleController/ConsoleController.cpp b/src/Controllers/ConsoleController/ConsoleController.cpp index 1bc9b84..57f626f 100644 --- a/src/Controllers/ConsoleController/ConsoleController.cpp +++ b/src/Controllers/ConsoleController/ConsoleController.cpp @@ -70,6 +70,9 @@ kbdh::Direction ConsoleController::waitArrowKeyPress() //Initialise keyPress kbdh::Direction keyPress; + //White space to remove arrows print by the terminal + std::string spaces=" "; + //Wait for keypress while(1){ if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left)) @@ -78,7 +81,7 @@ kbdh::Direction ConsoleController::waitArrowKeyPress() while(sf::Keyboard::isKeyPressed(sf::Keyboard::Left)) { //Wait for release and try to remove arrow printed characters - std::cout << "\r" << " "; + std::cout << "\r" << spaces; } break; } @@ -88,7 +91,7 @@ kbdh::Direction ConsoleController::waitArrowKeyPress() while(sf::Keyboard::isKeyPressed(sf::Keyboard::Right)) { //Wait for release and try to remove arrow printed characters - std::cout << "\r" << " "; + std::cout << "\r" << spaces; } break; } @@ -98,7 +101,7 @@ kbdh::Direction ConsoleController::waitArrowKeyPress() while(sf::Keyboard::isKeyPressed(sf::Keyboard::Up)) { //Wait for release and try to remove arrow printed characters - std::cout << "\r" << " "; + std::cout << "\r" << spaces; } break; } @@ -108,7 +111,7 @@ kbdh::Direction ConsoleController::waitArrowKeyPress() while(sf::Keyboard::isKeyPressed(sf::Keyboard::Down)) { //Wait for release and try to remove arrow printed characters - std::cout << "\r" << " "; + std::cout << "\r" << spaces; } break; } From ddaf5ba3ba3954c2b8a9926adbd3a066d8f0316c Mon Sep 17 00:00:00 2001 From: manzerbredes Date: Sun, 3 May 2015 12:24:03 +0200 Subject: [PATCH 02/11] Add readme --- Readme.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 Readme.md diff --git a/Readme.md b/Readme.md new file mode 100644 index 0000000..d0acd15 --- /dev/null +++ b/Readme.md @@ -0,0 +1,2 @@ +#2P11 +----- From ce3f721e16c779d519c04469e49a65f60546ab8d Mon Sep 17 00:00:00 2001 From: manzerbredes Date: Sun, 3 May 2015 14:19:30 +0200 Subject: [PATCH 03/11] Add first version of SFMLController and View class --- src/CMakeLists.txt | 3 +- src/Controllers/CMakeLists.txt | 1 + src/Controllers/SFMLController/CMakeLists.txt | 3 ++ .../SFMLController/SFMLController.cpp | 37 +++++++++++++++++++ .../SFMLController/SFMLController.hpp | 21 +++++++++++ src/View/CMakeLists.txt | 2 + src/View/MainWindow.cpp | 25 +++++++++++++ src/View/MainWindow.hpp | 20 ++++++++++ src/main.cpp | 4 +- 9 files changed, 113 insertions(+), 3 deletions(-) create mode 100644 src/Controllers/SFMLController/CMakeLists.txt create mode 100644 src/Controllers/SFMLController/SFMLController.cpp create mode 100644 src/Controllers/SFMLController/SFMLController.hpp create mode 100644 src/View/CMakeLists.txt create mode 100644 src/View/MainWindow.cpp create mode 100644 src/View/MainWindow.hpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index da444d2..e7b7f73 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -12,7 +12,8 @@ set_property(GLOBAL PROPERTY SFML_INCLUDE_DIR "${SFML_INCLUDE_DIR}") #Include "Includes" and "Libraries" include_directories(${SFML_INCLUDE_DIR}) -target_link_libraries(2P11 ${SFML_LIBRARIES} Model ConsoleController) +target_link_libraries(2P11 ${SFML_LIBRARIES} Model ConsoleController View SFMLController) add_subdirectory(./Model) add_subdirectory(./Controllers/) +add_subdirectory(./View/) diff --git a/src/Controllers/CMakeLists.txt b/src/Controllers/CMakeLists.txt index 7ebeb19..13b1c20 100644 --- a/src/Controllers/CMakeLists.txt +++ b/src/Controllers/CMakeLists.txt @@ -1 +1,2 @@ add_subdirectory(./ConsoleController/) +add_subdirectory(./SFMLController/) diff --git a/src/Controllers/SFMLController/CMakeLists.txt b/src/Controllers/SFMLController/CMakeLists.txt new file mode 100644 index 0000000..e3e60c4 --- /dev/null +++ b/src/Controllers/SFMLController/CMakeLists.txt @@ -0,0 +1,3 @@ +#Make Model lib +add_library(SFMLController ./SFMLController.cpp) +target_link_libraries(SFMLController Model View) diff --git a/src/Controllers/SFMLController/SFMLController.cpp b/src/Controllers/SFMLController/SFMLController.cpp new file mode 100644 index 0000000..09a3c25 --- /dev/null +++ b/src/Controllers/SFMLController/SFMLController.cpp @@ -0,0 +1,37 @@ +#include "SFMLController.hpp" + + + + + + +SFMLController::SFMLController() : m_MainWindow(800,800, "2P11"){ + +} + + +SFMLController::~SFMLController(){ + +} + + + + +void SFMLController::run(){ + + while(m_MainWindow.isOpen()){ + + + sf::Event event; + while (m_MainWindow.pollEvent(event)) + { + // évènement "fermeture demandée" : on ferme la fenêtre + if (event.type == sf::Event::Closed) + m_MainWindow.close(); + } + m_MainWindow.clearMW(); + m_MainWindow.display(); + } + + +} diff --git a/src/Controllers/SFMLController/SFMLController.hpp b/src/Controllers/SFMLController/SFMLController.hpp new file mode 100644 index 0000000..94a22e3 --- /dev/null +++ b/src/Controllers/SFMLController/SFMLController.hpp @@ -0,0 +1,21 @@ + + + +#include +#include +#include +#include "../../View/MainWindow.hpp" + +class SFMLController{ + + private: + MainWindow m_MainWindow; + + + public: + SFMLController(); + ~SFMLController(); + + void run(); + +}; diff --git a/src/View/CMakeLists.txt b/src/View/CMakeLists.txt new file mode 100644 index 0000000..9a13671 --- /dev/null +++ b/src/View/CMakeLists.txt @@ -0,0 +1,2 @@ +#Make Model lib +add_library(View ./MainWindow.cpp) diff --git a/src/View/MainWindow.cpp b/src/View/MainWindow.cpp new file mode 100644 index 0000000..274fc8e --- /dev/null +++ b/src/View/MainWindow.cpp @@ -0,0 +1,25 @@ +#include "MainWindow.hpp" + + + + + + +MainWindow::MainWindow(int width, int height, std::string title): + RenderWindow(sf::VideoMode(width,height), title), + skin() +{ + + //Define skin: + skin.push_back(sf::Color(250,248,239)); + + +} + + +MainWindow::~MainWindow(){ +} + +void MainWindow::clearMW(){ + RenderWindow::clear(skin.at(0)); +} diff --git a/src/View/MainWindow.hpp b/src/View/MainWindow.hpp new file mode 100644 index 0000000..a0e7c58 --- /dev/null +++ b/src/View/MainWindow.hpp @@ -0,0 +1,20 @@ + + + +#include +#include +#include +#include + + +class MainWindow : public sf::RenderWindow{ + + private: + std::vector skin; + public: + MainWindow(int width, int height, std::string title); + ~MainWindow(); + + void clearMW(); + +}; diff --git a/src/main.cpp b/src/main.cpp index 48c1766..70f3a6b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -6,7 +6,7 @@ //---------------------- //----- Personnal include ----- -#include "./Controllers/ConsoleController/ConsoleController.hpp" +#include "./Controllers/SFMLController/SFMLController.hpp" //----------------------------- @@ -20,7 +20,7 @@ int main() srand(time(NULL)); //Init controller - ConsoleController controller; + SFMLController controller; //Run the game controller.run(); From 7f0edabb5dff0e88d33cd8855eacda07aa17b1ca Mon Sep 17 00:00:00 2001 From: manzerbredes Date: Sun, 3 May 2015 15:12:46 +0200 Subject: [PATCH 04/11] Quickly draw basic grid (no reliable code) --- .../SFMLController/SFMLController.cpp | 3 +- src/View/MainWindow.cpp | 33 +++++++++++++++---- src/View/MainWindow.hpp | 8 +++-- 3 files changed, 35 insertions(+), 9 deletions(-) diff --git a/src/Controllers/SFMLController/SFMLController.cpp b/src/Controllers/SFMLController/SFMLController.cpp index 09a3c25..cd676a9 100644 --- a/src/Controllers/SFMLController/SFMLController.cpp +++ b/src/Controllers/SFMLController/SFMLController.cpp @@ -29,7 +29,8 @@ void SFMLController::run(){ if (event.type == sf::Event::Closed) m_MainWindow.close(); } - m_MainWindow.clearMW(); + m_MainWindow.clearBG(); + m_MainWindow.drawCells(); m_MainWindow.display(); } diff --git a/src/View/MainWindow.cpp b/src/View/MainWindow.cpp index 274fc8e..a381bc5 100644 --- a/src/View/MainWindow.cpp +++ b/src/View/MainWindow.cpp @@ -6,12 +6,16 @@ MainWindow::MainWindow(int width, int height, std::string title): - RenderWindow(sf::VideoMode(width,height), title), - skin() + RenderWindow(sf::VideoMode(width,height), title,sf::Style::Titlebar | sf::Style::Close), + m_skin(), + m_windowMargin(10), + m_sizeCell(120), + m_spaceBetweenCell(10) { - + //Define skin: - skin.push_back(sf::Color(250,248,239)); + m_skin.push_back(sf::Color(250,248,239)); //Background MainWindow + m_skin.push_back(sf::Color(205,192,180)); //Background cells } @@ -20,6 +24,23 @@ MainWindow::MainWindow(int width, int height, std::string title): MainWindow::~MainWindow(){ } -void MainWindow::clearMW(){ - RenderWindow::clear(skin.at(0)); +void MainWindow::clearBG(){ + RenderWindow::clear(m_skin.at(0)); +} + + +void MainWindow::drawCells(){ + + for(int i=0;i<4;i++){ + + for(int j=0;j<4;j++){ + sf::RectangleShape cell(sf::Vector2f(m_sizeCell, m_sizeCell)); + cell.setFillColor(m_skin.at(1)); + int centerOffset=(800-(3*m_spaceBetweenCell+4*m_sizeCell))/2; + int distanceBetweenTopAndGrid=200; + cell.setPosition(centerOffset+j*(m_sizeCell+m_spaceBetweenCell),distanceBetweenTopAndGrid+i*(m_sizeCell+m_spaceBetweenCell)); + RenderWindow::draw(cell); + } + + } } diff --git a/src/View/MainWindow.hpp b/src/View/MainWindow.hpp index a0e7c58..3b13e0c 100644 --- a/src/View/MainWindow.hpp +++ b/src/View/MainWindow.hpp @@ -10,11 +10,15 @@ class MainWindow : public sf::RenderWindow{ private: - std::vector skin; + std::vector m_skin; + int m_windowMargin; + int m_sizeCell; + int m_spaceBetweenCell; public: MainWindow(int width, int height, std::string title); ~MainWindow(); - void clearMW(); + void clearBG(); + void drawCells(); }; From fb7fb90b85b16ee029b3eb4bc2741214d750807b Mon Sep 17 00:00:00 2001 From: manzerbredes Date: Sun, 3 May 2015 17:18:10 +0200 Subject: [PATCH 05/11] Add original 2048 skin ! --- src/View/MainWindow.cpp | 58 +++++++++++++++++++++++++++++++++++++---- src/View/MainWindow.hpp | 1 + 2 files changed, 54 insertions(+), 5 deletions(-) diff --git a/src/View/MainWindow.cpp b/src/View/MainWindow.cpp index a381bc5..7fe547d 100644 --- a/src/View/MainWindow.cpp +++ b/src/View/MainWindow.cpp @@ -13,10 +13,32 @@ MainWindow::MainWindow(int width, int height, std::string title): m_spaceBetweenCell(10) { - //Define skin: - m_skin.push_back(sf::Color(250,248,239)); //Background MainWindow - m_skin.push_back(sf::Color(205,192,180)); //Background cells + //Define original skin: + m_skin.push_back(sf::Color(250,248,239)); //Background MainWindow + m_skin.push_back(sf::Color(205,192,180)); //Background cells + m_skin.push_back(sf::Color(187,173,160)); //Background grid color + m_skin.push_back(sf::Color(119,110,101)); //2 and 4 font color + m_skin.push_back(sf::Color(249,246,242)); //other number font Color + //Skin 2 et le 4 + m_skin.push_back(sf::Color(238,228,218)); //2 + m_skin.push_back(sf::Color(237,224,200)); //4 + + //Skin 8 à 64 + m_skin.push_back(sf::Color(242,177,121)); //8 + m_skin.push_back(sf::Color(245,149,99)); //16 + m_skin.push_back(sf::Color(246,124,95)); //32 + m_skin.push_back(sf::Color(246,94,59)); //64 + + //Skin 128 à 2048 + m_skin.push_back(sf::Color(237,207,114)); //128 + m_skin.push_back(sf::Color(237,204,97)); //256 + m_skin.push_back(sf::Color(237,200,80)); //512 + m_skin.push_back(sf::Color(237,197,63)); //1024 + m_skin.push_back(sf::Color(238,194,46)); //2048 + + //Skin for other number + m_skin.push_back(sf::Color(60,58,50)); //More than 2048 } @@ -31,16 +53,42 @@ void MainWindow::clearBG(){ void MainWindow::drawCells(){ + int centerOffset=(800-(3*m_spaceBetweenCell+4*m_sizeCell))/2; + int distanceBetweenTopAndGrid=200; + int bgsize=3*m_spaceBetweenCell + 4*m_sizeCell + 2*m_spaceBetweenCell; + sf::RectangleShape gridBG(sf::Vector2f(bgsize, bgsize)); + gridBG.setFillColor(m_skin.at(2)); + gridBG.setPosition(centerOffset-m_spaceBetweenCell,distanceBetweenTopAndGrid - m_spaceBetweenCell); + RenderWindow::draw(gridBG); for(int i=0;i<4;i++){ for(int j=0;j<4;j++){ sf::RectangleShape cell(sf::Vector2f(m_sizeCell, m_sizeCell)); cell.setFillColor(m_skin.at(1)); - int centerOffset=(800-(3*m_spaceBetweenCell+4*m_sizeCell))/2; - int distanceBetweenTopAndGrid=200; cell.setPosition(centerOffset+j*(m_sizeCell+m_spaceBetweenCell),distanceBetweenTopAndGrid+i*(m_sizeCell+m_spaceBetweenCell)); RenderWindow::draw(cell); } } } + + + +sf::Color MainWindow::getCellColor(int value){ + + //Id of the first cell color skin + int idStart=5; + + if(value%2==0){ + int result(value); + int id(idStart); + while(result!=2){ + result/=2; + id++; + } + return m_skin.at(id); + } + + + return m_skin.at(idStart+11); +} diff --git a/src/View/MainWindow.hpp b/src/View/MainWindow.hpp index 3b13e0c..50527fc 100644 --- a/src/View/MainWindow.hpp +++ b/src/View/MainWindow.hpp @@ -20,5 +20,6 @@ class MainWindow : public sf::RenderWindow{ void clearBG(); void drawCells(); + sf::Color getCellColor(int value); }; From 1bf3038477b05cf9ead455116ef8125c123a4aae Mon Sep 17 00:00:00 2001 From: manzerbredes Date: Sun, 3 May 2015 17:34:47 +0200 Subject: [PATCH 06/11] Add windowsSize attribute --- src/View/MainWindow.cpp | 6 ++++-- src/View/MainWindow.hpp | 1 + 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/View/MainWindow.cpp b/src/View/MainWindow.cpp index 7fe547d..179b737 100644 --- a/src/View/MainWindow.cpp +++ b/src/View/MainWindow.cpp @@ -13,6 +13,8 @@ MainWindow::MainWindow(int width, int height, std::string title): m_spaceBetweenCell(10) { + m_windowSize=RenderWindow::getSize(); + //Define original skin: m_skin.push_back(sf::Color(250,248,239)); //Background MainWindow m_skin.push_back(sf::Color(205,192,180)); //Background cells @@ -53,8 +55,8 @@ void MainWindow::clearBG(){ void MainWindow::drawCells(){ - int centerOffset=(800-(3*m_spaceBetweenCell+4*m_sizeCell))/2; - int distanceBetweenTopAndGrid=200; + int centerOffset=(m_windowSize.x-(3*m_spaceBetweenCell+4*m_sizeCell))/2; + int distanceBetweenTopAndGrid=180; int bgsize=3*m_spaceBetweenCell + 4*m_sizeCell + 2*m_spaceBetweenCell; sf::RectangleShape gridBG(sf::Vector2f(bgsize, bgsize)); gridBG.setFillColor(m_skin.at(2)); diff --git a/src/View/MainWindow.hpp b/src/View/MainWindow.hpp index 50527fc..89cce0f 100644 --- a/src/View/MainWindow.hpp +++ b/src/View/MainWindow.hpp @@ -14,6 +14,7 @@ class MainWindow : public sf::RenderWindow{ int m_windowMargin; int m_sizeCell; int m_spaceBetweenCell; + sf::Vector2u m_windowSize; public: MainWindow(int width, int height, std::string title); ~MainWindow(); From 6b37ae07ffe0d233b7ff54558d7d39e3e9035e0d Mon Sep 17 00:00:00 2001 From: manzerbredes Date: Sun, 3 May 2015 20:23:43 +0200 Subject: [PATCH 07/11] Add font and fast programming to test the game --- .../SFMLController/SFMLController.cpp | 91 +++++++++++++++++- .../SFMLController/SFMLController.hpp | 5 + src/Model/Game.cpp | 9 ++ src/Model/Game.hpp | 2 + src/Model/Grid.cpp | 5 + src/Model/Grid.hpp | 3 +- src/View/MainWindow.cpp | 71 ++++++++++++-- src/View/MainWindow.hpp | 7 +- src/skin/original/Pragmatica-Medium.ttf | Bin 0 -> 87416 bytes 9 files changed, 178 insertions(+), 15 deletions(-) create mode 100644 src/skin/original/Pragmatica-Medium.ttf diff --git a/src/Controllers/SFMLController/SFMLController.cpp b/src/Controllers/SFMLController/SFMLController.cpp index cd676a9..e037c0b 100644 --- a/src/Controllers/SFMLController/SFMLController.cpp +++ b/src/Controllers/SFMLController/SFMLController.cpp @@ -5,8 +5,7 @@ -SFMLController::SFMLController() : m_MainWindow(800,800, "2P11"){ - +SFMLController::SFMLController() : m_game(), m_MainWindow(800,800, "2P11"){ } @@ -19,6 +18,9 @@ SFMLController::~SFMLController(){ void SFMLController::run(){ + kbdh::Direction keyPress; + + m_game.popRandomNumber(); while(m_MainWindow.isOpen()){ @@ -28,11 +30,94 @@ void SFMLController::run(){ // évènement "fermeture demandée" : on ferme la fenêtre if (event.type == sf::Event::Closed) m_MainWindow.close(); + if (event.type == sf::Event::KeyPressed) + { + if (event.key.code == sf::Keyboard::Up) + { + m_game.swipe(kbdh::Direction::Up); + } + if (event.key.code == sf::Keyboard::Down) + { + m_game.swipe(kbdh::Direction::Down); + // Do something when W is pressed... + } + if (event.key.code == sf::Keyboard::Left){ + + m_game.swipe(kbdh::Direction::Left); + } + if (event.key.code == sf::Keyboard::Right){ + m_game.swipe(kbdh::Direction::Right); + } + + // And so on. + } } + + m_MainWindow.clearBG(); - m_MainWindow.drawCells(); + //m_game.swipe(kbdh::Direction::Left); + m_MainWindow.drawGrid(m_game.getGrid()); m_MainWindow.display(); + + //keyPress=this->waitArrowKeyPress(); + m_game.swipe(keyPress); } } + +//Wait for keypress and return the keyPress. +kbdh::Direction SFMLController::waitArrowKeyPress() +{ + //Initialise keyPress + kbdh::Direction keyPress; + + //White space to remove arrows print by the terminal + std::string spaces=" "; + + //Wait for keypress + while(1){ + if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left)) + { + keyPress=kbdh::Left; + while(sf::Keyboard::isKeyPressed(sf::Keyboard::Left)) + { + //Wait for release and try to remove arrow printed characters + std::cout << "\r" << spaces; + } + break; + } + if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right)) + { + keyPress=kbdh::Right; + while(sf::Keyboard::isKeyPressed(sf::Keyboard::Right)) + { + //Wait for release and try to remove arrow printed characters + std::cout << "\r" << spaces; + } + break; + } + if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up)) + { + keyPress=kbdh::Up; + while(sf::Keyboard::isKeyPressed(sf::Keyboard::Up)) + { + //Wait for release and try to remove arrow printed characters + std::cout << "\r" << spaces; + } + break; + } + if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down)) + { + keyPress=kbdh::Down; + while(sf::Keyboard::isKeyPressed(sf::Keyboard::Down)) + { + //Wait for release and try to remove arrow printed characters + std::cout << "\r" << spaces; + } + break; + } + } + + return keyPress; +} diff --git a/src/Controllers/SFMLController/SFMLController.hpp b/src/Controllers/SFMLController/SFMLController.hpp index 94a22e3..0bb0eea 100644 --- a/src/Controllers/SFMLController/SFMLController.hpp +++ b/src/Controllers/SFMLController/SFMLController.hpp @@ -5,17 +5,22 @@ #include #include #include "../../View/MainWindow.hpp" +#include "../../Model/Game.hpp" +#include "../../Helpers/Keyboard.hpp" +#include class SFMLController{ private: MainWindow m_MainWindow; + Game m_game; public: SFMLController(); ~SFMLController(); + kbdh::Direction waitArrowKeyPress(); void run(); }; diff --git a/src/Model/Game.cpp b/src/Model/Game.cpp index 284d82b..e2ac799 100644 --- a/src/Model/Game.cpp +++ b/src/Model/Game.cpp @@ -83,3 +83,12 @@ int Game::getScore(){ int Game::getNbMove(){ return m_nbMove; } + +std::vector > Game::getGrid(){ + return m_grid.getGrid(); +} + + +int Game::maxStrLenInGrid(){ + return m_grid.maxStrLenInGrid(); +} diff --git a/src/Model/Game.hpp b/src/Model/Game.hpp index 0b2ee4d..e5d19e5 100644 --- a/src/Model/Game.hpp +++ b/src/Model/Game.hpp @@ -35,6 +35,8 @@ class Game //Getters and Setters int getScore(); int getNbMove(); + int maxStrLenInGrid(); + std::vector > getGrid(); }; #endif diff --git a/src/Model/Grid.cpp b/src/Model/Grid.cpp index cc0fe60..7d23c6c 100644 --- a/src/Model/Grid.cpp +++ b/src/Model/Grid.cpp @@ -345,3 +345,8 @@ std::vector Grid::getCol(int col){ return colVect; } + + +std::vector > Grid::getGrid(){ + return m_grid; +} diff --git a/src/Model/Grid.hpp b/src/Model/Grid.hpp index 51168a9..604a6ff 100644 --- a/src/Model/Grid.hpp +++ b/src/Model/Grid.hpp @@ -21,7 +21,6 @@ class Grid int m_lastMoveScore; //Private methods - int maxStrLenInGrid(); public: //Constructor and Destructor @@ -34,6 +33,7 @@ class Grid std::vector rightMerge(std::vector line); std::vector leftMerge(std::vector line); + int maxStrLenInGrid(); //Swipe methods bool swipeRight(); bool swipeLeft(); @@ -55,6 +55,7 @@ class Grid std::vector getCol(int col); void setCol(int col, std::vector colVect); int getLastMoveScore(); + std::vector > getGrid(); }; diff --git a/src/View/MainWindow.cpp b/src/View/MainWindow.cpp index 179b737..784effb 100644 --- a/src/View/MainWindow.cpp +++ b/src/View/MainWindow.cpp @@ -12,7 +12,7 @@ MainWindow::MainWindow(int width, int height, std::string title): m_sizeCell(120), m_spaceBetweenCell(10) { - + //Set windows size m_windowSize=RenderWindow::getSize(); //Define original skin: @@ -53,35 +53,85 @@ void MainWindow::clearBG(){ } -void MainWindow::drawCells(){ +void MainWindow::drawGrid(std::vector > grid){ + //Usefull variable int centerOffset=(m_windowSize.x-(3*m_spaceBetweenCell+4*m_sizeCell))/2; int distanceBetweenTopAndGrid=180; - int bgsize=3*m_spaceBetweenCell + 4*m_sizeCell + 2*m_spaceBetweenCell; - sf::RectangleShape gridBG(sf::Vector2f(bgsize, bgsize)); + int gridsize=3*m_spaceBetweenCell + 4*m_sizeCell + 2*m_spaceBetweenCell; + + //First draw the grid + sf::RectangleShape gridBG(sf::Vector2f(gridsize, gridsize)); gridBG.setFillColor(m_skin.at(2)); gridBG.setPosition(centerOffset-m_spaceBetweenCell,distanceBetweenTopAndGrid - m_spaceBetweenCell); RenderWindow::draw(gridBG); + for(int i=0;i<4;i++){ for(int j=0;j<4;j++){ - sf::RectangleShape cell(sf::Vector2f(m_sizeCell, m_sizeCell)); - cell.setFillColor(m_skin.at(1)); - cell.setPosition(centerOffset+j*(m_sizeCell+m_spaceBetweenCell),distanceBetweenTopAndGrid+i*(m_sizeCell+m_spaceBetweenCell)); - RenderWindow::draw(cell); + int x=centerOffset+j*(m_sizeCell+m_spaceBetweenCell); + int y=distanceBetweenTopAndGrid+i*(m_sizeCell+m_spaceBetweenCell); + int value=grid.at(i).at(j); + this->drawCell(x,y,value); } } } +void MainWindow::drawCell(int x, int y, int value){ + + //Init RectangleShape + sf::RectangleShape cell(sf::Vector2f(m_sizeCell, m_sizeCell)); + + //Define color, checking skin + cell.setFillColor(this->getCellColor(value)); + + //Set position + cell.setPosition(x,y); + + //Draw the cell + RenderWindow::draw(cell); + + + std::stringstream valueStream; + valueStream << value; + + std::string valueString(valueStream.str()); + + int fontSize(m_sizeCell/2); + int valueSize(valueString.size()); + + + int fontX=x+(m_sizeCell/2)-((valueSize*(fontSize-20))/2); + int fontY=y+(m_sizeCell/2)-(fontSize/2)-10; + + + sf::Font font; + font.loadFromFile("./src/skin/original/Pragmatica-Medium.ttf"); + sf::Text text; + text.setFont(font); + text.setCharacterSize(fontSize); + text.setString(valueString); + if(value==2 || value==4) + text.setColor(m_skin.at(3)); + else + text.setColor(m_skin.at(4)); + text.setPosition(fontX,fontY); + + if(value != 0) + RenderWindow::draw(text); +} sf::Color MainWindow::getCellColor(int value){ //Id of the first cell color skin int idStart=5; - if(value%2==0){ + if(value==0){ + return m_skin.at(1); + } + else if(value%2==0){ int result(value); int id(idStart); while(result!=2){ @@ -91,6 +141,7 @@ sf::Color MainWindow::getCellColor(int value){ return m_skin.at(id); } - return m_skin.at(idStart+11); } + + diff --git a/src/View/MainWindow.hpp b/src/View/MainWindow.hpp index 89cce0f..aabdb09 100644 --- a/src/View/MainWindow.hpp +++ b/src/View/MainWindow.hpp @@ -3,6 +3,8 @@ #include #include +#include +#include #include #include @@ -15,12 +17,15 @@ class MainWindow : public sf::RenderWindow{ int m_sizeCell; int m_spaceBetweenCell; sf::Vector2u m_windowSize; + public: MainWindow(int width, int height, std::string title); ~MainWindow(); void clearBG(); - void drawCells(); + void drawGrid(std::vector > grid); + void drawCell(int x, int y, int value); sf::Color getCellColor(int value); + }; diff --git a/src/skin/original/Pragmatica-Medium.ttf b/src/skin/original/Pragmatica-Medium.ttf new file mode 100644 index 0000000000000000000000000000000000000000..f5fee8ddd9cc21d8b808dfa0fcad49df9cb282e2 GIT binary patch literal 87416 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 literal 0 HcmV?d00001 From 3384204edca8720958b7d20c72956037b03238ae Mon Sep 17 00:00:00 2001 From: manzerbredes Date: Mon, 4 May 2015 12:55:15 +0200 Subject: [PATCH 08/11] Clear some things --- .../SFMLController/SFMLController.cpp | 3 +- src/Model/Grid.cpp | 1 + src/View/MainWindow.cpp | 118 ++++++++++++++---- src/View/MainWindow.hpp | 17 ++- 4 files changed, 109 insertions(+), 30 deletions(-) diff --git a/src/Controllers/SFMLController/SFMLController.cpp b/src/Controllers/SFMLController/SFMLController.cpp index e037c0b..3d5d4a1 100644 --- a/src/Controllers/SFMLController/SFMLController.cpp +++ b/src/Controllers/SFMLController/SFMLController.cpp @@ -56,7 +56,8 @@ void SFMLController::run(){ m_MainWindow.clearBG(); //m_game.swipe(kbdh::Direction::Left); - m_MainWindow.drawGrid(m_game.getGrid()); + std::vector > aaa=m_game.getGrid(); + m_MainWindow.drawGrid(aaa,m_game.isOver()); m_MainWindow.display(); //keyPress=this->waitArrowKeyPress(); diff --git a/src/Model/Grid.cpp b/src/Model/Grid.cpp index 7d23c6c..64d8048 100644 --- a/src/Model/Grid.cpp +++ b/src/Model/Grid.cpp @@ -11,6 +11,7 @@ Grid::Grid(): m_size(4), m_grid(4){ m_grid.at(i).push_back(0); } } + //m_grid.at(3).at(0)=2048; } //Destructor diff --git a/src/View/MainWindow.cpp b/src/View/MainWindow.cpp index 784effb..659450f 100644 --- a/src/View/MainWindow.cpp +++ b/src/View/MainWindow.cpp @@ -8,19 +8,31 @@ MainWindow::MainWindow(int width, int height, std::string title): RenderWindow(sf::VideoMode(width,height), title,sf::Style::Titlebar | sf::Style::Close), m_skin(), - m_windowMargin(10), - m_sizeCell(120), - m_spaceBetweenCell(10) + m_windowSize(), + m_cellSize(105,105), + m_gridSize(0,0), + m_gridPosition(), + m_spaceBetweenCell(15), + m_font() { //Set windows size m_windowSize=RenderWindow::getSize(); + + m_gridPosition=sf::Vector2u(50,200); + + + + //Load font + m_font.loadFromFile("./src/skin/original/Pragmatica-Medium.ttf"); //Define original skin: m_skin.push_back(sf::Color(250,248,239)); //Background MainWindow m_skin.push_back(sf::Color(205,192,180)); //Background cells m_skin.push_back(sf::Color(187,173,160)); //Background grid color m_skin.push_back(sf::Color(119,110,101)); //2 and 4 font color + m_skin.push_back(sf::Color(143,122,102)); //Button color m_skin.push_back(sf::Color(249,246,242)); //other number font Color + m_skin.push_back(sf::Color(238,228,218,186)); //Game over color bg //Skin 2 et le 4 m_skin.push_back(sf::Color(238,228,218)); //2 @@ -53,36 +65,46 @@ void MainWindow::clearBG(){ } -void MainWindow::drawGrid(std::vector > grid){ +void MainWindow::drawGrid(std::vector > grid, bool gameIsOver){ - //Usefull variable - int centerOffset=(m_windowSize.x-(3*m_spaceBetweenCell+4*m_sizeCell))/2; - int distanceBetweenTopAndGrid=180; - int gridsize=3*m_spaceBetweenCell + 4*m_sizeCell + 2*m_spaceBetweenCell; //First draw the grid - sf::RectangleShape gridBG(sf::Vector2f(gridsize, gridsize)); - gridBG.setFillColor(m_skin.at(2)); - gridBG.setPosition(centerOffset-m_spaceBetweenCell,distanceBetweenTopAndGrid - m_spaceBetweenCell); - RenderWindow::draw(gridBG); + int gridX=m_gridPosition.x; + int gridY=m_gridPosition.y; - for(int i=0;i<4;i++){ + m_gridSize.x=(grid.at(0).size()*m_cellSize.x)+(grid.at(0).size()*m_spaceBetweenCell)+m_spaceBetweenCell; + m_gridSize.y=(grid.size()*m_cellSize.y)+(grid.size()*m_spaceBetweenCell)+m_spaceBetweenCell; - for(int j=0;j<4;j++){ - int x=centerOffset+j*(m_sizeCell+m_spaceBetweenCell); - int y=distanceBetweenTopAndGrid+i*(m_sizeCell+m_spaceBetweenCell); + //Draw the grid + sf::RectangleShape gridShape(sf::Vector2f(m_gridSize.x,m_gridSize.y)); + gridShape.setFillColor(m_skin.at(2)); + gridShape.setPosition(gridX,gridY); + RenderWindow::draw(gridShape); + + for(int i=0;idrawCell(x,y,value); + + this->drawCell(cellX,cellY,value); + } } + + if(gameIsOver) + this->drawGameOver(gridX,gridY); + this->drawATH(); } void MainWindow::drawCell(int x, int y, int value){ //Init RectangleShape - sf::RectangleShape cell(sf::Vector2f(m_sizeCell, m_sizeCell)); + sf::RectangleShape cell(sf::Vector2f(m_cellSize.x, m_cellSize.y)); //Define color, checking skin cell.setFillColor(this->getCellColor(value)); @@ -99,18 +121,20 @@ void MainWindow::drawCell(int x, int y, int value){ std::string valueString(valueStream.str()); - int fontSize(m_sizeCell/2); + int fontSize(m_cellSize.x/2); + int fontSizeFact=15; + if(value>=1024) + fontSize-=fontSizeFact; int valueSize(valueString.size()); - int fontX=x+(m_sizeCell/2)-((valueSize*(fontSize-20))/2); - int fontY=y+(m_sizeCell/2)-(fontSize/2)-10; + int fontX=x+(m_cellSize.x/2)-((valueSize*(fontSize-20))/2); + int fontY=y+(m_cellSize.y/2)-(fontSize/2)-10; - sf::Font font; - font.loadFromFile("./src/skin/original/Pragmatica-Medium.ttf"); sf::Text text; - text.setFont(font); + text.setFont(m_font); + text.setStyle(sf::Text::Bold); text.setCharacterSize(fontSize); text.setString(valueString); if(value==2 || value==4) @@ -126,7 +150,7 @@ void MainWindow::drawCell(int x, int y, int value){ sf::Color MainWindow::getCellColor(int value){ //Id of the first cell color skin - int idStart=5; + int idStart=7; if(value==0){ return m_skin.at(1); @@ -144,4 +168,48 @@ sf::Color MainWindow::getCellColor(int value){ return m_skin.at(idStart+11); } +void MainWindow::drawGameOver(int gridX, int gridY){ + + sf::RectangleShape gridShape(sf::Vector2f(m_gridSize.x,m_gridSize.y)); + gridShape.setFillColor(m_skin.at(6)); + gridShape.setPosition(gridX,gridY); + RenderWindow::draw(gridShape); +} + +void MainWindow::drawATH(){ + + int titleX=m_gridPosition.x; + int titleY=m_gridPosition.y-190; + + + //==================== Draw title ==================== + sf::Text text; + text.setFont(m_font); + text.setStyle(sf::Text::Bold); + text.setCharacterSize(80); + text.setColor(m_skin.at(3)); + text.setPosition(titleX,titleY); + text.setString("2048"); + + RenderWindow::draw(text); + + + //==================== Draw score ==================== + + int scoreSizeX=110; + int scoreX=m_gridPosition.x+m_gridSize.x-scoreSizeX; + + sf::RectangleShape scoreShape(sf::Vector2f(scoreSizeX,60)); + scoreShape.setFillColor(m_skin.at(2)); + scoreShape.setPosition(scoreX,titleY+25); + RenderWindow::draw(scoreShape); + + //==================== Draw best score ==================== + + + sf::RectangleShape bestScoreShape(sf::Vector2f(scoreSizeX,60)); + bestScoreShape.setFillColor(m_skin.at(2)); + bestScoreShape.setPosition(scoreX-scoreSizeX-5,titleY+25); + RenderWindow::draw(bestScoreShape); +} diff --git a/src/View/MainWindow.hpp b/src/View/MainWindow.hpp index aabdb09..729b961 100644 --- a/src/View/MainWindow.hpp +++ b/src/View/MainWindow.hpp @@ -13,19 +13,28 @@ class MainWindow : public sf::RenderWindow{ private: std::vector m_skin; - int m_windowMargin; - int m_sizeCell; - int m_spaceBetweenCell; + //int m_windowMargin; + //int m_sizeCell; + + sf::Font m_font; + //Coordonates sf::Vector2u m_windowSize; + sf::Vector2u m_gridSize; + sf::Vector2u m_cellSize; + + sf::Vector2u m_gridPosition; + int m_spaceBetweenCell; public: MainWindow(int width, int height, std::string title); ~MainWindow(); void clearBG(); - void drawGrid(std::vector > grid); + void drawGrid(std::vector > grid, bool gameIsOver); void drawCell(int x, int y, int value); sf::Color getCellColor(int value); + void drawGameOver(int gridX, int griY); + void drawATH(); }; From 1bebaf0f924c83bfb5a91bafefcb69d98e3b8b05 Mon Sep 17 00:00:00 2001 From: manzerbredes Date: Mon, 4 May 2015 13:08:45 +0200 Subject: [PATCH 09/11] Prefer extends Game to grid than encapsulation --- src/Model/Game.cpp | 36 ++++++++++++++++++------------------ src/Model/Game.hpp | 10 +++++----- src/Model/Grid.hpp | 3 ++- 3 files changed, 25 insertions(+), 24 deletions(-) diff --git a/src/Model/Game.cpp b/src/Model/Game.cpp index e2ac799..9c67184 100644 --- a/src/Model/Game.cpp +++ b/src/Model/Game.cpp @@ -4,7 +4,7 @@ //==================== Constructor and Destructor ==================== //Constructor -Game::Game() : m_grid(), m_score(0), m_nbMove(0){ +Game::Game() : Grid(), m_nbMove(0), m_score(0){ } //Destructor @@ -21,21 +21,21 @@ bool Game::swipe(kbdh::Direction direction){ switch(direction){ case kbdh::Left: - moveDone=m_grid.swipeLeft(); + moveDone=swipeLeft(); break; case kbdh::Right: - moveDone=m_grid.swipeRight(); + moveDone=swipeRight(); break; case kbdh::Up: - moveDone=m_grid.swipeUp(); + moveDone=swipeUp(); break; case kbdh::Down: - moveDone=m_grid.swipeDown(); + moveDone=swipeDown(); break; } if(moveDone){ - m_score+=m_grid.getLastMoveScore(); + m_score+=m_lastMoveScore; m_nbMove++; this->popRandomNumber(); } @@ -46,17 +46,17 @@ bool Game::swipe(kbdh::Direction direction){ //Cout the grid void Game::coutGrid(){ - std::cout << m_grid.description(); + std::cout << this->description(); } //Return true if the game is lost. False else. -bool Game::isOver(){ - return m_grid.isOver(); -} +//bool Game::isOver(){ + //return m_grid.isOver(); +//} //Pop a random number on the grid void Game::popRandomNumber(){ - std::tuple coord(m_grid.getRandomEmptyCellCoord()); + std::tuple coord(Grid::getRandomEmptyCellCoord()); int percent=rand() % 100; @@ -70,7 +70,7 @@ void Game::popRandomNumber(){ } - m_grid.setCell(coord, number); + Grid::setCell(coord, number); } //==================== Getters and Setter ==================== @@ -84,11 +84,11 @@ int Game::getNbMove(){ return m_nbMove; } -std::vector > Game::getGrid(){ - return m_grid.getGrid(); -} +//std::vector > Game::getGrid(){ + //return m_grid.getGrid(); +//} -int Game::maxStrLenInGrid(){ - return m_grid.maxStrLenInGrid(); -} +//int Game::maxStrLenInGrid(){ + //return m_grid.maxStrLenInGrid(); +//} diff --git a/src/Model/Game.hpp b/src/Model/Game.hpp index e5d19e5..77be7d7 100644 --- a/src/Model/Game.hpp +++ b/src/Model/Game.hpp @@ -13,11 +13,11 @@ #include "Grid.hpp" #include -class Game +class Game : public Grid { private: //Members - Grid m_grid; + //Grid m_grid; int m_score; int m_nbMove; @@ -30,13 +30,13 @@ class Game bool swipe(kbdh::Direction direction); void coutGrid(); void popRandomNumber(); - bool isOver(); + //bool isOver(); //Getters and Setters int getScore(); int getNbMove(); - int maxStrLenInGrid(); - std::vector > getGrid(); + //int maxStrLenInGrid(); + //std::vector > getGrid(); }; #endif diff --git a/src/Model/Grid.hpp b/src/Model/Grid.hpp index 604a6ff..22416b0 100644 --- a/src/Model/Grid.hpp +++ b/src/Model/Grid.hpp @@ -16,8 +16,9 @@ class Grid { private: //Members - int m_size; + protected: std::vector > m_grid; + int m_size; int m_lastMoveScore; //Private methods From 164d94eec1b88f0e9a466585b512fc8dca4c80ed Mon Sep 17 00:00:00 2001 From: manzerbredes Date: Mon, 4 May 2015 14:00:54 +0200 Subject: [PATCH 10/11] Add stats class, make a functionnal SFML game --- .../SFMLController/SFMLController.cpp | 2 +- src/Model/CMakeLists.txt | 2 +- src/Model/Game.cpp | 14 ++-- src/Model/Game.hpp | 8 +-- src/Model/Stats.cpp | 29 ++++++++ src/Model/Stats.hpp | 30 ++++++++ src/View/MainWindow.cpp | 68 +++++++++++++++---- src/View/MainWindow.hpp | 5 +- 8 files changed, 127 insertions(+), 31 deletions(-) create mode 100644 src/Model/Stats.cpp create mode 100644 src/Model/Stats.hpp diff --git a/src/Controllers/SFMLController/SFMLController.cpp b/src/Controllers/SFMLController/SFMLController.cpp index 3d5d4a1..bf4a069 100644 --- a/src/Controllers/SFMLController/SFMLController.cpp +++ b/src/Controllers/SFMLController/SFMLController.cpp @@ -57,7 +57,7 @@ void SFMLController::run(){ m_MainWindow.clearBG(); //m_game.swipe(kbdh::Direction::Left); std::vector > aaa=m_game.getGrid(); - m_MainWindow.drawGrid(aaa,m_game.isOver()); + m_MainWindow.drawGame(aaa,m_game.isOver(), m_game.getStats()); m_MainWindow.display(); //keyPress=this->waitArrowKeyPress(); diff --git a/src/Model/CMakeLists.txt b/src/Model/CMakeLists.txt index 888589e..4ebe544 100644 --- a/src/Model/CMakeLists.txt +++ b/src/Model/CMakeLists.txt @@ -1,2 +1,2 @@ #Make Model lib -add_library(Model Grid.cpp Game.cpp) +add_library(Model Grid.cpp Game.cpp Stats.cpp) diff --git a/src/Model/Game.cpp b/src/Model/Game.cpp index 9c67184..5781f54 100644 --- a/src/Model/Game.cpp +++ b/src/Model/Game.cpp @@ -4,7 +4,7 @@ //==================== Constructor and Destructor ==================== //Constructor -Game::Game() : Grid(), m_nbMove(0), m_score(0){ +Game::Game() : Grid(), m_stats(){ } //Destructor @@ -35,8 +35,8 @@ bool Game::swipe(kbdh::Direction direction){ } if(moveDone){ - m_score+=m_lastMoveScore; - m_nbMove++; + m_stats.incScore(m_lastMoveScore); + m_stats.incnbMove(); this->popRandomNumber(); } @@ -75,14 +75,10 @@ void Game::popRandomNumber(){ //==================== Getters and Setter ==================== //Retrieve the Score -int Game::getScore(){ - return m_score; +Stats Game::getStats(){ + return m_stats; } -//Retrieve the number of moves -int Game::getNbMove(){ - return m_nbMove; -} //std::vector > Game::getGrid(){ //return m_grid.getGrid(); diff --git a/src/Model/Game.hpp b/src/Model/Game.hpp index 77be7d7..e468176 100644 --- a/src/Model/Game.hpp +++ b/src/Model/Game.hpp @@ -11,6 +11,7 @@ #include #include "../Helpers/Keyboard.hpp" #include "Grid.hpp" +#include "Stats.hpp" #include class Game : public Grid @@ -18,9 +19,7 @@ class Game : public Grid private: //Members //Grid m_grid; - int m_score; - int m_nbMove; - + Stats m_stats; public: //Constructor and Destructor Game(); @@ -33,8 +32,7 @@ class Game : public Grid //bool isOver(); //Getters and Setters - int getScore(); - int getNbMove(); + Stats getStats(); //int maxStrLenInGrid(); //std::vector > getGrid(); }; diff --git a/src/Model/Stats.cpp b/src/Model/Stats.cpp new file mode 100644 index 0000000..8bada78 --- /dev/null +++ b/src/Model/Stats.cpp @@ -0,0 +1,29 @@ +#include "Stats.hpp" + + +Stats::Stats() : + m_score(0), + m_nbMove(0) +{ + +} + +Stats::~Stats(){ +} + + + +void Stats::incScore(int value){ + m_score+=value; +} +void Stats::incnbMove(){ + m_nbMove++; +} + + +int Stats::getScore(){ + return m_score; +} +int Stats::getNbMove(){ + return m_nbMove; +} diff --git a/src/Model/Stats.hpp b/src/Model/Stats.hpp new file mode 100644 index 0000000..49c7356 --- /dev/null +++ b/src/Model/Stats.hpp @@ -0,0 +1,30 @@ +#ifndef __STATS__ +#define __STATS__ + +#include + + + + + +class Stats{ + + private: + int m_score; + int m_nbMove; + public: + + Stats(); + ~Stats(); + void incScore(int value); + void incnbMove(); + + + int getScore(); + int getNbMove(); + + + +}; + +#endif diff --git a/src/View/MainWindow.cpp b/src/View/MainWindow.cpp index 659450f..23b8677 100644 --- a/src/View/MainWindow.cpp +++ b/src/View/MainWindow.cpp @@ -18,7 +18,7 @@ MainWindow::MainWindow(int width, int height, std::string title): //Set windows size m_windowSize=RenderWindow::getSize(); - m_gridPosition=sf::Vector2u(50,200); + m_gridPosition=sf::Vector2u(0,200); @@ -75,6 +75,11 @@ void MainWindow::drawGrid(std::vector > grid, bool gameIsOver){ m_gridSize.x=(grid.at(0).size()*m_cellSize.x)+(grid.at(0).size()*m_spaceBetweenCell)+m_spaceBetweenCell; m_gridSize.y=(grid.size()*m_cellSize.y)+(grid.size()*m_spaceBetweenCell)+m_spaceBetweenCell; + //Center: + m_gridPosition.x=m_windowSize.x/2-m_gridSize.x/2; + m_gridPosition.y=220; + + //Draw the grid sf::RectangleShape gridShape(sf::Vector2f(m_gridSize.x,m_gridSize.y)); gridShape.setFillColor(m_skin.at(2)); @@ -97,7 +102,6 @@ void MainWindow::drawGrid(std::vector > grid, bool gameIsOver){ if(gameIsOver) this->drawGameOver(gridX,gridY); - this->drawATH(); } @@ -177,7 +181,7 @@ void MainWindow::drawGameOver(int gridX, int gridY){ } -void MainWindow::drawATH(){ +void MainWindow::drawATH(Stats stats){ int titleX=m_gridPosition.x; int titleY=m_gridPosition.y-190; @@ -195,21 +199,57 @@ void MainWindow::drawATH(){ RenderWindow::draw(text); - //==================== Draw score ==================== + //==================== Draw best score ==================== - int scoreSizeX=110; - int scoreX=m_gridPosition.x+m_gridSize.x-scoreSizeX; + int scoreAndBestScoreFontSize(20); - sf::RectangleShape scoreShape(sf::Vector2f(scoreSizeX,60)); + int bestScoreSizeX=110; + int bestScoreSizeY=60; + int bestScoreX=m_gridPosition.x+m_gridSize.x-bestScoreSizeX; + int bestScoreY=titleY+25; + + sf::RectangleShape bestScoreShape(sf::Vector2f(bestScoreSizeX,bestScoreSizeY)); + bestScoreShape.setFillColor(m_skin.at(2)); + bestScoreShape.setPosition(bestScoreX,bestScoreY); + RenderWindow::draw(bestScoreShape); + + text.setString("BEST"); + text.setPosition(bestScoreX+bestScoreSizeY-scoreAndBestScoreFontSize-5,bestScoreY+12); + text.setCharacterSize(scoreAndBestScoreFontSize-5); + text.setColor(m_skin.at(7)); + + RenderWindow::draw(text); + + //==================== Draw score ==================== + + int scoreX=bestScoreX-bestScoreSizeX-5; + int scoreY=bestScoreY; + int scoreSizeX=bestScoreSizeX; + int scoreSizeY=bestScoreSizeY; + int scoreLength=std::to_string(stats.getScore()).size(); + + sf::RectangleShape scoreShape(sf::Vector2f(scoreSizeX,scoreSizeY)); scoreShape.setFillColor(m_skin.at(2)); - scoreShape.setPosition(scoreX,titleY+25); + scoreShape.setPosition(scoreX,scoreY); RenderWindow::draw(scoreShape); - //==================== Draw best score ==================== - - sf::RectangleShape bestScoreShape(sf::Vector2f(scoreSizeX,60)); - bestScoreShape.setFillColor(m_skin.at(2)); - bestScoreShape.setPosition(scoreX-scoreSizeX-5,titleY+25); - RenderWindow::draw(bestScoreShape); + text.setString("SCORE"); + text.setPosition(scoreX+scoreSizeY-scoreAndBestScoreFontSize-10,scoreY+12); + text.setCharacterSize(scoreAndBestScoreFontSize-5); + text.setColor(m_skin.at(7)); + + RenderWindow::draw(text); + + text.setString(std::to_string(stats.getScore())); + text.setPosition(scoreX+scoreSizeY-((scoreLength+20)/2)-scoreAndBestScoreFontSize+10,scoreY+scoreSizeY - scoreAndBestScoreFontSize-10); + text.setCharacterSize(scoreAndBestScoreFontSize); + text.setColor(sf::Color::White); + + RenderWindow::draw(text); +} + +void MainWindow::drawGame(std::vector > grid, bool gameIsOver, Stats stats){ + this->drawGrid(grid,gameIsOver); + this->drawATH(stats); } diff --git a/src/View/MainWindow.hpp b/src/View/MainWindow.hpp index 729b961..072a7ec 100644 --- a/src/View/MainWindow.hpp +++ b/src/View/MainWindow.hpp @@ -5,6 +5,7 @@ #include #include #include +#include "../Model/Stats.hpp" #include #include @@ -36,5 +37,7 @@ class MainWindow : public sf::RenderWindow{ void drawGameOver(int gridX, int griY); - void drawATH(); + void drawATH(Stats stats); + + void drawGame(std::vector > grid, bool gameIsOver, Stats stats); }; From a1c9b58c29746793f00520d46e1397abe2b0e711 Mon Sep 17 00:00:00 2001 From: manzerbredes Date: Mon, 4 May 2015 14:05:06 +0200 Subject: [PATCH 11/11] Resize window, center number --- src/Controllers/SFMLController/SFMLController.cpp | 2 +- src/View/MainWindow.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Controllers/SFMLController/SFMLController.cpp b/src/Controllers/SFMLController/SFMLController.cpp index bf4a069..1c21753 100644 --- a/src/Controllers/SFMLController/SFMLController.cpp +++ b/src/Controllers/SFMLController/SFMLController.cpp @@ -5,7 +5,7 @@ -SFMLController::SFMLController() : m_game(), m_MainWindow(800,800, "2P11"){ +SFMLController::SFMLController() : m_game(), m_MainWindow(600,800, "2P11"){ } diff --git a/src/View/MainWindow.cpp b/src/View/MainWindow.cpp index 23b8677..ea4346d 100644 --- a/src/View/MainWindow.cpp +++ b/src/View/MainWindow.cpp @@ -133,7 +133,7 @@ void MainWindow::drawCell(int x, int y, int value){ int fontX=x+(m_cellSize.x/2)-((valueSize*(fontSize-20))/2); - int fontY=y+(m_cellSize.y/2)-(fontSize/2)-10; + int fontY=y+(m_cellSize.y/2)-(fontSize/2)-9; sf::Text text;