diff --git a/Controller/FinishScene.h b/Controller/FinishScene.h new file mode 100644 index 0000000..b6c2388 --- /dev/null +++ b/Controller/FinishScene.h @@ -0,0 +1,41 @@ +#ifndef INC_2048BALLS_FINISHSCENE_H +#define INC_2048BALLS_FINISHSCENE_H + +#include +#include "scn.h" +#include "../View/MyDraw.h" + +class FinishScene { +public: + FinishScene(); + int show(sf::RenderWindow *window, MyDraw *draw, double totalTime); + void setScore(int score); +private: + int score; + Label label; +}; + +FinishScene::FinishScene() : label(410 - 10, 460 - 10, 20, 20, "", 50) {} + +/** + * Call on every step to show + * @param window sf::RenderWindow + * @param draw implementation of MyDraw + * @return the id of the next scene to show + */ +int FinishScene::show(sf::RenderWindow *window, MyDraw *draw, double totalTime) { + label.st = "You fail! \nYour score is " + std::to_string(score) + "!!!"; + draw->drawLabel(label, (int) (50.0 * totalTime)); + window->setMouseCursorVisible(false); + if (totalTime > 5) { + window->setMouseCursorVisible(true); + return scn::MENU; + } + return scn::FINISH; +} + +void FinishScene::setScore(int score) { + this->score = score; +} + +#endif //INC_2048BALLS_FINISHSCENE_H diff --git a/Controller/Game.h b/Controller/Game.h new file mode 100644 index 0000000..6b4711b --- /dev/null +++ b/Controller/Game.h @@ -0,0 +1,92 @@ +#ifndef INC_2048BALLS_GAME_H +#define INC_2048BALLS_GAME_H + +#include +#include +#include +#include + +#include "../model/Engine.h" +#include "../View/MyDraw.h" +#include "GameScene.h" +#include "OpenningScene.h" +#include "MenuScene.h" +#include "FinishScene.h" + +class Game { +public: + Game(); + void run(); + +private: + void manageScenes(double time); + sf::RenderWindow *window; + sf::Clock clock; + + MyDraw *draw; + OpeningScene openingScene; + MenuScene menuScene; + GameScene gameScene; + FinishScene finishScene; + + int currentScene = scn::OPENING; + float totalTime = 0; + + const sf::Color BACKGROUND_COLOR = sf::Color(182, 92, 0); +}; + +Game::Game() { + window = new sf::RenderWindow(sf::VideoMode(820, 920), "2048 - Balls", sf::Style::None); + draw = new MyDraw(window); +} + +/** + * Call to start the main loop + */ +void Game::run() { + while (window->isOpen()) { + window->clear(BACKGROUND_COLOR); + + double time = clock.getElapsedTime().asMicroseconds(); + clock.restart(); + totalTime += time / 1e6; + time = time / 1.8e5 * 0.6; + time = (time > 0.5) ? 0.5 : time; + + manageScenes(time); + window->display(); + } +} + +/** + * Show scenes in some order + * @param time timestamp + * @param totalTime time since the start of the game + */ +void Game::manageScenes(double time) { + int newScene = scn::OPENING; + if (currentScene == scn::OPENING) { + newScene = openingScene.show(window, draw, totalTime); + } else + if (currentScene == scn::MENU) { + newScene = menuScene.show(window, draw); + if (newScene == scn::GAME) + gameScene.init(); + } else + if (currentScene == scn::GAME) { + newScene = gameScene.show(window, draw, time); + if (newScene == scn::FINISH) + finishScene.setScore(gameScene.getScore()); + } else + if (currentScene == scn::FINISH) { + newScene = finishScene.show(window, draw, totalTime); + } + + if (newScene != currentScene) { + totalTime = 0; + currentScene = newScene; + } +} + + +#endif //INC_2048BALLS_GAME_H diff --git a/Controller/GameScene.h b/Controller/GameScene.h new file mode 100644 index 0000000..190b5a3 --- /dev/null +++ b/Controller/GameScene.h @@ -0,0 +1,94 @@ +#ifndef GAME_SCENE_H_INCLUDED +#define GAME_SCENE_H_INCLUDED + + +#include "scn.h" + +class GameScene { +public: + GameScene(); + int show(sf::RenderWindow *window, MyDraw *draw, double time); + int init(); + int getScore(); +private: + Engine engine; + bool push_ball = false; + + Label titleLabel; + Label swellLabel; +}; + +GameScene::GameScene() : titleLabel(Label(10, 10, 220, 90, "2048", 92)), + swellLabel(Label(350, 60, 220, 45, "doing swell", 50)) {} + +int GameScene::init() { + engine.setLose(false); + engine.initMap(); + push_ball = false; +} + +/** + * Call on every step to show + * @param window sf::RenderWindow + * @param draw implementation of MyDraw + * @return the id of the next scene to show + */ + +int GameScene::show(sf::RenderWindow *window, MyDraw *draw, double time) { + if (!engine.getLose()) { + engine.step(time); + engine.analiseMap(); + if (push_ball) { + engine.smartPushBall(); + push_ball = false; + } + } + draw->drawBalls(engine.getBalls()); + draw->drawLabel(titleLabel, 255); + draw->drawLabel(Label(330, 10, 220, 45, "Score: " + std::to_string(engine.score()), 50), 255); + + if (engine.getLose() == 0) { + draw->drawLabel(swellLabel, 255); + } else { + return scn::FINISH; + } + + + sf::Event event {}; + while (window->pollEvent(event)) { + if (event.type == sf::Event::Closed) window->close(); + if (event.type == sf::Event::KeyPressed) { + if (event.key.code == sf::Keyboard::Escape) { + return scn::MENU; + } + if (event.key.code == sf::Keyboard::W) { + engine.setGravity(Vec2d(0, -10)); + push_ball = true; + } + if (event.key.code == sf::Keyboard::S) { + engine.setGravity(Vec2d(0, 10)); + push_ball = true; + } + if (event.key.code == sf::Keyboard::D) { + engine.setGravity(Vec2d(10, 0)); + push_ball = true; + } + if (event.key.code == sf::Keyboard::A) { + engine.setGravity(Vec2d(-10, 0)); + push_ball = true; + } + + } + } + return scn::GAME; +} + +/** + * + * @return player score + */ +int GameScene::getScore() { + return engine.score(); +} + +#endif // GAME_SCENE_H_INCLUDED diff --git a/Controller/MenuScene.h b/Controller/MenuScene.h new file mode 100644 index 0000000..8de0f59 --- /dev/null +++ b/Controller/MenuScene.h @@ -0,0 +1,45 @@ +#ifndef MENU_SCENE_H_INCLUDED +#define MENU_SCENE_H_INCLUDED + +class MenuScene { +public: + MenuScene(); + int show(sf::RenderWindow *window, MyDraw *draw); + +private: + Button startButton; + Button exitButton; +}; + +MenuScene::MenuScene() : startButton(410 - 200, 390 - 70, 400, 140, "START", 100), + exitButton(410 - 200, 530 - 70, 400, 140, "EXIT", 100) {} + +/** + * Call on every step to show + * @param window sf::RenderWindow + * @param draw implementation of MyDraw + * @return the id of the next scene to show + */ +int MenuScene::show(sf::RenderWindow *window, MyDraw *draw) { + sf::Vector2i pixelPos = sf::Mouse::getPosition(*window); + sf::Vector2f pos = window->mapPixelToCoords(pixelPos); + draw->drawButton(startButton, pos.x, pos.y); + draw->drawButton(exitButton, pos.x, pos.y); + + sf::Event event; + while (window->pollEvent(event)) { + if (event.type == sf::Event::Closed) window->close(); + if (event.type == sf::Event::MouseButtonPressed) + if (event.key.code == sf::Mouse::Left) { + if (startButton.is_in(pos.x, pos.y)) { + return scn::GAME; + } + if (exitButton.is_in(pos.x, pos.y)) { + window->close(); + } + } + } + return scn::MENU; +} + +#endif // MENU_SCENE_H_INCLUDED diff --git a/Controller/OpenningScene.h b/Controller/OpenningScene.h new file mode 100644 index 0000000..42cc420 --- /dev/null +++ b/Controller/OpenningScene.h @@ -0,0 +1,33 @@ +#ifndef OPENNING_SCENE_H_INCLUDED +#define OPENNING_SCENE_H_INCLUDED + +#include "scn.h" + +class OpeningScene { +public: + OpeningScene(); + int show(sf::RenderWindow *window, MyDraw *draw, double totalTime); + +private: + Label label; +}; + +OpeningScene::OpeningScene() : label(410 - 10, 460 - 10, 20, 20, "Hello, Master!", 100) {} + +/** + * Call on every step to show + * @param window sf::RenderWindow + * @param draw implementation of MyDraw + * @return the id of the next scene to show + */ +int OpeningScene::show(sf::RenderWindow *window, MyDraw *draw, double totalTime) { + draw->drawLabel(label, (int) (85.0 * totalTime)); + window->setMouseCursorVisible(false); + if (totalTime > 3) { + window->setMouseCursorVisible(true); + return scn::MENU; + } + return scn::OPENING; +} + +#endif // OPENNING_SCENE_H_INCLUDED diff --git a/Controller/scn.h b/Controller/scn.h new file mode 100644 index 0000000..eee51ae --- /dev/null +++ b/Controller/scn.h @@ -0,0 +1,8 @@ +#ifndef INC_2048BALLS_SCN_H +#define INC_2048BALLS_SCN_H + +enum scn { + OPENING, MENU, GAME, FINISH +}; + +#endif //INC_2048BALLS_SCN_H diff --git a/View/Button.h b/View/Button.h new file mode 100644 index 0000000..00dee56 --- /dev/null +++ b/View/Button.h @@ -0,0 +1,18 @@ +#ifndef BUTTON_H_INCLUDED +#define BUTTON_H_INCLUDED + +#include "Label.h" + +class Button : public Label { +public: + Button(int _x, int _y, int _l, int _h, std::string _st, int _siz) : Label(_x, _y, _l, _h, _st, _siz) {} + + bool is_in(int px, int py) { + bool ret = 0; + if ((px > x) && (px < x + l) && (py > y) && (py < y + h)) + ret = 1; + return ret; + } +}; + +#endif // BUTTON_H_INCLUDED diff --git a/View/Label.h b/View/Label.h new file mode 100644 index 0000000..812296d --- /dev/null +++ b/View/Label.h @@ -0,0 +1,23 @@ +#ifndef INC_2048BALLS_LABEL_H +#define INC_2048BALLS_LABEL_H + +#include + +class Label { +public: + int x, y; + int l, h; + int siz; + std::string st; + + Label(int _x, int _y, int _l, int _h, std::string _st, int _siz) { + x = _x; + y = _y; + l = _l; + h = _h; + st = _st; + siz = _siz; + } +}; + +#endif //INC_2048BALLS_LABEL_H diff --git a/View/MyDraw.h b/View/MyDraw.h new file mode 100644 index 0000000..81ca2bc --- /dev/null +++ b/View/MyDraw.h @@ -0,0 +1,95 @@ +#ifndef DRAW_H_INCLUDED +#define DRAW_H_INCLUDED + +#include "Button.h" +#include "Label.h" + + +class MyDraw { +public: + MyDraw(sf::RenderWindow *renderWindow); + virtual void drawBalls(const std::vector *balls); + virtual void drawLabel(Label label, int transparency); + virtual void drawButton(Button but, int px, int py); + +private: + sf::RenderWindow *window; + sf::Font rita; +}; + +MyDraw::MyDraw(sf::RenderWindow *renderWindow) { + window = renderWindow; + if (!rita.loadFromFile("rita.ttf")) { + std::cerr << "Error: failed to load font" << std::endl; + } +} + +void MyDraw::drawBalls(const std::vector *balls) { + sf::RectangleShape rectangle(sf::Vector2f(800, 800)); + rectangle.setPosition(10, 110); + rectangle.setFillColor(sf::Color(255, 255, 230)); + rectangle.setOutlineThickness(10); + rectangle.setOutlineColor(sf::Color(182, 92, 0)); + window->draw(rectangle); + + for (auto &ball : *balls) { + sf::CircleShape shape(ball.p); + shape.setPosition(sf::Vector2f(10 + ball.x - ball.p, 110 + ball.y - ball.p)); + shape.setFillColor(sf::Color(255, 220 - 10 * (ball.num - 4), + ((100 - 30 * (ball.num - 4)) > 0) ? (100 - 30 * (ball.num - 4)) : 0)); + window->draw(shape); + + sf::Text text; + + text.setFont(rita); + text.setString("" + std::to_string(ball.st)); + text.setPosition(sf::Vector2f(10 + ball.x + 0 * ball.p - text.getLocalBounds().width / 2, + 110 + ball.y + 0 * ball.p - 10 - text.getLocalBounds().height / 2)); + text.setFillColor(sf::Color(0, 0, 0)); + window->draw(text); + } +} + +void MyDraw::drawLabel(Label label, int transparency) { + sf::RectangleShape rectangle(sf::Vector2f(label.l, label.h)); + rectangle.setPosition(label.x, label.y); + rectangle.setFillColor(sf::Color(182, 92, 0)); + window->draw(rectangle); + + sf::Text text("", rita, label.siz); + + text.setFont(rita); + + text.setString(label.st); + text.setPosition(sf::Vector2f(label.x + label.l / 2 - text.getLocalBounds().width / 2 - label.siz / 15, + label.y + label.h / 2 - label.siz / 3.5 - text.getLocalBounds().height / 2)); + text.setFillColor(sf::Color(255, 255, 255, transparency)); + window->draw(text); +} + +void MyDraw::drawButton(Button but, int px, int py) { + sf::RectangleShape rectangle(sf::Vector2f(but.l, but.h)); + rectangle.setPosition(but.x, but.y); + if (but.is_in(px, py) == 0) { + rectangle.setFillColor(sf::Color(182, 92, 0)); + } else { + rectangle.setFillColor(sf::Color(255, 255, 255)); + } + window->draw(rectangle); + + sf::Text text("", rita, but.siz); + + text.setFont(rita); + + text.setString(but.st); + text.setPosition(sf::Vector2f(but.x + but.l / 2 - text.getLocalBounds().width / 2 - but.siz / 15, + but.y + but.h / 2 - but.siz / 3.5 - text.getLocalBounds().height / 2)); + if (but.is_in(px, py) == 0) { + text.setFillColor(sf::Color(255, 255, 255)); + } else { + text.setFillColor(sf::Color(182, 92, 0)); + } + window->draw(text); +} + +#endif // DRAW_H_INCLUDED diff --git a/ball_class.h b/ball_class.h deleted file mode 100644 index 5f98f0e..0000000 --- a/ball_class.h +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef BALL_CLASS_H_INCLUDED -#define BALL_CLASS_H_INCLUDED - - -class Ball -{ -private: -public: - float p; - float x, y, ux, uy; - int num; - int st; - bool del = 0; - - Ball(float _x,float _y, int _num) - { - x = _x; - y = _y; - ux = 0; - uy = 0; - num = _num; - st = 1; - for (int i = 0; i < num; i ++) - { - st*=2; - } - p = 60 + num*13; - } - - void app(float time) - { - x += ux*time; - y += uy*time; - - if (y > 800 - p) {uy *= -1; y = 800 - p;} - if (y < p) {uy *= -1; y = p;} - if (x < p) {ux *= -1; x = p;} - if (x > 800 - p) {ux *= -1; x = 800 - p;} - } - - void low2(float time, float fx, float fy) - { - ux += fx*time; - uy += fy*time; - } -}; - - - -#endif // BALL_CLASS_H_INCLUDED diff --git a/button.h b/button.h deleted file mode 100644 index 97443df..0000000 --- a/button.h +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef BUTTON_H_INCLUDED -#define BUTTON_H_INCLUDED - -class button_zero -{ -public: - int x, y; - int l, h; - int siz; - string st; -button_zero(int _x, int _y, int _l, int _h, string _st, int _siz) -{ - x = _x; - y = _y; - l = _l; - h = _h; - st = _st; - siz = _siz; -} -}; - -class button_active : public button_zero -{ -public: - button_active(int _x, int _y, int _l, int _h, string _st, int _siz) : button_zero(_x, _y, _l, _h, _st, _siz) - {} -bool is_in (int px, int py) -{ - bool ret = 0; - if ((px>x) && (pxy) && (py* balls) -{ - float x1, y1; - float x2, y2; - - RectangleShape rectangle(sf::Vector2f(800, 800)); - rectangle.setPosition(10,110); - rectangle.setFillColor(Color(255,255,230)); - rectangle.setOutlineThickness(10); - rectangle.setOutlineColor(sf::Color(182, 92, 0)); - window->draw(rectangle); - - for (int i = 0; i < balls->size(); i ++) - { - CircleShape shape((*balls)[i].p); - shape.setPosition(Vector2f(10 + (*balls)[i].x - (*balls)[i].p,110+(*balls)[i].y - (*balls)[i].p)); - shape.setFillColor(Color(255, 220 - 10*((*balls)[i].num - 4), ((100 - 30*((*balls)[i].num - 4))>0)?(100 - 30*((*balls)[i].num - 4)):0)); - window->draw(shape); - - Text chi; - Font rita; - - ostringstream playerScoreString; - playerScoreString << (*balls)[i].st; - rita.loadFromFile("rita.ttf"); - chi.setFont(rita); - //chi.setString("Boulat - Petooh"); - chi.setString("" + playerScoreString.str()); - chi.setPosition(Vector2f(10 + (*balls)[i].x + 0*(*balls)[i].p - chi.getLocalBounds().width/2,110 + (*balls)[i].y + 0*(*balls)[i].p - 10 - chi.getLocalBounds().height/2)); - chi.setFillColor(Color(0,0,0)); - window->draw(chi); - } -} - -void drawing_button(RenderWindow* window, button_zero but, int alfa) -{ - RectangleShape rectangle(sf::Vector2f(but.l, but.h)); - rectangle.setPosition(but.x,but.y); - rectangle.setFillColor(Color(182, 92, 0)); - window->draw(rectangle); - - Font rita; - Text chi("",rita,but.siz); - - rita.loadFromFile("rita.ttf"); - chi.setFont(rita); - //chi.setStyle(sf::Text::Bold | sf::Text::Regular); - - chi.setString(but.st); - chi.setPosition(Vector2f(but.x + but.l/2 - chi.getLocalBounds().width/2 - but.siz/15, but.y + but.h/2 - but.siz/3.5 - chi.getLocalBounds().height/2)); - chi.setFillColor(Color(255,255,255,alfa)); - window->draw(chi); -} - -void drawing_button(RenderWindow* window, button_active but, int px, int py) -{ - RectangleShape rectangle(sf::Vector2f(but.l, but.h)); - rectangle.setPosition(but.x,but.y); - if (but.is_in(px,py) == 0) - { - rectangle.setFillColor(Color(182, 92, 0)); - } - else - { - rectangle.setFillColor(Color(255, 255, 255)); - } - window->draw(rectangle); - - Font rita; - Text chi("",rita,but.siz); - - rita.loadFromFile("rita.ttf"); - chi.setFont(rita); - //chi.setStyle(sf::Text::Bold | sf::Text::Regular); - - chi.setString(but.st); - chi.setPosition(Vector2f(but.x + but.l/2 - chi.getLocalBounds().width/2 - but.siz/15, but.y + but.h/2 - but.siz/3.5 - chi.getLocalBounds().height/2)); - if (but.is_in(px,py) == 0) - { - chi.setFillColor(Color(255,255,255)); - } - else - { - chi.setFillColor(Color(182, 92, 0)); - } - window->draw(chi); -} - -#endif // DRAWING_H_INCLUDED diff --git a/egine.h b/egine.h deleted file mode 100644 index fc4deeb..0000000 --- a/egine.h +++ /dev/null @@ -1,169 +0,0 @@ -#ifndef EGINE_H_INCLUDED -#define EGINE_H_INCLUDED - -#include -#include -#include -#include -#include - -using namespace sf; -using namespace std; - -#include "ball_class.h" - -int lose = 0; - -void app_phys(vector* balls, float GG, float G, float time) -{ - float s1,s2; - for(int k = 0; k < 3; k ++) - { - for (int i = 0; i < balls->size(); i ++) - { - (*balls)[i].app(time); - (*balls)[i].low2(time, GG - ((*balls)[i].ux)/3, G - ((*balls)[i].uy)/3); - } - for (int i = 0; i < balls->size(); i ++) - for (int j = 0; j < balls->size(); j ++) - { - if (i != j) - { - s1 = (((*balls)[i].x - (*balls)[j].x)*((*balls)[i].x - (*balls)[j].x) + ((*balls)[i].y - (*balls)[j].y)*((*balls)[i].y - (*balls)[j].y)); - s2 = ((*balls)[i].p + (*balls)[j].p)*((*balls)[i].p + (*balls)[j].p); - if (s1 < s2) - { - (*balls)[i].low2(time, (s2 - s1)*((*balls)[i].x - (*balls)[j].x)/5e3, (s2 - s1)*((*balls)[i].y - (*balls)[j].y)/5e3); - } - } - } - } -} - -void analise_map(vector* balls) - { - float s1,s2; - float xnew, ynew, ne = 0, stnew; - for (int i = 0; i < (*balls).size(); i ++) - for (int j = 0; j < (*balls).size(); j ++) - { - if (i != j) - { - s1 = (((*balls)[i].x - (*balls)[j].x)*((*balls)[i].x - (*balls)[j].x) + ((*balls)[i].y - (*balls)[j].y)*((*balls)[i].y - (*balls)[j].y)); - s2 = ((*balls)[i].p + (*balls)[j].p)*((*balls)[i].p + (*balls)[j].p); - if ((s1 < s2) && ((*balls)[i].st == (*balls)[j].st)) - { - (*balls)[i].del = 1; - (*balls)[j].del = 1; - xnew = ((*balls)[i].x + (*balls)[j].x)/2; - ynew = ((*balls)[i].y + (*balls)[j].y)/2; - stnew = (*balls)[i].num + 1; - ne = 1; - } - } - } - - for (int i = 0; i < (*balls).size(); i ++) - { - if ((*balls)[i].del == 1) - { - (*balls).erase((*balls).begin() + i); - i = (*balls).size() + 1; - } - } - - for (int i = 0; i < (*balls).size(); i ++) - { - if ((*balls)[i].del == 1) - { - (*balls).erase((*balls).begin() + i); - i = (*balls).size() + 1; - } - } - - if (ne == 1) - { - (*balls).push_back(Ball(xnew,ynew, stnew)); - } - } - -class vect -{ -public: - int x, y; - vect(int X, int Y) - { - x = X; - y = Y; - } -}; - -void smart_push_ball(vector* balls) -{ - int ran; - int n1, d1, n2, d2; - n1 = 73; d1 = 10; - n2 = 73; d2 = 10; - - vector vects; - - - float s1,s2; - int xp = 0, yp = 0; - for (int i = n1; i < 800- n1; i += d1) - for (int j = n2; j < 800 - n2; j += d2) - { - xp = 0; - for (int k = 0; k < (*balls).size(); k ++) - { - s1 = ((*balls)[k].x - i)*((*balls)[k].x - i) + ((*balls)[k].y - j)*((*balls)[k].y - j); - s2 = ((*balls)[k].p + 70)*((*balls)[k].p + 70); - if (s2 > s1) xp = - 1; - } - if (xp == 0) - { - vects.push_back(vect(i,j)); - } - } - if (vects.size() != 0) - { - ran = rand()%vects.size(); - (*balls).push_back(Ball(vects[ran].x,vects[ran].y,rand()%2 + 1)); - } - else - { - lose = 1; - } -} - -void create_first_balls(vector* balls) -{ - balls->clear(); - for (int i = 1; i < 6; i ++) - { - balls->push_back(Ball(rand()%600 + 100,rand()%600 + 100,i)); - } -} - -int get_lose() -{ - return lose; -} - -void set_lose() -{ - lose = 0; -} - -int score(vector* balls) -{ - int ret = 0; - for (int i = 0; i < (*balls).size(); i ++) - { - ret += (*balls)[i].st; - } - return ret; -} - - -#endif // EGINE_H_INCLUDED diff --git a/game_scene.h b/game_scene.h deleted file mode 100644 index aba84f0..0000000 --- a/game_scene.h +++ /dev/null @@ -1,100 +0,0 @@ -#ifndef GAME_SCENE_H_INCLUDED -#define GAME_SCENE_H_INCLUDED - -#include "change_scene.h" - -using namespace sf; -using namespace std; - -vector balls; -float G = -10; -float GG = -10; -bool push_ball = 0; - -void game_start() -{ - set_lose(); - create_first_balls(&balls); - push_ball = 0; -} - - -void still_game(RenderWindow* window, float time) -{ - if (get_lose() == 0) - { - app_phys(&balls,GG,G,time); - analise_map(&balls); - if (push_ball == 1) - { - smart_push_ball(&balls); - push_ball = 0; - } - } - ostringstream playerScoreString; - playerScoreString << (score(&balls) - 62); - drawing_balls(window, &balls); - drawing_button(window, button_zero(10,10,220,90,"2048", 92),255); - drawing_button(window, button_zero(330,10,220,45,"Score:", 50),255); - drawing_button(window, button_zero(550,10,220,45,playerScoreString.str(), 50),255); - if (get_lose() == 0) - { - //drawing_button(window, button_zero(385,60,220,45,"doing swell", 50),255); - Vector2i pixelPos = Mouse::getPosition(*window); - Vector2f pos = window->mapPixelToCoords(pixelPos); - drawing_button(window, button_active(385,60,220,45,"doing swell", 50),255); - } - else - { - drawing_button(window, button_zero(385,60,220,45,"ooh, fail!", 50),255); - } - - - sf::Event event; - while (window->pollEvent(event)) - { - if (event.type == sf::Event::Closed) window->close(); - if (event.type == sf::Event::KeyPressed) - { - if (event.key.code == sf::Keyboard::Escape) - { - //window->close(); - change_scene(2); - } - if (event.key.code == sf::Keyboard::W) - { - G = -10; - GG = 0; - push_ball = 1; - } - if (event.key.code == sf::Keyboard::S) - { - G = 10; - GG = 0; - push_ball = 1; - } - if (event.key.code == sf::Keyboard::D) - { - G = 0; - GG = 10; - push_ball = 1; - } - if (event.key.code == sf::Keyboard::A) - { - G = 0; - GG = -10; - push_ball = 1; - } - - } - if (event.type == Event::MouseButtonPressed)//если нажата клавиша мыши - if (event.key.code == Mouse::Left)//а именно левая - { - //game_start(); - //change_scene(0); - } - } - window->setMouseCursorVisible(1); -} - -#endif // GAME_SCENE_H_INCLUDED diff --git a/main.cpp b/main.cpp index 95f9710..8849b1f 100644 --- a/main.cpp +++ b/main.cpp @@ -1,48 +1,15 @@ -#include -#include -#include -#include - -#include "egine.h" -#include "drawing.h" -#include "game_scene.h" -#include "openning_scene.h" -#include "change_scene.h" -#include "menu_scene.h" - -using namespace sf; -using namespace std; - -int main() -{ - - change_scene(0); - - RenderWindow window(sf::VideoMode(820, 920),"2048 - Balls", Style::None ); - - Clock clock; - - float all_time = 0; - - while (window.isOpen()) - { - window.clear(Color(182, 92, 0)); - - double time = clock.getElapsedTime().asMicroseconds(); - clock.restart(); - all_time += time/1e6; - time = time/1.8e5*0.6; - time = (time > 0.5)?0.5:time; - cout<mapPixelToCoords(pixelPos); - drawing_button(window, button_active(410-200,390-70,400,140,"START", 100), pos.x, pos.y); - drawing_button(window, button_active(410-200,530-70,400,140,"EXIT", 100), pos.x, pos.y); - - sf::Event event; - while (window->pollEvent(event)) - { - if (event.type == sf::Event::Closed) window->close(); - if (event.type == Event::MouseButtonPressed)//если нажата клавиша мыши - if (event.key.code == Mouse::Left)//а именно левая - { - if (button_active(410-200,390-70,400,140,"START", 100).is_in(pos.x, pos.y)) - { - //window->close(); - game_start(); - change_scene(1); - } - if (button_active(410-200,530-70,400,140,"START", 100).is_in(pos.x, pos.y)) - { - window->close(); - } - } - } - window->setMouseCursorVisible(1); -} - -#endif // MENU_SCENE_H_INCLUDED diff --git a/model/Ball.h b/model/Ball.h new file mode 100644 index 0000000..d68f437 --- /dev/null +++ b/model/Ball.h @@ -0,0 +1,56 @@ +#ifndef BALL_CLASS_H_INCLUDED +#define BALL_CLASS_H_INCLUDED + + +class Ball { +private: +public: + double p; + double x, y, ux, uy; + int num; + int st; + bool del = false; + + Ball(double _x, double _y, int _num) { + x = _x; + y = _y; + ux = 0; + uy = 0; + num = _num; + st = 1; + for (int i = 0; i < num; i++) { + st *= 2; + } + p = 60 + num * 13; + } + + void app(double time) { + x += ux * time; + y += uy * time; + + if (y > 800 - p) { + uy *= -1; + y = 800 - p; + } + if (y < p) { + uy *= -1; + y = p; + } + if (x < p) { + ux *= -1; + x = p; + } + if (x > 800 - p) { + ux *= -1; + x = 800 - p; + } + } + + void low2(double time, double fx, double fy) { + ux += fx * time; + uy += fy * time; + } +}; + + +#endif // BALL_CLASS_H_INCLUDED diff --git a/model/Engine.h b/model/Engine.h new file mode 100644 index 0000000..1502623 --- /dev/null +++ b/model/Engine.h @@ -0,0 +1,165 @@ +#ifndef EGINE_H_INCLUDED +#define EGINE_H_INCLUDED + +#include +#include +#include +#include +#include + +#include "Ball.h" +#include "Vec2d.h" +#include "MyRandom.h" + +class Engine { +public: + Engine(); + void step(double time); + void analiseMap(); + void smartPushBall(); + void initMap(); + bool getLose(); + void setLose(bool lose); + void setGravity(Vec2d g); + int score(); + const std::vector *getBalls(); +private: + MyRandom random; + std::vector balls; + Vec2d gravity; + bool lose = false; + const int ITERATIONS = 3; + const double K = 5e3; +}; + +Engine::Engine() : gravity(0, 10) {} + +void Engine::step(double time) { + double s1, s2; + for (int k = 0; k < ITERATIONS; k++) { + for (auto &ball : balls) { + ball.app(time); + ball.low2(time, gravity.x - (ball.ux) / ITERATIONS, gravity.y - (ball.uy) / ITERATIONS); + } + for (int i = 0; i < balls.size(); i++) + for (int j = 0; j < balls.size(); j++) { + if (i != j) { + s1 = ((balls[i].x - balls[j].x) * (balls[i].x - balls[j].x) + + (balls[i].y - balls[j].y) * (balls[i].y - balls[j].y)); + s2 = (balls[i].p + balls[j].p) * (balls[i].p + balls[j].p); + if (s1 < s2) { + balls[i].low2(time, (s2 - s1) * (balls[i].x - balls[j].x) / K, + (s2 - s1) * (balls[i].y - balls[j].y) / K); + } + } + } + } +} + +void Engine::analiseMap() { + double s1, s2; + double xnew = 0.0, ynew = 0.0, ne = 0.0; + int stnew = 0; + + for (int i = 0; i < balls.size(); i++) + for (int j = 0; j < balls.size(); j++) { + if (i != j) { + s1 = (balls[i].x - balls[j].x) * (balls[i].x - balls[j].x) + + (balls[i].y - balls[j].y) * (balls[i].y - balls[j].y); + s2 = (balls[i].p + balls[j].p) * (balls[i].p + balls[j].p); + if ((s1 < s2) && (balls[i].st == balls[j].st)) { + balls[i].del = true; + balls[j].del = true; + xnew = (balls[i].x + balls[j].x) / 2; + ynew = (balls[i].y + balls[j].y) / 2; + stnew = balls[i].num + 1; + ne = 1; + } + } + } + + for (unsigned long i = 0; i < balls.size(); i++) { + if (balls[i].del == 1) { + balls.erase(balls.begin() + i); + i = balls.size() + 1; + } + } + + for (unsigned long i = 0; i < balls.size(); i++) { + if (balls[i].del == 1) { + balls.erase(balls.begin() + i); + i = balls.size() + 1; + } + } + + if (ne == 1) { + balls.emplace_back(xnew, ynew, stnew); + } +} + +void Engine::smartPushBall() { + int ran; + int n1, d1, n2, d2; + n1 = 73; + d1 = 10; + n2 = 73; + d2 = 10; + + std::vector> vects; + + double s1, s2; + int xp = 0; + for (int i = n1; i < 800 - n1; i += d1) + for (int j = n2; j < 800 - n2; j += d2) { + xp = 0; + for (auto &ball : balls) { + s1 = (ball.x - i) * (ball.x - i) + (ball.y - j) * (ball.y - j); + s2 = (ball.p + 70) * (ball.p + 70); + if (s2 > s1) + xp = - 1; + } + if (xp == 0) { + vects.emplace_back(i, j); + } + } + if (!vects.empty()) { + ran = random.iRandom(0, static_cast(vects.size())); + balls.emplace_back(vects[ran].x, vects[ran].y, random.iRandom(1, 2)); + } else { + lose = true; + } +} + +void Engine::initMap() { + balls.clear(); + for (int i = 1; i < 6; i++) { + smartPushBall(); + } +} + +bool Engine::getLose() { + return lose; +} + +void Engine::setLose(bool lose) { + this->lose = lose; +} + +int Engine::score() { + int ret = 0; + for (auto &i : balls) { + ret += i.st; + } + return ret; +} + +void Engine::setGravity(Vec2d g) { + this->gravity = g; +} + +const std::vector *Engine::getBalls() { + return &balls; +} + + +#endif // EGINE_H_INCLUDED diff --git a/model/MyRandom.h b/model/MyRandom.h new file mode 100644 index 0000000..0d51f21 --- /dev/null +++ b/model/MyRandom.h @@ -0,0 +1,22 @@ +#ifndef INC_2048BALLS_MYRANDOM_H +#define INC_2048BALLS_MYRANDOM_H + +#include +#include + +class MyRandom { +public: + float rRandom(float left, float right) { + std::uniform_real_distribution urd(left, right); + return urd(rd); + } + + int iRandom(int left, int right) { + std::uniform_int_distribution urd(left, right); + return urd(rd); + } +private: + std::random_device rd; +}; + +#endif //INC_2048BALLS_MYRANDOM_H diff --git a/model/Vec2d.h b/model/Vec2d.h new file mode 100644 index 0000000..43fa23b --- /dev/null +++ b/model/Vec2d.h @@ -0,0 +1,15 @@ +#ifndef INC_2048BALLS_VEC2D_H +#define INC_2048BALLS_VEC2D_H + +template +class Vec2d { +public: + T x, y; + + Vec2d(T x, T y) { + this->x = x; + this->y = y; + } +}; + +#endif //INC_2048BALLS_VEC2D_H diff --git a/openning_scene.h b/openning_scene.h deleted file mode 100644 index dca7ada..0000000 --- a/openning_scene.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef OPENNING_SCENE_H_INCLUDED -#define OPENNING_SCENE_H_INCLUDED - -#include "change_scene.h" - - -void still_oppening(RenderWindow* window, float time, float all_time) -{ - drawing_button(window, button_zero(410-10,460-10,20,20,"Hello, Master!", 100), (int)(85.0*all_time)); - window->setMouseCursorVisible(0); - if (all_time > 3) change_scene(2); -} - - -#endif // OPENNING_SCENE_H_INCLUDED