From 6ed85869ae3de164967ce8dd1f6babb10fdea0a1 Mon Sep 17 00:00:00 2001 From: zulianc Date: Tue, 27 May 2025 18:52:07 +0200 Subject: [PATCH] added bones block to master mode and added invisible mode --- README.md | 8 ++-- src/Core/Game.cpp | 4 ++ src/Core/Game.h | 5 +++ src/Core/GameParameters.cpp | 34 ++++++++++++++-- src/Core/GameParameters.h | 8 +++- src/Core/Gamemode.h | 3 ++ .../AppMenus/GamePlayingAppMenu.cpp | 40 ++++++++++++++----- .../AppMenus/GameSettingsAppMenu.cpp | 8 ++-- 8 files changed, 89 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index e014240..3caf7e9 100644 --- a/README.md +++ b/README.md @@ -24,11 +24,12 @@ You will find more infos about the Rotation System, the scoring system, or the d - Every polyominoes up to pentedecaminoes! - 7bag with proportionnality for each polyomino size! +- AutoRS as the Rotation System! +- 0° rotations! +- All spin! +- IRS, IHS, infinite hold, and other leniency mechanics! - Customizable board size! - Customizable keybinds! -- 0° rotations! -- AutoRS as the Rotation System! -- IRS, IHS, infinite hold, and other leniency mechanics! - Very bland interface!! (i'm not a designer) ### Available gamemodes @@ -37,6 +38,7 @@ You will find more infos about the Rotation System, the scoring system, or the d - MARATHON : clear 200 lines with increasing gravity! - ULTRA : scores as much as possible in only 2 minutes! - MASTER : clear 200 lines at levels higher than maximum gravity! +- INVISIBLE : get 1000 grade while not being able to see the board! - ZEN : practice indefinitely in this mode with no gravity! ### Screenshots diff --git a/src/Core/Game.cpp b/src/Core/Game.cpp index 963b302..c8efbea 100644 --- a/src/Core/Game.cpp +++ b/src/Core/Game.cpp @@ -366,6 +366,10 @@ bool Game::areBlocksBones() const { return this->parameters.getBoneBlocks(); } +bool Game::isBoardInvisible() const { + return this->parameters.getInvisibleBoard(); +} + const Board& Game::getBoard() const { return this->board.getBoard(); } diff --git a/src/Core/Game.h b/src/Core/Game.h index 71473ef..cd577a3 100644 --- a/src/Core/Game.h +++ b/src/Core/Game.h @@ -136,6 +136,11 @@ class Game { */ bool areBlocksBones() const; + /** + * @return If the board is currently invisible + */ + bool isBoardInvisible() const; + /** * @return The board */ diff --git a/src/Core/GameParameters.cpp b/src/Core/GameParameters.cpp index e5f9efe..d3caf84 100644 --- a/src/Core/GameParameters.cpp +++ b/src/Core/GameParameters.cpp @@ -24,6 +24,8 @@ void GameParameters::reset() { case MARATHON : {this->level = 1; break;} // goes from level 20 to 39 case MASTER : {this->level = 20; break;} + // goes from level 1 to 19 + case INVISIBLE : {this->level = 1; break;} // no gravity case ZEN : {this->level = 0; break;} default : this->level = 1; @@ -34,7 +36,7 @@ void GameParameters::reset() { void GameParameters::lockedPiece(const LineClear& lineClear) { switch (this->gamemode) { - // modes where level increases + // modes where level increases with lines case MARATHON : case MASTER : { int previousLines = this->clearedLines; @@ -51,9 +53,23 @@ void GameParameters::lockedPiece(const LineClear& lineClear) { default : this->clearedLines += lineClear.lines; } + int previousGrade = this->grade; if (!((lineClear.lines == 0) && ((this->grade % 100) == 99))) { this->grade += (1 + lineClear.lines); } + + switch (this->gamemode) { + // modes where level increases with grade + case INVISIBLE : { + if (previousGrade / 100 < this->grade / 100) { + this->level += 2; + this->updateStats(); + } + break; + } + // other modes + default : break; + } } bool GameParameters::hasWon(int framesPassed) const { @@ -66,6 +82,8 @@ bool GameParameters::hasWon(int framesPassed) const { case MARATHON : return this->clearedLines >= 200; // win once 200 lines have been cleared case MASTER : return this->clearedLines >= 200; + // win once 1000 grade has been passed + case INVISIBLE : return this->grade >= 1000; // infinite mode case ZEN : default : return false; @@ -84,7 +102,8 @@ void GameParameters::updateStats() { } // 3 for slow-controls gamemodes case MARATHON : - case MASTER : { + case MASTER : + case INVISIBLE : { this->nextQueueLength = 3; break; } @@ -94,10 +113,13 @@ void GameParameters::updateStats() { /* BONE BLOCKS */ switch (this->gamemode) { // blocks turns into bone blocks at level 30 - case MASTER : this->boneBlocks = (this->level >= 30); + case MASTER : {this->boneBlocks = (this->level >= 30); break;} default : this->boneBlocks = false; } + /* INVISIBLE */ + this->invisibleBoard = (this->gamemode == INVISIBLE); + /* GRAVITY */ // get gravity for an assumed 20-rows board static const int gravityPerLevel[] = { @@ -152,6 +174,8 @@ void GameParameters::updateStats() { case MARATHON : {this->ARE = 24 - (this->level - 1); break;} // starts at 400ms (24f) at lvl 20 and ends at 083ms (5f) at lvl 39 case MASTER : {this->ARE = 24 - (this->level - 20); break;} + // fixed at 250ms (15f) + case INVISIBLE : {this->ARE = 15; break;} // no ARE by default default : this->ARE = 0; } @@ -228,6 +252,10 @@ bool GameParameters::getBoneBlocks() const { return this->boneBlocks; } +bool GameParameters::getInvisibleBoard() const { + return this->invisibleBoard; +} + int GameParameters::getGravity() const { return this->gravity; } diff --git a/src/Core/GameParameters.h b/src/Core/GameParameters.h index a0edd4d..1fa4e03 100644 --- a/src/Core/GameParameters.h +++ b/src/Core/GameParameters.h @@ -18,6 +18,7 @@ class GameParameters { int grade; // the current amount of points int nextQueueLength; // the number of pieces visibles in the next queue bool boneBlocks; // wheter all blocks are bone blocks + bool invisibleBoard; // wheter the board is invisible int gravity; // the gravity at which pieces drop int lockDelay; // the time before the piece lock in place int forcedLockDelay; // the forced time before the piece lock in place @@ -77,9 +78,14 @@ class GameParameters { int getNextQueueLength() const; /** - * Returns wheter the blocks are currently bone blocks + * @return Wheter the blocks are currently bone blocks */ bool getBoneBlocks() const; + + /** + * @return Wheter the board is currently invisible + */ + bool getInvisibleBoard() const; /** * @return The current gravity for a 20-line high board diff --git a/src/Core/Gamemode.h b/src/Core/Gamemode.h index 22e4cb4..e45f85f 100644 --- a/src/Core/Gamemode.h +++ b/src/Core/Gamemode.h @@ -11,6 +11,7 @@ enum Gamemode { MARATHON, ULTRA, MASTER, + INVISIBLE, ZEN }; @@ -24,6 +25,7 @@ inline std::string getGamemodeName(Gamemode gamemode) { "MARATHON", "ULTRA", "MASTER", + "INVISIBLE", "ZEN" }; @@ -39,6 +41,7 @@ inline std::string getGamemodeGoal(Gamemode gamemode) { "200 lines", "2 minutes", "200 lines", + "1000 grade", "Infinite" }; diff --git a/src/GraphicalUI/AppMenus/GamePlayingAppMenu.cpp b/src/GraphicalUI/AppMenus/GamePlayingAppMenu.cpp index 809b28c..09772df 100644 --- a/src/GraphicalUI/AppMenus/GamePlayingAppMenu.cpp +++ b/src/GraphicalUI/AppMenus/GamePlayingAppMenu.cpp @@ -104,17 +104,26 @@ void GamePlayingAppMenu::computeFrame() { void GamePlayingAppMenu::drawFrame() const { this->renderWindow->clear(sf::Color(200, 200, 200)); - + + sf::Color bonesBlockColor(0, 0, 0); + sf::Color bonesBlockGhostColor(100, 100, 100); + bool areBlockBones = this->game.areBlocksBones(); + bool isBoardInvisible = this->game.isBoardInvisible() && !(this->game.hasWon() || this->game.hasLost()); + sf::Vector2f cellSize(this->cellSizeZoom, this->cellSizeZoom); + float cellOutlineThickness = this->cellSizeZoom / 4; bool drawActivePiece = (this->game.getActivePiece() != nullptr) && (!this->game.hasLost()); // board for (int y = this->game.getBoard().getBaseHeight() + 9; y >= 0; y--) { for (int x = 0; x < this->game.getBoard().getWidth(); x++) { Block block = this->game.getBoard().getBlock(Position{x, y}); + if (isBoardInvisible) block = NOTHING; sf::RectangleShape cell(cellSize); - cell.setFillColor(this->getColorOfBlock(block, (block == NOTHING) ? 0 : -30)); + cell.setFillColor((areBlockBones && block != NOTHING) + ? bonesBlockColor + : this->getColorOfBlock(block, (block == NOTHING) ? 0 : -30)); cell.setPosition(this->getBoardBlockPosition(x, y)); this->renderWindow->draw(cell); } @@ -122,7 +131,10 @@ void GamePlayingAppMenu::drawFrame() const { if (drawActivePiece) { // ghost piece - sf::Color ghostColor = this->getColorOfBlock(this->game.getActivePiece()->getBlockType(), 100); + sf::Color ghostColor = areBlockBones + ? bonesBlockGhostColor + : this->getColorOfBlock(this->game.getActivePiece()->getBlockType(), 100); + for (const Position& position : this->game.getActivePiece()->getPositions()) { Position cellPosition = (this->game.getGhostPiecePosition() + position); @@ -133,13 +145,13 @@ void GamePlayingAppMenu::drawFrame() const { } // active piece outline - float pieceOutlineSize = std::roundf(this->cellSizeZoom / 4); sf::Color pieceOultlineColor = sf::Color(255, 255 - (255 * this->game.getForcedLockDelayProgression()), 255 - (255 * this->game.getForcedLockDelayProgression())); + for (const Position& position : this->game.getActivePiece()->getPositions()) { Position cellPosition = (this->game.getActivePiecePosition() + position); sf::RectangleShape cell(cellSize); - cell.setOutlineThickness(pieceOutlineSize); + cell.setOutlineThickness(cellOutlineThickness); cell.setOutlineColor(pieceOultlineColor); cell.setPosition(this->getBoardBlockPosition(cellPosition.x, cellPosition.y)); this->renderWindow->draw(cell); @@ -154,7 +166,9 @@ void GamePlayingAppMenu::drawFrame() const { if (drawActivePiece) { // active piece - sf::Color pieceColor = this->getColorOfBlock(this->game.getActivePiece()->getBlockType(), -200 * (this->game.getLockDelayProgression())); + sf::Color pieceColor = areBlockBones + ? bonesBlockColor + : this->getColorOfBlock(this->game.getActivePiece()->getBlockType(), -200 * (this->game.getLockDelayProgression())); for (const Position& position : this->game.getActivePiece()->getPositions()) { Position cellPosition = (this->game.getActivePiecePosition() + position); @@ -173,7 +187,9 @@ void GamePlayingAppMenu::drawFrame() const { nextBox.position.y -= upShift; sf::Vector2f nextCellSize(this->nextCellSizeZoom, this->nextCellSizeZoom); - sf::Color color = this->getColorOfBlock(this->game.getNextPieces().at(i).getBlockType(), 0); + sf::Color pieceColor = areBlockBones + ? bonesBlockColor + : this->getColorOfBlock(this->game.getNextPieces().at(i).getBlockType(), 0); sf::Color boxColor = sf::Color(180, 180, 180); int lowestRank = 0; @@ -181,7 +197,7 @@ void GamePlayingAppMenu::drawFrame() const { for (int x = 0; x < this->game.getNextPieces().at(i).getLength(); x++) { sf::RectangleShape cell(nextCellSize); if (this->game.getNextPieces().at(i).getPositions().contains(Position{x, y})) { - cell.setFillColor(color); + cell.setFillColor(pieceColor); lowestRank = y; } else { @@ -199,9 +215,11 @@ void GamePlayingAppMenu::drawFrame() const { // hold box if (this->game.getHeldPiece() != nullptr) { sf::Vector2f holdCellSize(this->holdCellSizeZoom, this->holdCellSizeZoom); - sf::Color color = this->getColorOfBlock(this->game.getHeldPiece()->getBlockType(), 0); + sf::Color color = areBlockBones + ? bonesBlockColor + : this->getColorOfBlock(this->game.getHeldPiece()->getBlockType(), 0); sf::Color boxColor = sf::Color(180, 180, 180); - + for (int y = 0; y < this->game.getHeldPiece()->getLength(); y++) { for (int x = 0; x < this->game.getHeldPiece()->getLength(); x++) { sf::RectangleShape cell(holdCellSize); @@ -212,7 +230,7 @@ void GamePlayingAppMenu::drawFrame() const { cell.setFillColor(boxColor); } cell.setPosition(sf::Vector2f(this->holdBoxPosition.position.x + (x * this->nextCellSizeZoom), - this->holdBoxPosition.position.y + ((this->game.getHeldPiece()->getLength() - y - 1) * this->holdCellSizeZoom))); + this->holdBoxPosition.position.y + ((this->game.getHeldPiece()->getLength() - y - 1) * this->holdCellSizeZoom))); this->renderWindow->draw(cell); } } diff --git a/src/GraphicalUI/AppMenus/GameSettingsAppMenu.cpp b/src/GraphicalUI/AppMenus/GameSettingsAppMenu.cpp index 715edf3..6cfdea0 100644 --- a/src/GraphicalUI/AppMenus/GameSettingsAppMenu.cpp +++ b/src/GraphicalUI/AppMenus/GameSettingsAppMenu.cpp @@ -13,7 +13,7 @@ GameSettingsAppMenu::GameSettingsAppMenu(std::shared_ptr menuStack, std::shared_ptr settings, std::shared_ptr renderWindow) : AppMenu(menuStack, settings, renderWindow), - playerCursor({2, 3, 2}) { + playerCursor({2, 3, 3}) { } @@ -33,7 +33,8 @@ void GameSettingsAppMenu::computeFrame() { case 2 : { switch (this->playerCursor.getPosition().x) { case 0 : {this->settings->setGamemode(MASTER); break;} - case 1 : {this->settings->setGamemode(ZEN); break;} + case 1 : {this->settings->setGamemode(INVISIBLE); break;} + case 2 : {this->settings->setGamemode(ZEN); break;} } break; } @@ -76,7 +77,8 @@ void GameSettingsAppMenu::drawFrame() const { this->placeText(text, this->playerCursor, "MARATHON", 25.f, 35.f, sf::Vector2u{1, 1}); this->placeText(text, this->playerCursor, "ULTRA", 50.f, 35.f, sf::Vector2u{2, 1}); this->placeText(text, this->playerCursor, "MASTER", 5.f, 45.f, sf::Vector2u{0, 2}); - this->placeText(text, this->playerCursor, "ZEN", 25.f, 45.f, sf::Vector2u{1, 2}); + this->placeText(text, this->playerCursor, "INVISIBLE", 25.f, 45.f, sf::Vector2u{1, 2}); + this->placeText(text, this->playerCursor, "ZEN", 50.f, 45.f, sf::Vector2u{2, 2}); this->renderWindow->display(); }