stats in-game
This commit is contained in:
@@ -92,8 +92,17 @@ Since we work with a great deal of different size and shapes, the rules for spin
|
|||||||
|
|
||||||
## Score calculation
|
## Score calculation
|
||||||
|
|
||||||
- For every position soft dropped, add 1 to the score
|
- When locking a piece, add 1 to the score if it is due to lock delay, or 10 if it was hard dropped.
|
||||||
- For every position hard dropped, add 2 to the score
|
|
||||||
- When clearing one line, add 100 to the score, 200 for 2 lines, 400 for 3 lines, 800 for 4 lines, 1600 for 5 lines, etc.
|
- When clearing one line, add 100 to the score, 200 for 2 lines, 400 for 3 lines, 800 for 4 lines, 1600 for 5 lines, etc.
|
||||||
- If the line clear is a spin, count the score like a normal clear of 2x more line (200 for 1-line spin, 800 for 2, 3200 for 3, etc.)
|
- If the line clear is a spin, count the score like a normal clear of 2x more line (200 for 1-line spin, 800 for 2, 3200 for 3, etc.)
|
||||||
- When performing a spin, a mini spin, or clearing 4 or more lines, B2B is activated, every subsequent line clear that is a spin, a mini spin, or clear 4 or more lines, scores twice as much
|
- When performing a spin, a mini spin, or clearing 4 or more lines, B2B is activated, every subsequent line clear that is a spin, a mini spin, or clear 4 or more lines, scores twice as much
|
||||||
|
|
||||||
|
## Grade calculation
|
||||||
|
|
||||||
|
Grade is an alternate system to line clears.
|
||||||
|
|
||||||
|
- Each time a piece is dropped, 1 point is added to the total.
|
||||||
|
- For each cleared line, 1 point is added to the total.
|
||||||
|
|
||||||
|
The only exception occurs when the total ends in '99', a line must be cleared to progress.
|
||||||
|
When this line is cleared, the point of the piece is also counted towards the total.
|
||||||
|
|||||||
@@ -9,8 +9,8 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
static const int SUBPX_PER_ROW = 60; // the number of position the active piece can take "between" two rows
|
static const int SUBPX_PER_ROW = 60; // the number of position the active piece can take "between" two rows
|
||||||
static const int SOFT_DROP_SCORE = 1; // the score gained by line soft dropped
|
static const int LOCK_DELAY_SCORE = 1; // the score gained when the piece locks due to lock delay
|
||||||
static const int HARD_DROP_SCORE = 2; // the score gained by line hard dropped
|
static const int HARD_DROP_SCORE = 10; // the score gained when the piece locks due to an hard drop
|
||||||
static const int LINE_CLEAR_BASE_SCORE = 100; // the score value of clearing a single line
|
static const int LINE_CLEAR_BASE_SCORE = 100; // the score value of clearing a single line
|
||||||
static const int B2B_SCORE_MULTIPLIER = 2; // by how much havaing B2B on multiplies the score of the line clear
|
static const int B2B_SCORE_MULTIPLIER = 2; // by how much havaing B2B on multiplies the score of the line clear
|
||||||
static const int B2B_MIN_LINE_NUMBER = 4; // the minimum number of lines needed to be cleared at once to gain B2B (without a spin)
|
static const int B2B_MIN_LINE_NUMBER = 4; // the minimum number of lines needed to be cleared at once to gain B2B (without a spin)
|
||||||
@@ -140,16 +140,14 @@ void Game::nextFrame(const std::set<Action>& playerActions) {
|
|||||||
|
|
||||||
// SDR=0 -> instant drop
|
// SDR=0 -> instant drop
|
||||||
if (appliedSDR == 0) {
|
if (appliedSDR == 0) {
|
||||||
while (this->board.moveDown()) {
|
while (this->board.moveDown());
|
||||||
this->score += SOFT_DROP_SCORE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// SDR>1 -> move down by specified amount
|
// SDR>1 -> move down by specified amount
|
||||||
else {
|
else {
|
||||||
this->subVerticalPosition += (SUBPX_PER_ROW / appliedSDR);
|
this->subVerticalPosition += (SUBPX_PER_ROW / appliedSDR);
|
||||||
while (this->subVerticalPosition >= SUBPX_PER_ROW) {
|
while (this->subVerticalPosition >= SUBPX_PER_ROW) {
|
||||||
|
this->board.moveDown();
|
||||||
this->subVerticalPosition -= SUBPX_PER_ROW;
|
this->subVerticalPosition -= SUBPX_PER_ROW;
|
||||||
this->score += (this->board.moveDown() * SOFT_DROP_SCORE);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -157,11 +155,10 @@ void Game::nextFrame(const std::set<Action>& playerActions) {
|
|||||||
/* HARD DROP */
|
/* HARD DROP */
|
||||||
// needs to be done last because we can enter ARE period afterwards
|
// needs to be done last because we can enter ARE period afterwards
|
||||||
if (this->initialActions.contains(HARD_DROP) || (playerActions.contains(HARD_DROP) && (!this->heldActions.contains(HARD_DROP)))) {
|
if (this->initialActions.contains(HARD_DROP) || (playerActions.contains(HARD_DROP) && (!this->heldActions.contains(HARD_DROP)))) {
|
||||||
while (this->board.moveDown()) {
|
while (this->board.moveDown());
|
||||||
this->score += HARD_DROP_SCORE;
|
|
||||||
}
|
|
||||||
this->lockPiece();
|
this->lockPiece();
|
||||||
pieceJustLocked = true;
|
pieceJustLocked = true;
|
||||||
|
this->score += HARD_DROP_SCORE;
|
||||||
}
|
}
|
||||||
// no need to apply gravity and lock delay if the piece was hard dropped
|
// no need to apply gravity and lock delay if the piece was hard dropped
|
||||||
else {
|
else {
|
||||||
@@ -192,6 +189,7 @@ void Game::nextFrame(const std::set<Action>& playerActions) {
|
|||||||
if ((this->totalLockDelay > this->parameters.getLockDelay()) || (this->totalForcedLockDelay > this->parameters.getForcedLockDelay())) {
|
if ((this->totalLockDelay > this->parameters.getLockDelay()) || (this->totalForcedLockDelay > this->parameters.getForcedLockDelay())) {
|
||||||
this->lockPiece();
|
this->lockPiece();
|
||||||
pieceJustLocked = true;
|
pieceJustLocked = true;
|
||||||
|
this->score += LOCK_DELAY_SCORE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -290,7 +288,7 @@ void Game::rotatePiece(Rotation rotation) {
|
|||||||
|
|
||||||
void Game::lockPiece() {
|
void Game::lockPiece() {
|
||||||
LineClear clear = this->board.lockPiece();
|
LineClear clear = this->board.lockPiece();
|
||||||
this->parameters.clearLines(clear.lines);
|
this->parameters.lockedPiece(clear);
|
||||||
|
|
||||||
bool B2BConditionsAreMet = ((clear.lines > B2B_MIN_LINE_NUMBER) || clear.isSpin || clear.isMiniSpin);
|
bool B2BConditionsAreMet = ((clear.lines > B2B_MIN_LINE_NUMBER) || clear.isSpin || clear.isMiniSpin);
|
||||||
if (clear.lines > 0) {
|
if (clear.lines > 0) {
|
||||||
@@ -330,6 +328,10 @@ int Game::getClearedLines() const {
|
|||||||
return this->parameters.getClearedLines();
|
return this->parameters.getClearedLines();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Game::getGrade() const {
|
||||||
|
return this->parameters.getGrade();
|
||||||
|
}
|
||||||
|
|
||||||
int Game::getLevel() const {
|
int Game::getLevel() const {
|
||||||
return this->parameters.getLevel();
|
return this->parameters.getLevel();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -101,6 +101,11 @@ class Game {
|
|||||||
*/
|
*/
|
||||||
int getClearedLines() const;
|
int getClearedLines() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The current grade
|
||||||
|
*/
|
||||||
|
int getGrade() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return The number of frames passed since the start of the game
|
* @return The number of frames passed since the start of the game
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ GameParameters::GameParameters(Gamemode gamemode, const Player& controls) :
|
|||||||
|
|
||||||
void GameParameters::reset() {
|
void GameParameters::reset() {
|
||||||
this->clearedLines = 0;
|
this->clearedLines = 0;
|
||||||
|
this->grade = 0;
|
||||||
|
|
||||||
switch (this->gamemode) {
|
switch (this->gamemode) {
|
||||||
// lowest gravity
|
// lowest gravity
|
||||||
case SPRINT : {this->level = 1; break;}
|
case SPRINT : {this->level = 1; break;}
|
||||||
@@ -30,13 +32,13 @@ void GameParameters::reset() {
|
|||||||
this->updateStats();
|
this->updateStats();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameParameters::clearLines(int lineNumber) {
|
void GameParameters::lockedPiece(const LineClear& lineClear) {
|
||||||
switch (this->gamemode) {
|
switch (this->gamemode) {
|
||||||
// modes where level increases
|
// modes where level increases
|
||||||
case MARATHON :
|
case MARATHON :
|
||||||
case MASTER : {
|
case MASTER : {
|
||||||
int previousLines = this->clearedLines;
|
int previousLines = this->clearedLines;
|
||||||
this->clearedLines += lineNumber;
|
this->clearedLines += lineClear.lines;
|
||||||
|
|
||||||
// level increments every 10 lines, stats only changes on level up
|
// level increments every 10 lines, stats only changes on level up
|
||||||
if (previousLines / 10 < this->clearedLines / 10) {
|
if (previousLines / 10 < this->clearedLines / 10) {
|
||||||
@@ -46,7 +48,11 @@ void GameParameters::clearLines(int lineNumber) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// other modes
|
// other modes
|
||||||
default : this->clearedLines += lineNumber;
|
default : this->clearedLines += lineClear.lines;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!((lineClear.lines == 0) && ((this->grade % 100) == 99))) {
|
||||||
|
this->grade += (1 + lineClear.lines);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -210,6 +216,10 @@ int GameParameters::getLevel() const {
|
|||||||
return this->level;
|
return this->level;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int GameParameters::getGrade() const {
|
||||||
|
return this->grade;
|
||||||
|
}
|
||||||
|
|
||||||
int GameParameters::getNextQueueLength() const {
|
int GameParameters::getNextQueueLength() const {
|
||||||
return this->nextQueueLength;
|
return this->nextQueueLength;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include "Gamemode.h"
|
#include "Gamemode.h"
|
||||||
#include "Player.h"
|
#include "Player.h"
|
||||||
|
#include "LineClear.h"
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -14,6 +15,7 @@ class GameParameters {
|
|||||||
Player controls; // the player's controls
|
Player controls; // the player's controls
|
||||||
int clearedLines; // the number of cleared lines
|
int clearedLines; // the number of cleared lines
|
||||||
int level; // the current level
|
int level; // the current level
|
||||||
|
int grade; // the current amount of points
|
||||||
int nextQueueLength; // the number of pieces visibles in the next queue
|
int nextQueueLength; // the number of pieces visibles in the next queue
|
||||||
bool boneBlocks; // wheter all blocks are bone blocks
|
bool boneBlocks; // wheter all blocks are bone blocks
|
||||||
int gravity; // the gravity at which pieces drop
|
int gravity; // the gravity at which pieces drop
|
||||||
@@ -39,7 +41,7 @@ class GameParameters {
|
|||||||
/**
|
/**
|
||||||
* Counts the newly cleared lines and update level and stats if needed
|
* Counts the newly cleared lines and update level and stats if needed
|
||||||
*/
|
*/
|
||||||
void clearLines(int lineNumber);
|
void lockedPiece(const LineClear& lineClear);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if the game ended based on the current states and time passed, accorind to the gamemode
|
* Checks if the game ended based on the current states and time passed, accorind to the gamemode
|
||||||
@@ -63,6 +65,11 @@ class GameParameters {
|
|||||||
* @return The current level
|
* @return The current level
|
||||||
*/
|
*/
|
||||||
int getLevel() const;
|
int getLevel() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The current grade
|
||||||
|
*/
|
||||||
|
int getGrade() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return The length of the next queue
|
* @return The length of the next queue
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Every gamemode supported by the game
|
* Every gamemode supported by the game
|
||||||
@@ -11,3 +13,34 @@ enum Gamemode {
|
|||||||
MASTER,
|
MASTER,
|
||||||
ZEN
|
ZEN
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return A string containing the name of the gamemode
|
||||||
|
*/
|
||||||
|
inline std::string getGamemodeName(Gamemode gamemode) {
|
||||||
|
static const std::string GAMEMODE_NAMES[] = {
|
||||||
|
"SPRINT",
|
||||||
|
"MARATHON",
|
||||||
|
"ULTRA",
|
||||||
|
"MASTER",
|
||||||
|
"ZEN"
|
||||||
|
};
|
||||||
|
|
||||||
|
return GAMEMODE_NAMES[gamemode];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return A tiny string containing the goal of the gamemode
|
||||||
|
*/
|
||||||
|
inline std::string getGamemodeGoal(Gamemode gamemode) {
|
||||||
|
static const std::string GAMEMODE_DESCRIPTIONS[] = {
|
||||||
|
"40 lines",
|
||||||
|
"200 lines",
|
||||||
|
"2 minutes",
|
||||||
|
"200 lines",
|
||||||
|
"Chill"
|
||||||
|
};
|
||||||
|
|
||||||
|
return GAMEMODE_DESCRIPTIONS[gamemode];
|
||||||
|
}
|
||||||
|
|||||||
@@ -64,9 +64,6 @@ class AppMenu {
|
|||||||
if (playerCursor.has_value() && cursorPos.has_value()) {
|
if (playerCursor.has_value() && cursorPos.has_value()) {
|
||||||
text.setOutlineThickness((playerCursor.value().getPosition() == cursorPos.value()) ? (sizeMultiplier / 2) : 0);
|
text.setOutlineThickness((playerCursor.value().getPosition() == cursorPos.value()) ? (sizeMultiplier / 2) : 0);
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
text.setOutlineThickness(0);
|
|
||||||
}
|
|
||||||
text.setOrigin(sf::Vector2f({0, text.getLocalBounds().size.y / 2}));
|
text.setOrigin(sf::Vector2f({0, text.getLocalBounds().size.y / 2}));
|
||||||
text.setPosition(sf::Vector2f({sizeMultiplier * xPos, sizeMultiplier * yPos}));
|
text.setPosition(sf::Vector2f({sizeMultiplier * xPos, sizeMultiplier * yPos}));
|
||||||
this->renderWindow->draw(text);
|
this->renderWindow->draw(text);
|
||||||
@@ -79,9 +76,6 @@ class AppMenu {
|
|||||||
if (playerCursor.has_value() && cursorPos.has_value()) {
|
if (playerCursor.has_value() && cursorPos.has_value()) {
|
||||||
text.setOutlineThickness((playerCursor.value().getPosition() == cursorPos.value()) ? (sizeMultiplier / 2) : 0);
|
text.setOutlineThickness((playerCursor.value().getPosition() == cursorPos.value()) ? (sizeMultiplier / 2) : 0);
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
text.setOutlineThickness(0);
|
|
||||||
}
|
|
||||||
text.setOrigin({text.getLocalBounds().getCenter().x, text.getLocalBounds().size.y / 2});
|
text.setOrigin({text.getLocalBounds().getCenter().x, text.getLocalBounds().size.y / 2});
|
||||||
text.setPosition(sf::Vector2f({sizeMultiplier * 40.f, sizeMultiplier * yPos}));
|
text.setPosition(sf::Vector2f({sizeMultiplier * 40.f, sizeMultiplier * yPos}));
|
||||||
this->renderWindow->draw(text);
|
this->renderWindow->draw(text);
|
||||||
|
|||||||
@@ -6,14 +6,17 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
#include <string>
|
||||||
#include <SFML/Graphics.hpp>
|
#include <SFML/Graphics.hpp>
|
||||||
|
|
||||||
|
static const int TIME_BEFORE_STARTING = 60;
|
||||||
|
|
||||||
|
|
||||||
GamePlayingAppMenu::GamePlayingAppMenu(std::shared_ptr<MenuStack> menuStack, std::shared_ptr<Settings> settings, std::shared_ptr<sf::RenderWindow> renderWindow) :
|
GamePlayingAppMenu::GamePlayingAppMenu(std::shared_ptr<MenuStack> menuStack, std::shared_ptr<Settings> settings, std::shared_ptr<sf::RenderWindow> renderWindow) :
|
||||||
AppMenu(menuStack, settings, renderWindow),
|
AppMenu(menuStack, settings, renderWindow),
|
||||||
game(this->settings->getMenu().startGame(this->settings->getGamemode())) {
|
game(this->settings->getMenu().startGame(this->settings->getGamemode())) {
|
||||||
|
|
||||||
this->game.start();
|
this->startTimer = TIME_BEFORE_STARTING;
|
||||||
this->paused = false;
|
this->paused = false;
|
||||||
this->pausePressed = false;
|
this->pausePressed = false;
|
||||||
this->retryPressed = false;
|
this->retryPressed = false;
|
||||||
@@ -24,14 +27,14 @@ GamePlayingAppMenu::GamePlayingAppMenu(std::shared_ptr<MenuStack> menuStack, std
|
|||||||
|
|
||||||
float boardWidth = this->game.getBoard().getWidth() * this->cellSizeZoom;
|
float boardWidth = this->game.getBoard().getWidth() * this->cellSizeZoom;
|
||||||
float boardHeight = (this->game.getBoard().getBaseHeight() + 10) * this->cellSizeZoom;
|
float boardHeight = (this->game.getBoard().getBaseHeight() + 10) * this->cellSizeZoom;
|
||||||
this->boardPosition = sf::Rect<float>(sf::Vector2f((this->settings->getWindowSizeMultiplier() * 40) - (boardWidth / 2),
|
this->boardPosition = sf::FloatRect(sf::Vector2f((this->settings->getWindowSizeMultiplier() * 40) - (boardWidth / 2),
|
||||||
(this->settings->getWindowSizeMultiplier() * 25) - (boardHeight / 2)),
|
(this->settings->getWindowSizeMultiplier() * 25) - (boardHeight / 2)),
|
||||||
sf::Vector2f(boardWidth, boardHeight));
|
sf::Vector2f(boardWidth, boardHeight));
|
||||||
|
|
||||||
|
|
||||||
for (int i = 0; i < 5; i++) {
|
for (int i = 0; i < 5; i++) {
|
||||||
this->nextQueuePosition[i] = sf::Rect<float>(sf::Vector2f(this->boardPosition.position.x + boardWidth + (5.f * this->settings->getWindowSizeMultiplier()), (1.f + (10.f * i)) * this->settings->getWindowSizeMultiplier()),
|
this->nextQueuePosition[i] = sf::FloatRect(sf::Vector2f(this->boardPosition.position.x + boardWidth + (5.f * this->settings->getWindowSizeMultiplier()), (10.f + (10.f * i)) * this->settings->getWindowSizeMultiplier()),
|
||||||
sf::Vector2f(8.f * this->settings->getWindowSizeMultiplier(), 8.f * this->settings->getWindowSizeMultiplier()));
|
sf::Vector2f(8.f * this->settings->getWindowSizeMultiplier(), 8.f * this->settings->getWindowSizeMultiplier()));
|
||||||
}
|
}
|
||||||
|
|
||||||
this->nextCellSizeZoom = this->nextQueuePosition[0].size.y;
|
this->nextCellSizeZoom = this->nextQueuePosition[0].size.y;
|
||||||
@@ -40,14 +43,21 @@ GamePlayingAppMenu::GamePlayingAppMenu(std::shared_ptr<MenuStack> menuStack, std
|
|||||||
this->nextCellSizeZoom = std::min(this->nextCellSizeZoom, nextPieceCellSizeZoom);
|
this->nextCellSizeZoom = std::min(this->nextCellSizeZoom, nextPieceCellSizeZoom);
|
||||||
}
|
}
|
||||||
|
|
||||||
this->holdBoxPosition = sf::Rect<float>(sf::Vector2f(this->boardPosition.position.x - ((8.f + 5.f) * this->settings->getWindowSizeMultiplier()), (11.f) * this->settings->getWindowSizeMultiplier()),
|
this->holdBoxPosition = sf::FloatRect(sf::Vector2f(this->boardPosition.position.x - ((8.f + 5.f) * this->settings->getWindowSizeMultiplier()), (10.f) * this->settings->getWindowSizeMultiplier()),
|
||||||
sf::Vector2f(8.f * this->settings->getWindowSizeMultiplier(), 8.f * this->settings->getWindowSizeMultiplier()));
|
sf::Vector2f(8.f * this->settings->getWindowSizeMultiplier(), 8.f * this->settings->getWindowSizeMultiplier()));
|
||||||
this->holdCellSizeZoom = this->nextCellSizeZoom;
|
this->holdCellSizeZoom = this->nextCellSizeZoom;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GamePlayingAppMenu::computeFrame() {
|
void GamePlayingAppMenu::computeFrame() {
|
||||||
this->updateMetaBinds();
|
this->updateMetaBinds();
|
||||||
|
|
||||||
|
if (this->startTimer > 0) {
|
||||||
|
this->startTimer--;
|
||||||
|
if (this->startTimer == 0) {
|
||||||
|
this->game.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (this->escReleased) {
|
if (this->escReleased) {
|
||||||
this->menuStack->pop();
|
this->menuStack->pop();
|
||||||
}
|
}
|
||||||
@@ -67,7 +77,7 @@ void GamePlayingAppMenu::computeFrame() {
|
|||||||
else {
|
else {
|
||||||
if (this->retryPressed) {
|
if (this->retryPressed) {
|
||||||
this->game.reset();
|
this->game.reset();
|
||||||
this->game.start();
|
this->startTimer = TIME_BEFORE_STARTING;
|
||||||
}
|
}
|
||||||
this->retryPressed = false;
|
this->retryPressed = false;
|
||||||
}
|
}
|
||||||
@@ -153,32 +163,40 @@ void GamePlayingAppMenu::drawFrame() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// next queue
|
// next queue
|
||||||
|
int upShift = 0;
|
||||||
for (int i = 0; i < std::min((int) this->game.getNextPieces().size(), 5); i++) {
|
for (int i = 0; i < std::min((int) this->game.getNextPieces().size(), 5); i++) {
|
||||||
|
sf::FloatRect nextBox = this->nextQueuePosition[i];
|
||||||
|
nextBox.position.y -= upShift;
|
||||||
|
|
||||||
sf::Vector2f nextCellSize(this->nextCellSizeZoom, this->nextCellSizeZoom);
|
sf::Vector2f nextCellSize(this->nextCellSizeZoom, this->nextCellSizeZoom);
|
||||||
sf::Color color = this->getColorOfBlock(this->game.getNextPieces().at(i).getBlockType(), 0);
|
sf::Color color = this->getColorOfBlock(this->game.getNextPieces().at(i).getBlockType(), 0);
|
||||||
sf::Color boxColor = sf::Color(150, 150, 150);
|
sf::Color boxColor = sf::Color(180, 180, 180);
|
||||||
|
|
||||||
|
int lowestRank = 0;
|
||||||
for (int y = 0; y < this->game.getNextPieces().at(i).getLength(); y++) {
|
for (int y = 0; y < this->game.getNextPieces().at(i).getLength(); y++) {
|
||||||
for (int x = 0; x < this->game.getNextPieces().at(i).getLength(); x++) {
|
for (int x = 0; x < this->game.getNextPieces().at(i).getLength(); x++) {
|
||||||
sf::RectangleShape cell(nextCellSize);
|
sf::RectangleShape cell(nextCellSize);
|
||||||
if (this->game.getNextPieces().at(i).getPositions().contains(Position{x, y})) {
|
if (this->game.getNextPieces().at(i).getPositions().contains(Position{x, y})) {
|
||||||
cell.setFillColor(color);
|
cell.setFillColor(color);
|
||||||
|
lowestRank = y;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
cell.setFillColor(boxColor);
|
cell.setFillColor(boxColor);
|
||||||
}
|
}
|
||||||
cell.setPosition(sf::Vector2f(this->nextQueuePosition[i].position.x + (x * this->nextCellSizeZoom),
|
cell.setPosition(sf::Vector2f(nextBox.position.x + (x * this->nextCellSizeZoom),
|
||||||
this->nextQueuePosition[i].position.y + ((this->game.getNextPieces().at(i).getLength() - y - 1) * this->nextCellSizeZoom)));
|
nextBox.position.y + ((this->game.getNextPieces().at(i).getLength() - y - 1) * this->nextCellSizeZoom)));
|
||||||
this->renderWindow->draw(cell);
|
this->renderWindow->draw(cell);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
upShift += nextBox.size.y - (this->game.getNextPieces().at(i).getLength() * this->nextCellSizeZoom);
|
||||||
}
|
}
|
||||||
|
|
||||||
// hold box
|
// hold box
|
||||||
if (this->game.getHeldPiece() != nullptr) {
|
if (this->game.getHeldPiece() != nullptr) {
|
||||||
sf::Vector2f holdCellSize(this->holdCellSizeZoom, this->holdCellSizeZoom);
|
sf::Vector2f holdCellSize(this->holdCellSizeZoom, this->holdCellSizeZoom);
|
||||||
sf::Color color = this->getColorOfBlock(this->game.getHeldPiece()->getBlockType(), 0);
|
sf::Color color = this->getColorOfBlock(this->game.getHeldPiece()->getBlockType(), 0);
|
||||||
sf::Color boxColor = sf::Color(150, 150, 150);
|
sf::Color boxColor = sf::Color(180, 180, 180);
|
||||||
|
|
||||||
for (int y = 0; y < this->game.getHeldPiece()->getLength(); y++) {
|
for (int y = 0; y < this->game.getHeldPiece()->getLength(); y++) {
|
||||||
for (int x = 0; x < this->game.getHeldPiece()->getLength(); x++) {
|
for (int x = 0; x < this->game.getHeldPiece()->getLength(); x++) {
|
||||||
@@ -196,6 +214,51 @@ void GamePlayingAppMenu::drawFrame() const {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// stats
|
||||||
|
int windowSizeMultiplier = this->settings->getWindowSizeMultiplier();
|
||||||
|
int fontSize = (this->boardPosition.size.x > (windowSizeMultiplier * 30.f)) ? (windowSizeMultiplier) : (windowSizeMultiplier * 2);
|
||||||
|
sf::Text text(this->pressStartFont, "", fontSize);
|
||||||
|
text.setFillColor(sf::Color(0, 0, 0));
|
||||||
|
|
||||||
|
int millisecondes = this->game.getFramesPassed() * (1000.f / FRAMES_PER_SECOND);
|
||||||
|
std::string showedMillisecondes = std::to_string(millisecondes % 1000);
|
||||||
|
while (showedMillisecondes.size() < 3) {
|
||||||
|
showedMillisecondes = "0" + showedMillisecondes;
|
||||||
|
}
|
||||||
|
std::string showedSecondes = std::to_string((millisecondes / 1000) % 60);
|
||||||
|
while (showedSecondes.size() < 2) {
|
||||||
|
showedSecondes = "0" + showedSecondes;
|
||||||
|
}
|
||||||
|
std::string showedMinutes = std::to_string((millisecondes / (60 * 1000)));
|
||||||
|
std::string showedTime = showedMinutes + ":" + showedSecondes + "." + showedMillisecondes;
|
||||||
|
|
||||||
|
this->placeText(text, {}, getGamemodeName(this->settings->getGamemode()), 1.f, 3.f, {});
|
||||||
|
this->placeText(text, {}, getGamemodeGoal(this->settings->getGamemode()), 1.f, 6.f, {});
|
||||||
|
|
||||||
|
this->placeText(text, {}, "LINES:" + std::to_string(this->game.getClearedLines()), 1.f, 25.f, {});
|
||||||
|
this->placeText(text, {}, "LEVEL:" + std::to_string(this->game.getLevel()), 1.f, 30.f, {});
|
||||||
|
this->placeText(text, {}, "SCORE:" + std::to_string(this->game.getScore()), 1.f, 35.f, {});
|
||||||
|
this->placeText(text, {}, "GRADE:" + std::to_string(this->game.getGrade()), 1.f, 40.f, {});
|
||||||
|
this->placeText(text, {}, showedTime, 1.f, 45.f, {});
|
||||||
|
|
||||||
|
// game state
|
||||||
|
text.setOutlineColor(sf::Color(255, 255, 255));
|
||||||
|
text.setOutlineThickness(windowSizeMultiplier / 2.f);
|
||||||
|
|
||||||
|
if (this->game.hasWon()) {
|
||||||
|
this->placeTitle(text, {}, "WIN", 25.f, {});
|
||||||
|
}
|
||||||
|
else if (this->game.hasLost()) {
|
||||||
|
this->placeTitle(text, {}, "LOSE", 25.f, {});
|
||||||
|
}
|
||||||
|
else if (this->paused) {
|
||||||
|
this->placeTitle(text, {}, "PAUSE", 25.f, {});
|
||||||
|
}
|
||||||
|
else if (this->startTimer > 0) {
|
||||||
|
text.setCharacterSize(windowSizeMultiplier * 4);
|
||||||
|
this->placeTitle(text, {}, std::to_string(((this->startTimer - 1) / (TIME_BEFORE_STARTING / 4))), 25.f, {});
|
||||||
|
}
|
||||||
|
|
||||||
this->renderWindow->display();
|
this->renderWindow->display();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,14 +10,15 @@
|
|||||||
class GamePlayingAppMenu : public AppMenu {
|
class GamePlayingAppMenu : public AppMenu {
|
||||||
private:
|
private:
|
||||||
Game game;
|
Game game;
|
||||||
|
int startTimer;
|
||||||
bool paused;
|
bool paused;
|
||||||
bool pausePressed;
|
bool pausePressed;
|
||||||
bool retryPressed;
|
bool retryPressed;
|
||||||
sf::Rect<float> boardPosition;
|
sf::FloatRect boardPosition;
|
||||||
float cellSizeZoom;
|
float cellSizeZoom;
|
||||||
sf::Rect<float> holdBoxPosition;
|
sf::FloatRect holdBoxPosition;
|
||||||
float holdCellSizeZoom;
|
float holdCellSizeZoom;
|
||||||
sf::Rect<float> nextQueuePosition[5];
|
sf::FloatRect nextQueuePosition[5];
|
||||||
float nextCellSizeZoom;
|
float nextCellSizeZoom;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ InfoAppMenu::InfoAppMenu(std::shared_ptr<MenuStack> menuStack, std::shared_ptr<S
|
|||||||
"The rotation center is always the\n"
|
"The rotation center is always the\n"
|
||||||
"center of the piece by default.\n"
|
"center of the piece by default.\n"
|
||||||
"When kicking the piece, it will\n"
|
"When kicking the piece, it will\n"
|
||||||
"compute and try every position that\n"
|
"compute and try (most) position that\n"
|
||||||
"touches the original piece,\n"
|
"touches the original piece,\n"
|
||||||
"prioritizing sides over depth and\n"
|
"prioritizing sides over depth and\n"
|
||||||
"firstly going down before going up.",
|
"firstly going down before going up.",
|
||||||
|
|||||||
@@ -112,6 +112,7 @@ void SettingsKeybindsAppMenu::drawFrame() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this->placeText(text, this->playerCursor, setStringToUpperCase(ACTION_NAMES[action]), 15.f, ((i - firstElem) * 10) + 25.f, sf::Vector2u{0, (unsigned int) i + 1});
|
this->placeText(text, this->playerCursor, setStringToUpperCase(ACTION_NAMES[action]), 15.f, ((i - firstElem) * 10) + 25.f, sf::Vector2u{0, (unsigned int) i + 1});
|
||||||
|
text.setOutlineThickness(0);
|
||||||
this->placeText(text, {}, string, 40.f, ((i - firstElem) * 10) + 25.f, {});
|
this->placeText(text, {}, string, 40.f, ((i - firstElem) * 10) + 25.f, {});
|
||||||
|
|
||||||
sf::Sprite sprite(this->iconTextures[action]);
|
sf::Sprite sprite(this->iconTextures[action]);
|
||||||
|
|||||||
Reference in New Issue
Block a user