Compare commits
11 Commits
xmake
...
92b58c4b98
| Author | SHA1 | Date | |
|---|---|---|---|
| 92b58c4b98 | |||
| 8635d4b853 | |||
| 9780a36af4 | |||
| 6b16abda6a | |||
| 30dd323e22 | |||
| d87ddcdc22 | |||
| 8aaced68d0 | |||
| be6c8d9f77 | |||
| d9ccecfdd8 | |||
| 02bab6ed87 | |||
| 0e17996c35 |
2
.vscode/c_cpp_properties.json
vendored
2
.vscode/c_cpp_properties.json
vendored
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"configurations": [
|
"configurations": [
|
||||||
{
|
{
|
||||||
"name": "JMinos",
|
"name": "jminos",
|
||||||
"cppStandard": "c++20",
|
"cppStandard": "c++20",
|
||||||
"compileCommands": ".vscode/compile_commands.json"
|
"compileCommands": ".vscode/compile_commands.json"
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
data/config/keybinds/layout0.bin
Normal file
BIN
data/config/keybinds/layout0.bin
Normal file
Binary file not shown.
BIN
data/config/keybinds/layout1.bin
Normal file
BIN
data/config/keybinds/layout1.bin
Normal file
Binary file not shown.
BIN
data/config/keybinds/layout2.bin
Normal file
BIN
data/config/keybinds/layout2.bin
Normal file
Binary file not shown.
BIN
data/config/keybinds/layout3.bin
Normal file
BIN
data/config/keybinds/layout3.bin
Normal file
Binary file not shown.
BIN
data/config/keybinds/layout4.bin
Normal file
BIN
data/config/keybinds/layout4.bin
Normal file
Binary file not shown.
Binary file not shown.
@@ -38,7 +38,7 @@ _Repeat for every avaible actions._
|
|||||||
The settings file has the following format:
|
The settings file has the following format:
|
||||||
|
|
||||||
- The number of the chosen keybinds (from 0 to 4), stored with 1 byte
|
- The number of the chosen keybinds (from 0 to 4), stored with 1 byte
|
||||||
- The size multiplier of the window, stored with 1 byte
|
- The window size mode, stored with 1 byte
|
||||||
- The number of the last selected gamemode (converted from an Enum), stored with 1 byte
|
- The number of the last selected gamemode (converted from an Enum), stored with 1 byte
|
||||||
- The last selected width of the board, stored with 1 byte
|
- The last selected width of the board, stored with 1 byte
|
||||||
- The last selected height of the board, stored with 1 byte
|
- The last selected height of the board, stored with 1 byte
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ We will only talk about pieces and not polyominoes. In this project, pieces are
|
|||||||
|
|
||||||
Each frame, the UI will translate the user's input into a series of action to apply to the game. The list of action is the following:
|
Each frame, the UI will translate the user's input into a series of action to apply to the game. The list of action is the following:
|
||||||
|
|
||||||
- Quit the game
|
|
||||||
- Pause
|
- Pause
|
||||||
- Retry
|
- Retry
|
||||||
- Hold
|
- Hold
|
||||||
|
|||||||
@@ -4,10 +4,9 @@
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The list of actions that can be taken by the player
|
* The list of in-game actions that can be taken by the player
|
||||||
*/
|
*/
|
||||||
enum Action {
|
enum Action {
|
||||||
QUIT,
|
|
||||||
PAUSE,
|
PAUSE,
|
||||||
RETRY,
|
RETRY,
|
||||||
HOLD,
|
HOLD,
|
||||||
@@ -22,8 +21,20 @@ enum Action {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static const std::string ACTION_NAMES[] = { // name for each action
|
static const Action ACTION_LIST_IN_ORDER[] = { // the list of possible actions in a sorted order
|
||||||
"Quit",
|
MOVE_LEFT,
|
||||||
|
MOVE_RIGHT,
|
||||||
|
SOFT_DROP,
|
||||||
|
HARD_DROP,
|
||||||
|
ROTATE_CW,
|
||||||
|
ROTATE_CCW,
|
||||||
|
ROTATE_180,
|
||||||
|
ROTATE_0,
|
||||||
|
HOLD,
|
||||||
|
PAUSE,
|
||||||
|
RETRY
|
||||||
|
};
|
||||||
|
static const std::string ACTION_NAMES[] = { // name representation for each actions
|
||||||
"Pause",
|
"Pause",
|
||||||
"Retry",
|
"Retry",
|
||||||
"Hold",
|
"Hold",
|
||||||
|
|||||||
@@ -6,6 +6,9 @@
|
|||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
static const int DEFAULT_BOARD_WIDTH = 10; // the default width of the board when starting the menu
|
||||||
|
static const int DEFAULT_BOARD_HEIGHT = 20; // the default height of the board when starting the menu
|
||||||
|
|
||||||
|
|
||||||
Menu::Menu() {
|
Menu::Menu() {
|
||||||
this->piecesList = std::make_shared<PiecesList>(PiecesList());
|
this->piecesList = std::make_shared<PiecesList>(PiecesList());
|
||||||
|
|||||||
@@ -5,8 +5,6 @@
|
|||||||
#include "Game.h"
|
#include "Game.h"
|
||||||
|
|
||||||
static const int FRAMES_PER_SECOND = 60; // the number of frames per second, all the values in the app were choosen with this number in mind
|
static const int FRAMES_PER_SECOND = 60; // the number of frames per second, all the values in the app were choosen with this number in mind
|
||||||
static const int DEFAULT_BOARD_WIDTH = 10; // the default width of the board when starting the menu
|
|
||||||
static const int DEFAULT_BOARD_HEIGHT = 20; // the default height of the board when starting the menu
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,20 +1,27 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Settings.h"
|
#include "../Settings.h"
|
||||||
|
|
||||||
#include <stack>
|
#include <stack>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <SFML/Graphics.hpp>
|
#include <SFML/Graphics.hpp>
|
||||||
|
|
||||||
|
class AppMenu;
|
||||||
|
using MenuStack = std::stack<std::shared_ptr<AppMenu>>;
|
||||||
|
|
||||||
|
|
||||||
class AppMenu {
|
class AppMenu {
|
||||||
protected:
|
protected:
|
||||||
std::shared_ptr<std::stack<AppMenu>> menuStack;
|
std::shared_ptr<MenuStack> menuStack;
|
||||||
std::shared_ptr<Settings> settings;
|
std::shared_ptr<Settings> settings;
|
||||||
std::shared_ptr<sf::RenderWindow> renderWindow;
|
std::shared_ptr<sf::RenderWindow> renderWindow;
|
||||||
|
bool enterPressed = false;
|
||||||
|
bool enterReleased = false;
|
||||||
|
bool escPressed = false;
|
||||||
|
bool escReleased = false;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AppMenu(std::shared_ptr<std::stack<AppMenu>> menuStack, std::shared_ptr<Settings> settings, std::shared_ptr<sf::RenderWindow> renderWindow) :
|
AppMenu(std::shared_ptr<MenuStack> menuStack, std::shared_ptr<Settings> settings, std::shared_ptr<sf::RenderWindow> renderWindow) :
|
||||||
menuStack(menuStack),
|
menuStack(menuStack),
|
||||||
settings(settings),
|
settings(settings),
|
||||||
renderWindow(renderWindow)
|
renderWindow(renderWindow)
|
||||||
@@ -22,6 +29,26 @@ class AppMenu {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void updateMetaBinds() {
|
||||||
|
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::Enter)) {
|
||||||
|
enterPressed = true;
|
||||||
|
enterReleased = false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
enterReleased = enterPressed;
|
||||||
|
enterPressed = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::Escape)) {
|
||||||
|
escPressed = true;
|
||||||
|
escReleased = false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
escReleased = escPressed;
|
||||||
|
escPressed = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
virtual void computeFrame() = 0;
|
virtual void computeFrame() = 0;
|
||||||
|
|
||||||
virtual void drawFrame() const = 0;
|
virtual void drawFrame() const = 0;
|
||||||
|
|||||||
103
src/GraphicalUI/AppMenus/InGameAppMenu.cpp
Normal file
103
src/GraphicalUI/AppMenus/InGameAppMenu.cpp
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
#include "InGameAppMenu.h"
|
||||||
|
|
||||||
|
#include "AppMenu.h"
|
||||||
|
|
||||||
|
#include <stack>
|
||||||
|
#include <memory>
|
||||||
|
#include <SFML/Graphics.hpp>
|
||||||
|
|
||||||
|
|
||||||
|
InGameAppMenu::InGameAppMenu(std::shared_ptr<MenuStack> menuStack, std::shared_ptr<Settings> settings, std::shared_ptr<sf::RenderWindow> renderWindow) :
|
||||||
|
AppMenu(menuStack, settings, renderWindow),
|
||||||
|
game(this->settings->getMenu().startGame(this->settings->getGamemode()))
|
||||||
|
{
|
||||||
|
|
||||||
|
this->game.start();
|
||||||
|
this->paused = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void InGameAppMenu::computeFrame() {
|
||||||
|
this->updateMetaBinds();
|
||||||
|
|
||||||
|
if (this->escReleased) {
|
||||||
|
this->menuStack->pop();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
std::set<Action> actions;
|
||||||
|
for (Action action : ACTION_LIST_IN_ORDER) {
|
||||||
|
for (sfKey key : this->settings->getKeybinds().getKeybinds(action)) {
|
||||||
|
if (sf::Keyboard::isKeyPressed(key)) {
|
||||||
|
actions.insert(action);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (actions.contains(RETRY)) {
|
||||||
|
this->game.reset();
|
||||||
|
this->game.start();
|
||||||
|
}
|
||||||
|
if (actions.contains(PAUSE)) {
|
||||||
|
this->paused = (!this->paused);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!paused) {
|
||||||
|
this->game.nextFrame(actions);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void InGameAppMenu::drawFrame() const {
|
||||||
|
this->renderWindow->clear(sf::Color::Black);
|
||||||
|
|
||||||
|
int sizeMultiplier = this->settings->getWindowSizeMultiplier();
|
||||||
|
sf::Vector2f cellSize((float) sizeMultiplier, (float) sizeMultiplier);
|
||||||
|
|
||||||
|
for (int y = this->game.getBoard().getBaseHeight() + 10; y >= 0; y--) {
|
||||||
|
for (int x = 0; x < this->game.getBoard().getWidth(); x++) {
|
||||||
|
bool isActivePieceHere = (this->game.getActivePiece() != nullptr) && (this->game.getActivePiece()->getPositions().contains(Position{x, y} - this->game.getActivePiecePosition()));
|
||||||
|
bool isGhostPieceHere = (this->game.getActivePiece() != nullptr) && (this->game.getActivePiece()->getPositions().contains(Position{x, y} - this->game.ghostPiecePosition()));
|
||||||
|
Block block = (isActivePieceHere || isGhostPieceHere) ? this->game.getActivePiece()->getBlockType() : this->game.getBoard().getBlock(Position{x, y});
|
||||||
|
|
||||||
|
sf::RectangleShape cell(cellSize);
|
||||||
|
cell.setFillColor(sf::Color(BLOCKS_COLOR[block].red, BLOCKS_COLOR[block].green, BLOCKS_COLOR[block].blue, (isGhostPieceHere && !isActivePieceHere) ? 150 : 255));
|
||||||
|
cell.setPosition(sf::Vector2f(x * sizeMultiplier, (this->game.getBoard().getBaseHeight() + 10 - y) * sizeMultiplier));
|
||||||
|
this->renderWindow->draw(cell);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->game.getNextPieces().size() > 0) {
|
||||||
|
for (int y = 10; y >= 0; y--) {
|
||||||
|
for (int x = 0; x <= 10; x++) {
|
||||||
|
Block block = this->game.getNextPieces().at(0).getBlockType();
|
||||||
|
sf::RectangleShape cell(sf::Vector2f(20.f, 20.f));
|
||||||
|
cell.setPosition(sf::Vector2f((x + 2 + this->game.getBoard().getWidth())*20, (this->game.getBoard().getBaseHeight() - y)*20));
|
||||||
|
if (this->game.getNextPieces().at(0).getPositions().contains(Position({x, y}))) {
|
||||||
|
cell.setFillColor(sf::Color(BLOCKS_COLOR[block].red, BLOCKS_COLOR[block].green, BLOCKS_COLOR[block].blue));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
cell.setFillColor(sf::Color(0, 0, 0));
|
||||||
|
}
|
||||||
|
this->renderWindow->draw(cell);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->game.getHeldPiece() != nullptr) {
|
||||||
|
for (int y = 10; y >= 0; y--) {
|
||||||
|
for (int x = 0; x <= 10; x++) {
|
||||||
|
Block block = this->game.getHeldPiece()->getBlockType();
|
||||||
|
sf::RectangleShape cell(sf::Vector2f(20.f, 20.f));
|
||||||
|
cell.setPosition(sf::Vector2f((x + 12 + this->game.getBoard().getWidth())*20, (this->game.getBoard().getBaseHeight() - y)*20));
|
||||||
|
if (this->game.getHeldPiece()->getPositions().contains(Position({x, y}))) {
|
||||||
|
cell.setFillColor(sf::Color(BLOCKS_COLOR[block].red, BLOCKS_COLOR[block].green, BLOCKS_COLOR[block].blue));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
cell.setFillColor(sf::Color(0, 0, 0));
|
||||||
|
}
|
||||||
|
this->renderWindow->draw(cell);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this->renderWindow->display();
|
||||||
|
}
|
||||||
21
src/GraphicalUI/AppMenus/InGameAppMenu.h
Normal file
21
src/GraphicalUI/AppMenus/InGameAppMenu.h
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "AppMenu.h"
|
||||||
|
|
||||||
|
#include <stack>
|
||||||
|
#include <memory>
|
||||||
|
#include <SFML/Graphics.hpp>
|
||||||
|
|
||||||
|
|
||||||
|
class InGameAppMenu : public AppMenu {
|
||||||
|
private:
|
||||||
|
Game game;
|
||||||
|
bool paused;
|
||||||
|
|
||||||
|
public:
|
||||||
|
InGameAppMenu(std::shared_ptr<MenuStack> menuStack, std::shared_ptr<Settings> settings, std::shared_ptr<sf::RenderWindow> renderWindow);
|
||||||
|
|
||||||
|
void computeFrame();
|
||||||
|
|
||||||
|
void drawFrame() const;
|
||||||
|
};
|
||||||
@@ -1,21 +1,31 @@
|
|||||||
#include "MainAppMenu.h"
|
#include "MainAppMenu.h"
|
||||||
|
|
||||||
#include "AppMenu.h"
|
#include "AppMenu.h"
|
||||||
|
#include "InGameAppMenu.h"
|
||||||
|
|
||||||
#include <stack>
|
#include <stack>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <SFML/Graphics.hpp>
|
#include <SFML/Graphics.hpp>
|
||||||
|
|
||||||
|
|
||||||
MainAppMenu::MainAppMenu(std::shared_ptr<std::stack<AppMenu>> menuStack, std::shared_ptr<Settings> settings, std::shared_ptr<sf::RenderWindow> renderWindow) :
|
MainAppMenu::MainAppMenu(std::shared_ptr<MenuStack> menuStack, std::shared_ptr<Settings> settings, std::shared_ptr<sf::RenderWindow> renderWindow) :
|
||||||
AppMenu(menuStack, settings, renderWindow) {
|
AppMenu(menuStack, settings, renderWindow) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainAppMenu::computeFrame() {
|
void MainAppMenu::computeFrame() {
|
||||||
|
this->updateMetaBinds();
|
||||||
|
|
||||||
|
if (this->enterReleased) {
|
||||||
|
this->menuStack->push(std::make_shared<InGameAppMenu>(this->menuStack, this->settings, this->renderWindow));
|
||||||
|
}
|
||||||
|
if (this->escReleased) {
|
||||||
|
this->menuStack->pop();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainAppMenu::drawFrame() const {
|
void MainAppMenu::drawFrame() const {
|
||||||
|
this->renderWindow->clear(sf::Color::Black);
|
||||||
|
|
||||||
|
this->renderWindow->display();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
class MainAppMenu : public AppMenu {
|
class MainAppMenu : public AppMenu {
|
||||||
public:
|
public:
|
||||||
MainAppMenu(std::shared_ptr<std::stack<AppMenu>> menuStack, std::shared_ptr<Settings> settings, std::shared_ptr<sf::RenderWindow> renderWindow);
|
MainAppMenu(std::shared_ptr<MenuStack> menuStack, std::shared_ptr<Settings> settings, std::shared_ptr<sf::RenderWindow> renderWindow);
|
||||||
|
|
||||||
void computeFrame();
|
void computeFrame();
|
||||||
|
|
||||||
|
|||||||
@@ -8,24 +8,24 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <SFML/Graphics.hpp>
|
#include <SFML/Graphics.hpp>
|
||||||
|
|
||||||
static const double TIME_BETWEEN_FRAMES = (1000.f / 60.f);
|
static const double TIME_BETWEEN_FRAMES = (1000.f / FRAMES_PER_SECOND);
|
||||||
|
|
||||||
|
|
||||||
GraphApp::GraphApp() {
|
GraphApp::GraphApp() {
|
||||||
this->settings = std::make_shared<Settings>();
|
this->settings = std::make_shared<Settings>();
|
||||||
this->menuStack = std::make_shared<std::stack<AppMenu>>();
|
this->menuStack = std::make_shared<MenuStack>();
|
||||||
this->window = std::make_shared<sf::RenderWindow>();
|
this->renderWindow = std::make_shared<sf::RenderWindow>();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GraphApp::startApp() {
|
void GraphApp::run() {
|
||||||
changeVideoMode(*this->window, this->settings->getVideoMode());
|
changeVideoMode(*this->renderWindow, this->settings->getVideoMode());
|
||||||
this->menuStack->push(MainAppMenu(this->menuStack, this->settings, this->window));
|
this->menuStack->push(std::make_shared<MainAppMenu>(this->menuStack, this->settings, this->renderWindow));
|
||||||
|
|
||||||
bool quit = false;
|
bool quit = false;
|
||||||
double timeAtNextFrame = 0;
|
double timeAtNextFrame = 0;
|
||||||
sf::Clock clock;
|
sf::Clock clock;
|
||||||
while (!quit) {
|
while (!quit) {
|
||||||
while (const std::optional event = this->window->pollEvent()) {
|
while (const std::optional event = this->renderWindow->pollEvent()) {
|
||||||
if (event->is<sf::Event::Closed>()) {
|
if (event->is<sf::Event::Closed>()) {
|
||||||
quit = true;
|
quit = true;
|
||||||
}
|
}
|
||||||
@@ -33,17 +33,20 @@ void GraphApp::startApp() {
|
|||||||
|
|
||||||
if (!quit) {
|
if (!quit) {
|
||||||
if (clock.getElapsedTime().asMilliseconds() > timeAtNextFrame) {
|
if (clock.getElapsedTime().asMilliseconds() > timeAtNextFrame) {
|
||||||
timeAtNextFrame += TIME_BETWEEN_FRAMES;
|
this->menuStack->top()->computeFrame();
|
||||||
this->menuStack->top().computeFrame();
|
|
||||||
|
|
||||||
if (this->menuStack->empty()) {
|
if (this->menuStack->empty()) {
|
||||||
quit = true;
|
quit = true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this->menuStack->top().drawFrame();
|
this->menuStack->top()->drawFrame();
|
||||||
|
}
|
||||||
|
|
||||||
|
while (clock.getElapsedTime().asMilliseconds() > timeAtNextFrame) {
|
||||||
|
timeAtNextFrame += TIME_BETWEEN_FRAMES;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
window->close();
|
renderWindow->close();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,11 +11,11 @@
|
|||||||
class GraphApp {
|
class GraphApp {
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<Settings> settings;
|
std::shared_ptr<Settings> settings;
|
||||||
std::shared_ptr<std::stack<AppMenu>> menuStack;
|
std::shared_ptr<MenuStack> menuStack;
|
||||||
std::shared_ptr<sf::RenderWindow> window;
|
std::shared_ptr<sf::RenderWindow> renderWindow;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GraphApp();
|
GraphApp();
|
||||||
|
|
||||||
void startApp();
|
void run();
|
||||||
};
|
};
|
||||||
|
|||||||
86
src/GraphicalUI/Keybinds.cpp
Normal file
86
src/GraphicalUI/Keybinds.cpp
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
#include "Keybinds.h"
|
||||||
|
|
||||||
|
#include "../Core/Action.h"
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <set>
|
||||||
|
#include <fstream>
|
||||||
|
#include <SFML/Graphics.hpp>
|
||||||
|
|
||||||
|
|
||||||
|
Keybinds::Keybinds(int layoutNumber) :
|
||||||
|
layoutNumber(layoutNumber) {
|
||||||
|
|
||||||
|
for (Action action : ACTION_LIST_IN_ORDER) {
|
||||||
|
this->keybinds.insert({action, std::set<sfKey>()});
|
||||||
|
}
|
||||||
|
|
||||||
|
this->loadKeybindsFromFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Keybinds::loadKeybindsFromFile() {
|
||||||
|
std::ifstream layoutFile("data/config/keybinds/layout" + std::to_string(this->layoutNumber) + ".bin", std::ios::binary);
|
||||||
|
|
||||||
|
for (Action action : ACTION_LIST_IN_ORDER) {
|
||||||
|
this->keybinds.at(action).clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
char byte;
|
||||||
|
while (layoutFile.peek() != EOF) {
|
||||||
|
layoutFile.get(byte);
|
||||||
|
Action action = Action(byte);
|
||||||
|
|
||||||
|
bool separatorMet = false;
|
||||||
|
while (!separatorMet) {
|
||||||
|
layoutFile.get(byte);
|
||||||
|
if (byte == (char) 0xFF) {
|
||||||
|
separatorMet = true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this->keybinds.at(action).insert(sfKey(byte));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Keybinds::saveKeybindsToFile() const {
|
||||||
|
std::ofstream layoutFile("data/config/keybinds/layout" + std::to_string(this->layoutNumber) + ".bin", std::ios::trunc | std::ios::binary);
|
||||||
|
|
||||||
|
char byte;
|
||||||
|
for (Action action : ACTION_LIST_IN_ORDER) {
|
||||||
|
byte = action;
|
||||||
|
layoutFile.write(&byte, 1);
|
||||||
|
|
||||||
|
for (sfKey key : this->keybinds.at(action)) {
|
||||||
|
byte = (int) key;
|
||||||
|
layoutFile.write(&byte, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
byte = 0xFF;
|
||||||
|
layoutFile.write(&byte, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Keybinds::addKey(Action action, sfKey key) {
|
||||||
|
this->keybinds.at(action).insert(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Keybinds::clearKeys(Action action) {
|
||||||
|
this->keybinds.at(action).clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::set<Action> Keybinds::getActions(sfKey key) const {
|
||||||
|
std::set<Action> actions;
|
||||||
|
|
||||||
|
for (const auto& [action, keys] : this->keybinds) {
|
||||||
|
if (keys.contains(key)) {
|
||||||
|
actions.insert(action);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return actions;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::set<sfKey>& Keybinds::getKeybinds(Action action) const {
|
||||||
|
return this->keybinds.at(action);
|
||||||
|
}
|
||||||
@@ -3,30 +3,32 @@
|
|||||||
#include "../Core/Action.h"
|
#include "../Core/Action.h"
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <vector>
|
#include <set>
|
||||||
#include <SFML/Graphics.hpp>
|
#include <SFML/Graphics.hpp>
|
||||||
|
|
||||||
using sfKey = sf::Keyboard::Key;
|
using sfKey = sf::Keyboard::Key;
|
||||||
|
|
||||||
|
static const int NUMBER_OF_KEYBINDS = 5;
|
||||||
|
static const int CUSTOMIZABLE_KEYBINDS = NUMBER_OF_KEYBINDS - 1;
|
||||||
|
|
||||||
|
|
||||||
class Keybinds {
|
class Keybinds {
|
||||||
private:
|
private:
|
||||||
std::map<Action, std::vector<sfKey>> keybinds;
|
std::map<Action, std::set<sfKey>> keybinds;
|
||||||
|
int layoutNumber;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Keybinds();
|
Keybinds(int layoutNumber);
|
||||||
|
|
||||||
void loadKeybindsFromFile();
|
void loadKeybindsFromFile();
|
||||||
|
|
||||||
void saveKeybindsToFile() const;
|
void saveKeybindsToFile() const;
|
||||||
|
|
||||||
void createDefaultKeybindsFile() const;
|
|
||||||
|
|
||||||
void addKey(Action action, sfKey key);
|
void addKey(Action action, sfKey key);
|
||||||
|
|
||||||
void clearKeys(Action action);
|
void clearKeys(Action action);
|
||||||
|
|
||||||
const std::vector<Action>& getActions(sfKey key) const;
|
const std::set<Action> getActions(sfKey key) const;
|
||||||
|
|
||||||
const std::vector<sfKey>& getKeybinds(Action action) const;
|
const std::set<sfKey>& getKeybinds(Action action) const;
|
||||||
};
|
};
|
||||||
|
|||||||
21
src/GraphicalUI/PiecesType.h
Normal file
21
src/GraphicalUI/PiecesType.h
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
|
||||||
|
enum PiecesType {
|
||||||
|
CONVEX_PIECES,
|
||||||
|
HOLELESS_PIECES,
|
||||||
|
OTHER_PIECES,
|
||||||
|
ALL_PIECES,
|
||||||
|
SINGLE_PIECE
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
inline int getSizeOfPieces(PiecesType type) {
|
||||||
|
if (type < SINGLE_PIECE) return 0;
|
||||||
|
|
||||||
|
else return (type - SINGLE_PIECE + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline PiecesType createSinglePieceType(int size) {
|
||||||
|
return PiecesType(SINGLE_PIECE + size - 1);
|
||||||
|
}
|
||||||
@@ -4,66 +4,174 @@
|
|||||||
#include "Keybinds.h"
|
#include "Keybinds.h"
|
||||||
|
|
||||||
#include <SFML/Graphics.hpp>
|
#include <SFML/Graphics.hpp>
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
static const int NUMBER_OF_KEYBINDS = 5;
|
|
||||||
static const int CUSTOMIZABLE_KEYBINDS = NUMBER_OF_KEYBINDS - 1;
|
|
||||||
static const sf::Vector2u BASE_WINDOW_SIZE = {80, 50};
|
static const sf::Vector2u BASE_WINDOW_SIZE = {80, 50};
|
||||||
static const int WINDOW_SIZE_MULTIPLIERS[] = {4, 6, 9, 14, 20};
|
static const int WINDOW_SIZE_MULTIPLIERS[] = {4, 6, 9, 14, 20};
|
||||||
static const int WINDOW_SIZE_LAST_MODE = (sizeof(WINDOW_SIZE_MULTIPLIERS) / sizeof(int)) - 1;
|
static const int WINDOW_SIZE_LAST_MODE = (sizeof(WINDOW_SIZE_MULTIPLIERS) / sizeof(int)) - 1;
|
||||||
|
|
||||||
|
|
||||||
Settings::Settings() {
|
Settings::Settings() {
|
||||||
for (int i = 1; i <= 15; i++) {
|
for (int i = 1; i <= MAXIMUM_PIECES_SIZE; i++) {
|
||||||
this->menu.getPiecesList().loadPieces(i);
|
this->menu.getPiecesList().loadPieces(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this->keybinds.reserve(NUMBER_OF_KEYBINDS);
|
||||||
|
for (int i = 0; i < NUMBER_OF_KEYBINDS; i++) {
|
||||||
|
this->keybinds.emplace_back(i);
|
||||||
|
}
|
||||||
|
|
||||||
this->loadSettingsFromFile();
|
this->loadSettingsFromFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Settings::loadSettingsFromFile() {
|
void Settings::loadSettingsFromFile() {
|
||||||
this->menu.getPiecesList().unselectAll();
|
std::ifstream settingsFile("data/config/settings.bin", std::ios::binary);
|
||||||
this->menu.getPiecesList().selectAllPieces(4);
|
char byte;
|
||||||
this->windowSizeMode = 2;
|
|
||||||
|
// keybind layout
|
||||||
|
settingsFile.get(byte);
|
||||||
|
this->chosenKeybinds = byte;
|
||||||
|
|
||||||
|
// window size mode
|
||||||
|
settingsFile.get(byte);
|
||||||
|
this->windowSizeMode = byte;
|
||||||
|
|
||||||
|
// gamemode
|
||||||
|
settingsFile.get(byte);
|
||||||
|
this->gamemode = Gamemode(byte);
|
||||||
|
|
||||||
|
// board width
|
||||||
|
settingsFile.get(byte);
|
||||||
|
this->menu.setBoardWidth(byte);
|
||||||
|
|
||||||
|
// board height
|
||||||
|
settingsFile.get(byte);
|
||||||
|
this->menu.setBoardHeight(byte);
|
||||||
|
|
||||||
|
// piece distribution
|
||||||
|
settingsFile.get(byte);
|
||||||
|
//TODO
|
||||||
|
|
||||||
|
// selected pieces
|
||||||
|
char pieceType;
|
||||||
|
char pieceValue;
|
||||||
|
this->selectedPieces.clear();
|
||||||
|
while (settingsFile.get(pieceType)) {
|
||||||
|
if (settingsFile.eof()) break;
|
||||||
|
|
||||||
|
settingsFile.get(pieceValue);
|
||||||
|
this->selectedPieces.push_back({PiecesType(pieceType), pieceValue});
|
||||||
|
}
|
||||||
|
this->confirmSelectedPieces();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Settings::saveSettingsToFile() const {
|
void Settings::saveSettingsToFile() const {
|
||||||
|
std::ofstream settingsFile("data/config/settings.bin", std::ios::trunc | std::ios::binary);
|
||||||
|
char byte;
|
||||||
|
|
||||||
}
|
// keybind layout
|
||||||
|
byte = this->chosenKeybinds;
|
||||||
|
settingsFile.write(&byte, 1);
|
||||||
|
|
||||||
void Settings::createDefaultSettingsFile() const {
|
// window size mode
|
||||||
|
byte = this->windowSizeMode;
|
||||||
|
settingsFile.write(&byte, 1);
|
||||||
|
|
||||||
|
// gamemode
|
||||||
|
byte = this->gamemode;
|
||||||
|
settingsFile.write(&byte, 1);
|
||||||
|
|
||||||
|
// board width
|
||||||
|
byte = this->menu.getBoardWidth();
|
||||||
|
settingsFile.write(&byte, 1);
|
||||||
|
|
||||||
|
// board height
|
||||||
|
byte = this->menu.getBoardHeight();
|
||||||
|
settingsFile.write(&byte, 1);
|
||||||
|
|
||||||
|
// piece distribution
|
||||||
|
//TODO
|
||||||
|
settingsFile.write(&byte, 1);
|
||||||
|
|
||||||
|
// selected pieces
|
||||||
|
for (const auto& [type, value] : this->selectedPieces) {
|
||||||
|
byte = type;
|
||||||
|
settingsFile.write(&byte, 1);
|
||||||
|
byte = value;
|
||||||
|
settingsFile.write(&byte, 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Settings::selectNextKeybinds() {
|
bool Settings::selectNextKeybinds() {
|
||||||
if (this->chosenKeybinds < NUMBER_OF_KEYBINDS) {
|
if (this->chosenKeybinds < NUMBER_OF_KEYBINDS) {
|
||||||
this->chosenKeybinds++;
|
this->chosenKeybinds++;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Settings::selectPreviousKeybinds() {
|
bool Settings::selectPreviousKeybinds() {
|
||||||
if (this->chosenKeybinds > 0) {
|
if (this->chosenKeybinds > 0) {
|
||||||
this->chosenKeybinds--;
|
this->chosenKeybinds--;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Settings::canModifyCurrentKeybinds() const {
|
bool Settings::canModifyCurrentKeybinds() const {
|
||||||
return (this->chosenKeybinds == CUSTOMIZABLE_KEYBINDS);
|
return (this->chosenKeybinds == CUSTOMIZABLE_KEYBINDS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Settings::setGamemode(Gamemode gamemode) {
|
||||||
|
this->gamemode = gamemode;
|
||||||
|
}
|
||||||
|
|
||||||
bool Settings::widenWindow() {
|
bool Settings::widenWindow() {
|
||||||
if (this->windowSizeMode < WINDOW_SIZE_LAST_MODE) {
|
if (this->windowSizeMode < WINDOW_SIZE_LAST_MODE) {
|
||||||
this->windowSizeMode++;
|
this->windowSizeMode++;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Settings::shortenWindow() {
|
bool Settings::shortenWindow() {
|
||||||
if (this->windowSizeMode > 0) {
|
if (this->windowSizeMode > 0) {
|
||||||
this->windowSizeMode--;
|
this->windowSizeMode--;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Settings::setGamemode(Gamemode gamemode) {
|
void Settings::selectPieces(PiecesType type, int value) {
|
||||||
this->gamemode = gamemode;
|
this->selectedPieces.emplace_back(type, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Settings::unselectPieces(int index) {
|
||||||
|
if (index >= this->selectedPieces.size()) return;
|
||||||
|
|
||||||
|
this->selectedPieces.erase(this->selectedPieces.begin() + index);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Settings::confirmSelectedPieces() {
|
||||||
|
this->menu.getPiecesList().unselectAll();
|
||||||
|
|
||||||
|
for (const auto& [type, value] : this->selectedPieces) {
|
||||||
|
int size = getSizeOfPieces(type);
|
||||||
|
|
||||||
|
if (size == 0) {
|
||||||
|
switch (type) {
|
||||||
|
case CONVEX_PIECES : {this->menu.getPiecesList().selectConvexPieces(value); break;}
|
||||||
|
case HOLELESS_PIECES : {this->menu.getPiecesList().selectHolelessPieces(value); break;}
|
||||||
|
case OTHER_PIECES : {this->menu.getPiecesList().selectOtherPieces(value); break;}
|
||||||
|
case ALL_PIECES : {this->menu.getPiecesList().selectAllPieces(value); break;}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (size > MAXIMUM_PIECES_SIZE) return;
|
||||||
|
|
||||||
|
this->menu.getPiecesList().selectPiece(size, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Menu& Settings::getMenu() {
|
Menu& Settings::getMenu() {
|
||||||
@@ -82,6 +190,10 @@ int Settings::getWindowSizeMultiplier() const {
|
|||||||
return WINDOW_SIZE_MULTIPLIERS[this->windowSizeMode];
|
return WINDOW_SIZE_MULTIPLIERS[this->windowSizeMode];
|
||||||
}
|
}
|
||||||
|
|
||||||
const sf::VideoMode& Settings::getVideoMode() const {
|
const sf::VideoMode Settings::getVideoMode() const {
|
||||||
return sf::VideoMode(BASE_WINDOW_SIZE * (unsigned int) WINDOW_SIZE_MULTIPLIERS[this->windowSizeMode]);
|
return sf::VideoMode(BASE_WINDOW_SIZE * (unsigned int) WINDOW_SIZE_MULTIPLIERS[this->windowSizeMode]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::vector<std::pair<PiecesType, int>>& Settings::getSelectedPieces() const {
|
||||||
|
return this->selectedPieces;
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,10 +2,16 @@
|
|||||||
|
|
||||||
#include "../Core/Menu.h"
|
#include "../Core/Menu.h"
|
||||||
#include "Keybinds.h"
|
#include "Keybinds.h"
|
||||||
|
#include "PiecesType.h"
|
||||||
|
|
||||||
#include <SFML/Graphics.hpp>
|
#include <SFML/Graphics.hpp>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
static const int MAXIMUM_BOARD_WIDTH = 40;
|
||||||
|
static const int MAXIMUM_BOARD_HEIGHT = 40;
|
||||||
|
|
||||||
|
static const int MAXIMUM_PIECES_SIZE = 10;
|
||||||
|
|
||||||
|
|
||||||
class Settings {
|
class Settings {
|
||||||
private:
|
private:
|
||||||
@@ -14,6 +20,7 @@ class Settings {
|
|||||||
int chosenKeybinds;
|
int chosenKeybinds;
|
||||||
Gamemode gamemode;
|
Gamemode gamemode;
|
||||||
int windowSizeMode;
|
int windowSizeMode;
|
||||||
|
std::vector<std::pair<PiecesType, int>> selectedPieces;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Settings();
|
Settings();
|
||||||
@@ -22,8 +29,6 @@ class Settings {
|
|||||||
|
|
||||||
void saveSettingsToFile() const;
|
void saveSettingsToFile() const;
|
||||||
|
|
||||||
void createDefaultSettingsFile() const;
|
|
||||||
|
|
||||||
bool selectNextKeybinds();
|
bool selectNextKeybinds();
|
||||||
|
|
||||||
bool selectPreviousKeybinds();
|
bool selectPreviousKeybinds();
|
||||||
@@ -36,6 +41,12 @@ class Settings {
|
|||||||
|
|
||||||
bool shortenWindow();
|
bool shortenWindow();
|
||||||
|
|
||||||
|
void selectPieces(PiecesType type, int value);
|
||||||
|
|
||||||
|
void unselectPieces(int index);
|
||||||
|
|
||||||
|
void confirmSelectedPieces();
|
||||||
|
|
||||||
Menu& getMenu();
|
Menu& getMenu();
|
||||||
|
|
||||||
Keybinds& getKeybinds();
|
Keybinds& getKeybinds();
|
||||||
@@ -44,5 +55,7 @@ class Settings {
|
|||||||
|
|
||||||
int getWindowSizeMultiplier() const;
|
int getWindowSizeMultiplier() const;
|
||||||
|
|
||||||
const sf::VideoMode& getVideoMode() const;
|
const sf::VideoMode getVideoMode() const;
|
||||||
|
|
||||||
|
const std::vector<std::pair<PiecesType, int>>& getSelectedPieces() const;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,138 +1,153 @@
|
|||||||
#include <SFML/Graphics.hpp>
|
#include "GraphApp.h"
|
||||||
#include "../Core/Menu.h"
|
|
||||||
#include "../Pieces/PiecesFiles.h"
|
#include "../Pieces/PiecesFiles.h"
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
void setToDefaultConfig();
|
#include <fstream>
|
||||||
|
|
||||||
|
|
||||||
|
void resetConfigFiles();
|
||||||
|
void resetSettingsFile();
|
||||||
|
void resetKeybindFile(int layout);
|
||||||
|
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
std::srand(std::time(NULL));
|
std::srand(std::time(NULL));
|
||||||
|
|
||||||
sf::RenderWindow window(sf::VideoMode({800, 640}), "My window", sf::Style::Titlebar | sf::Style::Close);
|
// keep only for dev
|
||||||
window.setPosition(sf::Vector2i(sf::VideoMode::getDesktopMode().size.x / 2 - 400, sf::VideoMode::getDesktopMode().size.y / 2 - 320));
|
|
||||||
|
|
||||||
PiecesFiles pf;
|
PiecesFiles pf;
|
||||||
for (int i = 1; i <= 10; i++) {
|
for (int i = 1; i <= MAXIMUM_PIECES_SIZE; i++) {
|
||||||
|
if (!std::filesystem::exists("data/pieces/" + std::to_string(i) + "minos.bin")) {
|
||||||
|
std::cout << "pieces files for size " << i << " not found, generating..." << std::endl;
|
||||||
pf.savePieces(i);
|
pf.savePieces(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
Menu m;
|
|
||||||
m.getPiecesList().loadPieces(10);
|
|
||||||
m.getPiecesList().selectAllPieces(4);
|
|
||||||
m.setBoardWidth(10);
|
|
||||||
m.getPlayerControls().setDAS(6);
|
|
||||||
m.getPlayerControls().setARR(0);
|
|
||||||
m.getPlayerControls().setSDR(0);
|
|
||||||
Game game = m.startGame(SPRINT);
|
|
||||||
game.start();
|
|
||||||
|
|
||||||
sf::Clock clock;
|
|
||||||
|
|
||||||
sf::Font font;
|
|
||||||
if (!font.openFromFile("data/fonts/arial.ttf")) {
|
|
||||||
std::cout << "aaaaaaaaaaaaaa";
|
|
||||||
}
|
}
|
||||||
sf::Text text(font);
|
if (!std::filesystem::exists("data/config/settings.bin")) {
|
||||||
text.setCharacterSize(20);
|
resetSettingsFile();
|
||||||
text.setFillColor(sf::Color::White);
|
|
||||||
|
|
||||||
while (window.isOpen()) {
|
|
||||||
while (const std::optional event = window.pollEvent()) {
|
|
||||||
if (event->is<sf::Event::Closed>())
|
|
||||||
window.close();
|
|
||||||
}
|
}
|
||||||
|
for (int i = 0; i < 5; i++) {
|
||||||
if (clock.getElapsedTime().asMilliseconds() > 16) {
|
if (!std::filesystem::exists("data/config/keybinds/layout" + std::to_string(i) + ".bin")) {
|
||||||
clock.restart();
|
resetKeybindFile(i);
|
||||||
|
|
||||||
window.clear(sf::Color::Black);
|
|
||||||
|
|
||||||
std::set<Action> actions;
|
|
||||||
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::Left)) {
|
|
||||||
actions.insert(MOVE_LEFT);
|
|
||||||
}
|
|
||||||
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::Right)) {
|
|
||||||
actions.insert(MOVE_RIGHT);
|
|
||||||
}
|
|
||||||
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::Up)) {
|
|
||||||
actions.insert(HARD_DROP);
|
|
||||||
}
|
|
||||||
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::Down)) {
|
|
||||||
actions.insert(SOFT_DROP);
|
|
||||||
}
|
|
||||||
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::A)) {
|
|
||||||
actions.insert(ROTATE_CCW);
|
|
||||||
}
|
|
||||||
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::E)) {
|
|
||||||
actions.insert(ROTATE_CW);
|
|
||||||
}
|
|
||||||
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::Z)) {
|
|
||||||
actions.insert(HOLD);
|
|
||||||
}
|
|
||||||
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::Tab)) {
|
|
||||||
actions.insert(ROTATE_0);
|
|
||||||
}
|
|
||||||
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::Num2)) {
|
|
||||||
actions.insert(ROTATE_180);
|
|
||||||
}
|
|
||||||
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::R)) {
|
|
||||||
game.reset();
|
|
||||||
game.start();
|
|
||||||
}
|
|
||||||
game.nextFrame(actions);
|
|
||||||
|
|
||||||
for (int y = game.getBoard().getBaseHeight() + 5; y >= 0; y--) {
|
|
||||||
for (int x = 0; x < game.getBoard().getWidth(); x++) {
|
|
||||||
bool isActivePieceHere = (game.getActivePiece() != nullptr) && (game.getActivePiece()->getPositions().contains(Position{x, y} - game.getActivePiecePosition()));
|
|
||||||
bool isGhostPieceHere = (game.getActivePiece() != nullptr) && (game.getActivePiece()->getPositions().contains(Position{x, y} - game.ghostPiecePosition()));
|
|
||||||
Block block = (isActivePieceHere || isGhostPieceHere) ? game.getActivePiece()->getBlockType() : game.getBoard().getBlock(Position{x, y});
|
|
||||||
|
|
||||||
sf::RectangleShape cell(sf::Vector2f(20.f, 20.f));
|
|
||||||
cell.setFillColor(sf::Color(BLOCKS_COLOR[block].red, BLOCKS_COLOR[block].green, BLOCKS_COLOR[block].blue, (isGhostPieceHere && !isActivePieceHere) ? 150 : 255));
|
|
||||||
cell.setPosition(sf::Vector2f(x*20, (game.getBoard().getBaseHeight() + 10 - y)*20));
|
|
||||||
window.draw(cell);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (game.getNextPieces().size() > 0) {
|
// before compiling release version
|
||||||
for (int y = 10; y >= 0; y--) {
|
resetConfigFiles();
|
||||||
for (int x = 0; x <= 10; x++) {
|
|
||||||
Block block = game.getNextPieces().at(0).getBlockType();
|
|
||||||
sf::RectangleShape cell(sf::Vector2f(20.f, 20.f));
|
|
||||||
cell.setPosition(sf::Vector2f((x + 2 + game.getBoard().getWidth())*20, (game.getBoard().getBaseHeight() - y)*20));
|
|
||||||
if (game.getNextPieces().at(0).getPositions().contains(Position({x, y}))) {
|
|
||||||
cell.setFillColor(sf::Color(BLOCKS_COLOR[block].red, BLOCKS_COLOR[block].green, BLOCKS_COLOR[block].blue));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
cell.setFillColor(sf::Color(0, 0, 0));
|
|
||||||
}
|
|
||||||
window.draw(cell);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (game.getHeldPiece() != nullptr) {
|
GraphApp UI;
|
||||||
for (int y = 10; y >= 0; y--) {
|
UI.run();
|
||||||
for (int x = 0; x <= 10; x++) {
|
|
||||||
Block block = game.getHeldPiece()->getBlockType();
|
|
||||||
sf::RectangleShape cell(sf::Vector2f(20.f, 20.f));
|
|
||||||
cell.setPosition(sf::Vector2f((x + 12 + game.getBoard().getWidth())*20, (game.getBoard().getBaseHeight() - y)*20));
|
|
||||||
if (game.getHeldPiece()->getPositions().contains(Position({x, y}))) {
|
|
||||||
cell.setFillColor(sf::Color(BLOCKS_COLOR[block].red, BLOCKS_COLOR[block].green, BLOCKS_COLOR[block].blue));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
cell.setFillColor(sf::Color(0, 0, 0));
|
|
||||||
}
|
|
||||||
window.draw(cell);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
text.setPosition(sf::Vector2f(12*20, (game.getBoard().getBaseHeight() - 5)*20));
|
return 0;
|
||||||
text.setString(sf::String(std::to_string(game.getClearedLines())));
|
}
|
||||||
window.draw(text);
|
|
||||||
|
|
||||||
window.display();
|
|
||||||
}
|
void resetConfigFiles() {
|
||||||
|
resetSettingsFile;
|
||||||
|
for (int i = 0; i < 5; i++) {
|
||||||
|
resetKeybindFile(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void resetSettingsFile() {
|
||||||
|
std::ofstream settingsFile("data/config/settings.bin", std::ios::trunc | std::ios::binary);
|
||||||
|
char byte;
|
||||||
|
|
||||||
|
// keybind layout
|
||||||
|
byte = 0;
|
||||||
|
settingsFile.write(&byte, 1);
|
||||||
|
|
||||||
|
// window size mode
|
||||||
|
byte = 2;
|
||||||
|
settingsFile.write(&byte, 1);
|
||||||
|
|
||||||
|
// gamemode
|
||||||
|
byte = SPRINT;
|
||||||
|
settingsFile.write(&byte, 1);
|
||||||
|
|
||||||
|
// board width
|
||||||
|
byte = 10;
|
||||||
|
settingsFile.write(&byte, 1);
|
||||||
|
|
||||||
|
// board height
|
||||||
|
byte = 20;
|
||||||
|
settingsFile.write(&byte, 1);
|
||||||
|
|
||||||
|
// piece distribution
|
||||||
|
byte = 0;
|
||||||
|
settingsFile.write(&byte, 1);
|
||||||
|
|
||||||
|
// selected pieces
|
||||||
|
byte = ALL_PIECES;
|
||||||
|
settingsFile.write(&byte, 1);
|
||||||
|
byte = 4;
|
||||||
|
settingsFile.write(&byte, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void resetKeybindFile(int layout) {
|
||||||
|
if (layout < 0 || layout > 4) return;
|
||||||
|
|
||||||
|
std::ofstream layoutFile("data/config/keybinds/layout" + std::to_string(layout) + ".bin", std::ios::trunc | std::ios::binary);
|
||||||
|
std::map<Action, sfKey> keybinds;
|
||||||
|
|
||||||
|
if (layout != 4) {
|
||||||
|
keybinds.insert({PAUSE, sfKey::P});
|
||||||
|
keybinds.insert({RETRY, sfKey::R});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (layout == 0) {
|
||||||
|
keybinds.insert({MOVE_LEFT, sfKey::Left});
|
||||||
|
keybinds.insert({MOVE_RIGHT, sfKey::Right});
|
||||||
|
keybinds.insert({SOFT_DROP, sfKey::Down});
|
||||||
|
keybinds.insert({HARD_DROP, sfKey::Space});
|
||||||
|
keybinds.insert({ROTATE_CW, sfKey::Up});
|
||||||
|
keybinds.insert({ROTATE_CCW, sfKey::Z});
|
||||||
|
keybinds.insert({ROTATE_180, sfKey::X});
|
||||||
|
keybinds.insert({ROTATE_0, sfKey::LShift});
|
||||||
|
keybinds.insert({HOLD, sfKey::C});
|
||||||
|
}
|
||||||
|
if (layout == 1) {
|
||||||
|
keybinds.insert({MOVE_LEFT, sfKey::Z});
|
||||||
|
keybinds.insert({MOVE_RIGHT, sfKey::C});
|
||||||
|
keybinds.insert({SOFT_DROP, sfKey::X});
|
||||||
|
keybinds.insert({HARD_DROP, sfKey::S});
|
||||||
|
keybinds.insert({ROTATE_CW, sfKey::M});
|
||||||
|
keybinds.insert({ROTATE_CCW, sfKey::Comma});
|
||||||
|
keybinds.insert({ROTATE_180, sfKey::J});
|
||||||
|
keybinds.insert({ROTATE_0, sfKey::K});
|
||||||
|
keybinds.insert({HOLD, sfKey::LShift});
|
||||||
|
}
|
||||||
|
if (layout == 2) {
|
||||||
|
keybinds.insert({MOVE_LEFT, sfKey::A});
|
||||||
|
keybinds.insert({MOVE_RIGHT, sfKey::D});
|
||||||
|
keybinds.insert({SOFT_DROP, sfKey::W});
|
||||||
|
keybinds.insert({HARD_DROP, sfKey::S});
|
||||||
|
keybinds.insert({ROTATE_CW, sfKey::Left});
|
||||||
|
keybinds.insert({ROTATE_CCW, sfKey::Right});
|
||||||
|
keybinds.insert({ROTATE_180, sfKey::Up});
|
||||||
|
keybinds.insert({ROTATE_0, sfKey::Down});
|
||||||
|
keybinds.insert({HOLD, sfKey::RShift});
|
||||||
|
}
|
||||||
|
if (layout == 3) {
|
||||||
|
keybinds.insert({MOVE_LEFT, sfKey::Left});
|
||||||
|
keybinds.insert({MOVE_RIGHT, sfKey::Right});
|
||||||
|
keybinds.insert({SOFT_DROP, sfKey::Down});
|
||||||
|
keybinds.insert({HARD_DROP, sfKey::Up});
|
||||||
|
keybinds.insert({ROTATE_CW, sfKey::E});
|
||||||
|
keybinds.insert({ROTATE_CCW, sfKey::A});
|
||||||
|
keybinds.insert({ROTATE_180, sfKey::Num2});
|
||||||
|
keybinds.insert({ROTATE_0, sfKey::Tab});
|
||||||
|
keybinds.insert({HOLD, sfKey::Z});
|
||||||
|
}
|
||||||
|
|
||||||
|
char byte;
|
||||||
|
for (Action action : ACTION_LIST_IN_ORDER) {
|
||||||
|
byte = action;
|
||||||
|
layoutFile.write(&byte, 1);
|
||||||
|
|
||||||
|
if (keybinds.contains(action)) {
|
||||||
|
byte = (int) keybinds.at(action);
|
||||||
|
layoutFile.write(&byte, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
byte = 0xFF;
|
||||||
|
layoutFile.write(&byte, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ void TextApp::run() {
|
|||||||
default : std::cout << "Invalid answer!" << std::endl;
|
default : std::cout << "Invalid answer!" << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::cout << "===| SEE YA NEXT TIME! |===";
|
std::cout << "===| SEE YA NEXT TIME! |===" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextApp::choosePieces() {
|
void TextApp::choosePieces() {
|
||||||
@@ -136,7 +136,6 @@ void TextApp::seeKeybinds() const {
|
|||||||
|
|
||||||
void TextApp::defaultKeybinds() {
|
void TextApp::defaultKeybinds() {
|
||||||
this->keybinds.clear();
|
this->keybinds.clear();
|
||||||
this->keybinds.insert({"quit", QUIT});
|
|
||||||
this->keybinds.insert({"pause", PAUSE});
|
this->keybinds.insert({"pause", PAUSE});
|
||||||
this->keybinds.insert({"retry", RETRY});
|
this->keybinds.insert({"retry", RETRY});
|
||||||
this->keybinds.insert({"h", HOLD});
|
this->keybinds.insert({"h", HOLD});
|
||||||
@@ -171,15 +170,21 @@ void TextApp::startGame() const {
|
|||||||
|
|
||||||
std::set<Action> playerActions;
|
std::set<Action> playerActions;
|
||||||
std::set<Action> lastFrameActions;
|
std::set<Action> lastFrameActions;
|
||||||
std::set<Action> metaActions;
|
bool retrying = false;
|
||||||
for (std::string action : actions) {
|
for (std::string action : actions) {
|
||||||
try {
|
if (action == "quit") {
|
||||||
Action playerAction = this->keybinds.at(action);
|
quit = true;
|
||||||
if (playerAction == PAUSE || playerAction == RETRY || playerAction == quit) {
|
|
||||||
metaActions.insert(playerAction);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (playerAction == SOFT_DROP || playerAction == MOVE_LEFT || playerAction == MOVE_RIGHT) {
|
try {
|
||||||
|
Action playerAction = this->keybinds.at(action);
|
||||||
|
if (playerAction == RETRY) {
|
||||||
|
retrying = true;
|
||||||
|
}
|
||||||
|
else if (playerAction == PAUSE) {
|
||||||
|
paused = (!paused);
|
||||||
|
}
|
||||||
|
else if (playerAction == SOFT_DROP || playerAction == MOVE_LEFT || playerAction == MOVE_RIGHT) {
|
||||||
playerActions.insert(playerAction);
|
playerActions.insert(playerAction);
|
||||||
lastFrameActions.insert(playerAction);
|
lastFrameActions.insert(playerAction);
|
||||||
}
|
}
|
||||||
@@ -190,19 +195,12 @@ void TextApp::startGame() const {
|
|||||||
playerActions.insert(playerAction);
|
playerActions.insert(playerAction);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
catch (std::exception ignored) {}
|
catch (std::exception ignored) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (metaActions.contains(PAUSE)) {
|
|
||||||
paused = (!paused);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!paused) {
|
if (!paused && !quit) {
|
||||||
if (metaActions.contains(QUIT)) {
|
if (retrying) {
|
||||||
quit = true;
|
|
||||||
}
|
|
||||||
else if (metaActions.contains(RETRY)) {
|
|
||||||
game.reset();
|
game.reset();
|
||||||
game.start();
|
game.start();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user