Started fixing positioning and scaling making it more accurate to the original
This commit is contained in:
@@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
## TODO
|
## TODO
|
||||||
|
|
||||||
- Game Over screen
|
|
||||||
- Add Gamemodes
|
- Add Gamemodes
|
||||||
- Gamemode selection screen
|
- Gamemode selection screen
|
||||||
- Save score
|
- Save score
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 10 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 9.1 KiB After Width: | Height: | Size: 4.8 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 4.8 KiB |
12
src/Game.cpp
12
src/Game.cpp
@@ -45,7 +45,6 @@ void Game::run( ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sound->PlayMusic(MusicName::MAIN_THEME);
|
sound->PlayMusic(MusicName::MAIN_THEME);
|
||||||
|
|
||||||
lastUpdateTime = SDL_GetTicks( );
|
lastUpdateTime = SDL_GetTicks( );
|
||||||
while (!gameState.gameover && !gameBoard->isCollision( )) {
|
while (!gameState.gameover && !gameBoard->isCollision( )) {
|
||||||
if (gameState.quit) return;
|
if (gameState.quit) return;
|
||||||
@@ -57,7 +56,6 @@ void Game::run( ) {
|
|||||||
gameState.gameover = true;
|
gameState.gameover = true;
|
||||||
sound->PauseMusic( );
|
sound->PauseMusic( );
|
||||||
sound->PlaySound(SoundName::GAME_OVER);
|
sound->PlaySound(SoundName::GAME_OVER);
|
||||||
|
|
||||||
while (gameState.gameover) {
|
while (gameState.gameover) {
|
||||||
if (gameState.quit) return;
|
if (gameState.quit) return;
|
||||||
SDL_SetRenderDrawColor(renderer.get( ), 248, 248, 248, 255);
|
SDL_SetRenderDrawColor(renderer.get( ), 248, 248, 248, 255);
|
||||||
@@ -124,10 +122,7 @@ void Game::inputHandler( ) {
|
|||||||
Mix_VolumeMusic(Mix_GetMusicVolume(bgm.get( )) - 8);
|
Mix_VolumeMusic(Mix_GetMusicVolume(bgm.get( )) - 8);
|
||||||
break;
|
break;
|
||||||
case SDLK_m:
|
case SDLK_m:
|
||||||
if (true)
|
sound->IsMusicPlaying( ) ? sound->PauseMusic( ) : sound->ResumeMusic( );
|
||||||
sound->ResumeMusic( );
|
|
||||||
else
|
|
||||||
sound->PauseMusic( );
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@@ -154,11 +149,8 @@ void Game::handleWindowResize( ) {
|
|||||||
int windowWidth, windowHeight;
|
int windowWidth, windowHeight;
|
||||||
SDL_GetWindowSize(window.get( ), &windowWidth, &windowHeight);
|
SDL_GetWindowSize(window.get( ), &windowWidth, &windowHeight);
|
||||||
|
|
||||||
gameRenderer->setBlockSize(windowHeight / gameBoard->getHeight( ));
|
//gameRenderer->setScale(windowHeight / gameBoard->getHeight( ));
|
||||||
|
|
||||||
int offsetX = (windowWidth - gameBoard->getWidth( ) * gameRenderer->getBlockSize( )) / 2;
|
|
||||||
int offsetY = (windowHeight - gameBoard->getHeight( ) * gameRenderer->getBlockSize( )) / 2;
|
|
||||||
gameRenderer->setOffset(offsetX, offsetY);
|
|
||||||
|
|
||||||
gameRenderer->setWindowSize(windowWidth, windowHeight);
|
gameRenderer->setWindowSize(windowWidth, windowHeight);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,6 +34,8 @@ private:
|
|||||||
|
|
||||||
struct GameState {
|
struct GameState {
|
||||||
bool gameover = false;
|
bool gameover = false;
|
||||||
|
bool singlePlayer = false;
|
||||||
|
bool multiPlayer = false;
|
||||||
bool startSequence = false;
|
bool startSequence = false;
|
||||||
bool quit = false;
|
bool quit = false;
|
||||||
} gameState;
|
} gameState;
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
GameBoard::GameBoard( )
|
GameBoard::GameBoard( )
|
||||||
: lockedTetrominos(20, vector<int>(10, 0)),
|
: lockedTetrominos(18, vector<int>(10, 0)),
|
||||||
lockedColors(20, std::vector<SDL_Color>(10, { 0, 0, 0, 255 })), score(0), level(0), lines(0), collision(false),
|
lockedColors(18, std::vector<SDL_Color>(10, { 0, 0, 0, 255 })), score(0), level(0), lines(0), collision(false),
|
||||||
sound(make_unique<Sound>( )) {
|
sound(make_unique<Sound>( )) {
|
||||||
spawnNewTetromino( );
|
spawnNewTetromino( );
|
||||||
}
|
}
|
||||||
@@ -162,7 +162,7 @@ void GameBoard::spawnNewTetromino( ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
currentTetromino = move(nextTetromino);
|
currentTetromino = move(nextTetromino);
|
||||||
currentTetromino->move(width / 2 - 1, 0);
|
currentTetromino->move(4, 0);
|
||||||
|
|
||||||
// Generate next tetromino
|
// Generate next tetromino
|
||||||
random_device dev;
|
random_device dev;
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ private:
|
|||||||
shared_ptr<Tetromino> currentTetromino;
|
shared_ptr<Tetromino> currentTetromino;
|
||||||
shared_ptr<Tetromino> nextTetromino;
|
shared_ptr<Tetromino> nextTetromino;
|
||||||
const int width = 10;
|
const int width = 10;
|
||||||
const int height = 20;
|
const int height = 18;
|
||||||
bool collision;
|
bool collision;
|
||||||
int score;
|
int score;
|
||||||
int level;
|
int level;
|
||||||
@@ -36,7 +36,7 @@ public:
|
|||||||
bool tryMoveCurrentTetromino(int dx, int dy);
|
bool tryMoveCurrentTetromino(int dx, int dy);
|
||||||
bool tryRotateCurrentTetromino( );
|
bool tryRotateCurrentTetromino( );
|
||||||
bool isValidPosition(const vector<vector<int>>& shape, int x, int y) const;
|
bool isValidPosition(const vector<vector<int>>& shape, int x, int y) const;
|
||||||
bool moveToBottom( );
|
void moveToBottom( );
|
||||||
|
|
||||||
const bool isCollision( ) const;
|
const bool isCollision( ) const;
|
||||||
const int getScore( ) const;
|
const int getScore( ) const;
|
||||||
|
|||||||
277
src/Renderer.cpp
277
src/Renderer.cpp
@@ -1,7 +1,8 @@
|
|||||||
#include "Renderer.hpp"
|
#include "Renderer.hpp"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
Renderer::Renderer(shared_ptr<SDL_Renderer> renderer, int w, int h) : renderer(renderer), blockSize(30), windowHeight(h), windowWidth(w) {
|
Renderer::Renderer(shared_ptr<SDL_Renderer> renderer, int w, int h) : renderer(renderer), windowHeight(h), windowWidth(w) {
|
||||||
textures[TetrisAssets::SINGLE] = "assets/sprites/single.png";
|
textures[TetrisAssets::SINGLE] = "assets/sprites/single.png";
|
||||||
textures[TetrisAssets::BORDER] = "assets/sprites/border.png";
|
textures[TetrisAssets::BORDER] = "assets/sprites/border.png";
|
||||||
textures[TetrisAssets::J] = "assets/sprites/J.png";
|
textures[TetrisAssets::J] = "assets/sprites/J.png";
|
||||||
@@ -20,33 +21,80 @@ Renderer::Renderer(shared_ptr<SDL_Renderer> renderer, int w, int h) : renderer(r
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::renderBoard(const shared_ptr<GameBoard> gameBoard) {
|
void Renderer::renderBoard(const shared_ptr<GameBoard> gameBoard) {
|
||||||
|
drawScoreboard(gameBoard->getScore( ), gameBoard->getLevel( ), gameBoard->getLines( ));
|
||||||
drawWall(gameBoard->getWidth( ), gameBoard->getHeight( ));
|
drawWall(gameBoard->getWidth( ), gameBoard->getHeight( ));
|
||||||
drawLockedBlocks(gameBoard);
|
drawLockedBlocks(gameBoard);
|
||||||
drawTetromino(gameBoard->getCurrentTetromino( ));
|
drawTetromino(gameBoard->getCurrentTetromino( ));
|
||||||
drawScoreboard(gameBoard->getScore( ), gameBoard->getLevel( ), gameBoard->getLines( ));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::drawScoreboard(int score, int level, int lines) {
|
void Renderer::drawScoreboard(int score, int level, int lines) {
|
||||||
// 6 Because the gameBoard is 10 blocks, half that is 5 + 1 for the wall = 6
|
SDL_Rect blackRect = { 0, 0, 7 * scale, windowHeight };
|
||||||
SDL_Rect blackRect = { 0, 0, (windowWidth / 2) - (blockSize * 6) - blockSize / 8, windowHeight };
|
|
||||||
SDL_SetRenderDrawColor(renderer.get( ), 0, 0, 0, 255);
|
SDL_SetRenderDrawColor(renderer.get( ), 0, 0, 0, 255);
|
||||||
SDL_RenderFillRect(renderer.get( ), &blackRect);
|
SDL_RenderFillRect(renderer.get( ), &blackRect);
|
||||||
|
SDL_Color col{ 255,255,255 };
|
||||||
auto surf = unique_ptr<SDL_Surface, decltype(&SDL_FreeSurface)>(IMG_Load("assets/sprites/scoreboard.png"), SDL_FreeSurface);
|
auto surf = unique_ptr<SDL_Surface, decltype(&SDL_FreeSurface)>(IMG_Load("assets/sprites/scoreboard.png"), SDL_FreeSurface);
|
||||||
renderTexture("assets/sprites/scoreboard.png", windowWidth - surf->w * static_cast<float>(windowHeight) / surf->h, 0, surf->w * static_cast<float>(windowHeight) / surf->h, windowHeight);
|
scoreBoardDimensions = renderTexture(
|
||||||
|
"assets/sprites/scoreboard.png",
|
||||||
|
windowWidth,
|
||||||
|
0,
|
||||||
|
surf->w * scale,
|
||||||
|
surf->h * scale,
|
||||||
|
col,
|
||||||
|
1.0f,
|
||||||
|
HAlign::RIGHT
|
||||||
|
);
|
||||||
|
|
||||||
renderText(fmt::format("{0}", score), windowWidth - 30, 97, 32, SDL_Color{ 0,0,0 }, HAlign::RIGHT);
|
renderText(
|
||||||
renderText(fmt::format("{0}", level), windowWidth - 92, 230, 32, SDL_Color{ 0,0,0 });
|
fmt::format("{0}", score),
|
||||||
renderText(fmt::format("{0}", lines), windowWidth - 92, 330, 32, SDL_Color{ 0,0,0 });
|
windowWidth - (7 * scale),
|
||||||
|
23 * scale,
|
||||||
|
8 * scale,
|
||||||
|
SDL_Color{ 0,0,0 },
|
||||||
|
HAlign::RIGHT,
|
||||||
|
VAlign::TOP
|
||||||
|
);
|
||||||
|
renderText(
|
||||||
|
fmt::format("{0}", level),
|
||||||
|
windowWidth - (15 * scale),
|
||||||
|
55 * scale,
|
||||||
|
8 * scale,
|
||||||
|
SDL_Color{ 0,0,0 },
|
||||||
|
HAlign::RIGHT,
|
||||||
|
VAlign::TOP
|
||||||
|
);
|
||||||
|
renderText(
|
||||||
|
fmt::format("{0}", lines),
|
||||||
|
windowWidth - (15 * scale),
|
||||||
|
79 * scale,
|
||||||
|
8 * scale,
|
||||||
|
SDL_Color{ 0,0,0 },
|
||||||
|
HAlign::RIGHT,
|
||||||
|
VAlign::TOP
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::drawWall(const int w, const int h) {
|
void Renderer::drawWall(const int w, const int h) {
|
||||||
int innerBorderThickness = blockSize / 4;
|
SDL_Color color{ 165, 42, 42 }, gapColor{ 0,0,0 };
|
||||||
|
SDL_SetRenderDrawColor(renderer.get( ), color.r, color.g, color.b, 255);
|
||||||
|
|
||||||
for (int y = 0; y < (h + (innerBorderThickness * h)); ++y) {
|
for (int y = 0; y <= windowHeight; y += ((gridSize - 2) * scale)) {
|
||||||
SDL_Color color{ 165, 42, 42 };
|
leftBorder = renderTexture(
|
||||||
renderTexture(textures[TetrisAssets::BORDER], offsetX - blockSize, (offsetY + y * blockSize) - (innerBorderThickness * y + 1), blockSize, blockSize, color);
|
textures[TetrisAssets::BORDER],
|
||||||
renderTexture(textures[TetrisAssets::BORDER], offsetX + w * blockSize, (offsetY + y * blockSize) - (innerBorderThickness * y + 1), blockSize, blockSize, color);
|
gridSize * scale,
|
||||||
|
y,
|
||||||
|
gridSize * scale,
|
||||||
|
(gridSize * scale),
|
||||||
|
color
|
||||||
|
);
|
||||||
|
int t = ceil(static_cast<float>(scoreBoardDimensions->w) / scale / gridSize);
|
||||||
|
rightBorder = renderTexture(
|
||||||
|
textures[TetrisAssets::BORDER],
|
||||||
|
windowWidth - (ceil(static_cast<float>(scoreBoardDimensions->w) / scale / gridSize) + 1) * 8 * scale,
|
||||||
|
y,
|
||||||
|
gridSize * scale,
|
||||||
|
gridSize * scale,
|
||||||
|
color
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,10 +109,10 @@ void Renderer::drawLockedBlocks(const shared_ptr<GameBoard> gameBoard) {
|
|||||||
SDL_Color color = lockedColors[row][col];
|
SDL_Color color = lockedColors[row][col];
|
||||||
renderTexture(
|
renderTexture(
|
||||||
textures[shapeToAsset(static_cast<TetrominoShape>(blockType - 1))],
|
textures[shapeToAsset(static_cast<TetrominoShape>(blockType - 1))],
|
||||||
offsetX + col * blockSize,
|
(col + 2) * gridSize * scale,
|
||||||
offsetY + row * blockSize,
|
row * gridSize * scale,
|
||||||
blockSize,
|
gridSize * scale,
|
||||||
blockSize,
|
gridSize * scale,
|
||||||
color);
|
color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -83,60 +131,60 @@ void Renderer::drawTetromino(const shared_ptr<Tetromino> tetromino) {
|
|||||||
for (int i = 0; i < 4; ++i) {
|
for (int i = 0; i < 4; ++i) {
|
||||||
renderTexture(
|
renderTexture(
|
||||||
textures[TetrisAssets::I_MIDR],
|
textures[TetrisAssets::I_MIDR],
|
||||||
offsetX + (x + i) * blockSize,
|
(2 + x + i) * gridSize * scale,
|
||||||
offsetY + y * blockSize,
|
y * gridSize * scale,
|
||||||
blockSize,
|
gridSize * scale,
|
||||||
blockSize,
|
gridSize * scale,
|
||||||
tetromino->getColor( )
|
tetromino->getColor( )
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
renderTexture(
|
renderTexture(
|
||||||
textures[TetrisAssets::I_ENDR],
|
textures[TetrisAssets::I_ENDR],
|
||||||
offsetX + (x + 0) * blockSize,
|
(2 + x) * gridSize * scale,
|
||||||
offsetY + y * blockSize,
|
y * gridSize * scale,
|
||||||
blockSize,
|
gridSize * scale,
|
||||||
blockSize,
|
gridSize * scale,
|
||||||
tetromino->getColor( )
|
tetromino->getColor( )
|
||||||
);
|
);
|
||||||
renderTexture(
|
renderTexture(
|
||||||
textures[TetrisAssets::I_STARTR],
|
textures[TetrisAssets::I_STARTR],
|
||||||
offsetX + (x + 3) * blockSize,
|
(2 + x + 3) * gridSize * scale,
|
||||||
offsetY + y * blockSize,
|
y * gridSize * scale,
|
||||||
blockSize,
|
gridSize * scale,
|
||||||
blockSize,
|
gridSize * scale,
|
||||||
tetromino->getColor( )
|
tetromino->getColor( )
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
renderTexture(
|
renderTexture(
|
||||||
textures[TetrisAssets::I_END],
|
textures[TetrisAssets::I_END],
|
||||||
offsetX + x * blockSize,
|
(2 + x) * gridSize * scale,
|
||||||
offsetY + y * blockSize,
|
y * gridSize * scale,
|
||||||
blockSize,
|
gridSize * scale,
|
||||||
blockSize,
|
gridSize * scale,
|
||||||
tetromino->getColor( )
|
tetromino->getColor( )
|
||||||
);
|
);
|
||||||
renderTexture(
|
renderTexture(
|
||||||
textures[TetrisAssets::I_MID],
|
textures[TetrisAssets::I_MID],
|
||||||
offsetX + x * blockSize,
|
(2 + x) * gridSize * scale,
|
||||||
offsetY + (y + 1) * blockSize,
|
(y + 1) * gridSize * scale,
|
||||||
blockSize,
|
gridSize * scale,
|
||||||
blockSize,
|
gridSize * scale,
|
||||||
tetromino->getColor( )
|
tetromino->getColor( )
|
||||||
);
|
);
|
||||||
renderTexture(
|
renderTexture(
|
||||||
textures[TetrisAssets::I_MID],
|
textures[TetrisAssets::I_MID],
|
||||||
offsetX + x * blockSize,
|
(2 + x) * gridSize * scale,
|
||||||
offsetY + (y + 2) * blockSize,
|
(y + 2) * gridSize * scale,
|
||||||
blockSize,
|
gridSize * scale,
|
||||||
blockSize,
|
gridSize * scale,
|
||||||
tetromino->getColor( )
|
tetromino->getColor( )
|
||||||
);
|
);
|
||||||
renderTexture(
|
renderTexture(
|
||||||
textures[TetrisAssets::I_START],
|
textures[TetrisAssets::I_START],
|
||||||
offsetX + x * blockSize,
|
(2 + x) * gridSize * scale,
|
||||||
offsetY + (y + 3) * blockSize,
|
(y + 3) * gridSize * scale,
|
||||||
blockSize,
|
gridSize * scale,
|
||||||
blockSize,
|
gridSize * scale,
|
||||||
tetromino->getColor( )
|
tetromino->getColor( )
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -147,10 +195,10 @@ void Renderer::drawTetromino(const shared_ptr<Tetromino> tetromino) {
|
|||||||
if (shape[row][col] != 0) {
|
if (shape[row][col] != 0) {
|
||||||
renderTexture(
|
renderTexture(
|
||||||
textures[shapeToAsset(tetromino->getShapeEnumn( ))],
|
textures[shapeToAsset(tetromino->getShapeEnumn( ))],
|
||||||
offsetX + (x + col) * blockSize,
|
((x + col) * gridSize * scale) + leftBorder->x + leftBorder->w,
|
||||||
offsetY + (y + row) * blockSize,
|
(y + row) * gridSize * scale,
|
||||||
blockSize,
|
gridSize * scale,
|
||||||
blockSize,
|
gridSize * scale,
|
||||||
tetromino->getColor( )
|
tetromino->getColor( )
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -194,43 +242,76 @@ const TetrisAssets Renderer::shapeToAsset(const TetrominoShape shape) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::renderStartScreen( ) {
|
void Renderer::renderStartScreen( ) {
|
||||||
SDL_SetRenderDrawColor(renderer.get( ), 248, 248, 248, 255);
|
SDL_SetRenderDrawColor(renderer.get( ), 0, 0, 0, 255);
|
||||||
SDL_RenderClear(renderer.get( ));
|
SDL_RenderClear(renderer.get( ));
|
||||||
|
|
||||||
int borderThickness = 20;
|
auto title = unique_ptr<SDL_Surface, decltype(&SDL_FreeSurface)>(IMG_Load("assets/sprites/title.png"), SDL_FreeSurface);
|
||||||
SDL_Rect borderRect = {
|
|
||||||
borderThickness,
|
|
||||||
borderThickness,
|
|
||||||
windowWidth - 2 * borderThickness,
|
|
||||||
windowHeight - 2 * borderThickness
|
|
||||||
};
|
|
||||||
SDL_SetRenderDrawColor(renderer.get( ), 0, 0, 0, 255);
|
|
||||||
SDL_RenderDrawRect(renderer.get( ), &borderRect);
|
|
||||||
|
|
||||||
int titleWidth = static_cast<int>(windowWidth * 0.8f);
|
int titlePaddingX = 3, titlePaddingY = 8;
|
||||||
int titleHeight = static_cast<int>(titleWidth * 0.315f);
|
|
||||||
|
|
||||||
renderTexture(
|
TextureDimensions* titleDimensions = renderTexture(
|
||||||
"assets/sprites/title.png",
|
"assets/sprites/title.png",
|
||||||
(windowWidth / 2) - (titleWidth / 2),
|
titlePaddingX * scale,
|
||||||
static_cast<int>(windowHeight * 0.160f),
|
titlePaddingY * scale,
|
||||||
titleWidth,
|
title->w * scale,
|
||||||
titleHeight
|
title->h * scale
|
||||||
);
|
);
|
||||||
|
|
||||||
auto titleBg = unique_ptr<SDL_Surface, decltype(&SDL_FreeSurface)>(IMG_Load("assets/sprites/title_bg.png"), SDL_FreeSurface);
|
auto titleBg = unique_ptr<SDL_Surface, decltype(&SDL_FreeSurface)>(IMG_Load("assets/sprites/title_bg.png"), SDL_FreeSurface);
|
||||||
|
|
||||||
int titleBgWidth = static_cast<int>(windowWidth * 0.8f);
|
SDL_Color col = { 255,255,255 };
|
||||||
int titleBgHeight = static_cast<int>(titleBgWidth * (static_cast<float>(titleBg->h) / titleBg->w));
|
|
||||||
|
|
||||||
renderTexture(
|
TextureDimensions* titleBgDimensions = renderTexture(
|
||||||
"assets/sprites/title_bg.png",
|
"assets/sprites/title_bg.png",
|
||||||
(windowWidth / 2) - (titleBgWidth / 2),
|
windowWidth / 2,
|
||||||
static_cast<int>(windowHeight * 0.5f),
|
titleDimensions->y + titleDimensions->h,
|
||||||
titleBgWidth,
|
titleBg->w * scale,
|
||||||
titleBgHeight
|
titleBg->h * scale,
|
||||||
|
col,
|
||||||
|
1.0f,
|
||||||
|
HAlign::CENTER
|
||||||
|
);
|
||||||
|
|
||||||
|
SDL_SetRenderDrawColor(renderer.get( ), 248, 248, 248, 255);
|
||||||
|
|
||||||
|
int titleBgBottomPadding = 6;
|
||||||
|
int y = titleBgDimensions->y + titleBgDimensions->h + titleBgBottomPadding * scale;
|
||||||
|
|
||||||
|
SDL_Rect rect{
|
||||||
|
0,
|
||||||
|
y,
|
||||||
|
windowWidth,
|
||||||
|
windowHeight - y,
|
||||||
|
};
|
||||||
|
|
||||||
|
SDL_RenderFillRect(renderer.get( ), &rect);
|
||||||
|
|
||||||
|
TextDimensions player1TextDimendions = renderText(
|
||||||
|
"1player",
|
||||||
|
windowWidth / 4,
|
||||||
|
y + (1 * scale),
|
||||||
|
8 * scale,
|
||||||
|
SDL_Color{ 0, 0, 0 },
|
||||||
|
HAlign::CENTER
|
||||||
|
);
|
||||||
|
|
||||||
|
renderText(
|
||||||
|
"2player",
|
||||||
|
windowWidth * 3 / 4,
|
||||||
|
y + (1 * scale),
|
||||||
|
8 * scale,
|
||||||
|
SDL_Color{ 0, 0, 0 },
|
||||||
|
HAlign::CENTER
|
||||||
|
);
|
||||||
|
|
||||||
|
renderText(
|
||||||
|
"©1989 ®",
|
||||||
|
windowWidth / 2,
|
||||||
|
windowHeight - (14 * scale),
|
||||||
|
8 * scale,
|
||||||
|
SDL_Color{ 0, 0, 0 },
|
||||||
|
HAlign::CENTER
|
||||||
);
|
);
|
||||||
renderText("press G to start", (windowWidth / 2), windowHeight - 70, 16, SDL_Color{ 0, 0, 0 }, HAlign::CENTER);
|
|
||||||
|
|
||||||
SDL_RenderPresent(renderer.get( ));
|
SDL_RenderPresent(renderer.get( ));
|
||||||
}
|
}
|
||||||
@@ -268,29 +349,29 @@ void Renderer::renderTetrominoPreview(const shared_ptr<Tetromino> nextTetromino)
|
|||||||
for (int i = 0; i < 4; ++i) {
|
for (int i = 0; i < 4; ++i) {
|
||||||
renderTexture(
|
renderTexture(
|
||||||
textures[TetrisAssets::I_MIDR],
|
textures[TetrisAssets::I_MIDR],
|
||||||
(windowWidth - 155) + (x + i) * blockSize,
|
(windowWidth - 155) + (x + i) * gridSize * scale,
|
||||||
(windowHeight - 120) + y * blockSize,
|
(windowHeight - 120) + y * gridSize * scale,
|
||||||
blockSize,
|
gridSize * scale,
|
||||||
blockSize,
|
gridSize * scale,
|
||||||
nextTetromino->getColor( )
|
nextTetromino->getColor( )
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderTexture(
|
renderTexture(
|
||||||
textures[TetrisAssets::I_ENDR],
|
textures[TetrisAssets::I_ENDR],
|
||||||
(windowWidth - 155) + x * blockSize,
|
(windowWidth - 155) + x * gridSize * scale,
|
||||||
(windowHeight - 120) + y * blockSize,
|
(windowHeight - 120) + y * gridSize * scale,
|
||||||
blockSize,
|
gridSize * scale,
|
||||||
blockSize,
|
gridSize * scale,
|
||||||
nextTetromino->getColor( )
|
nextTetromino->getColor( )
|
||||||
);
|
);
|
||||||
|
|
||||||
renderTexture(
|
renderTexture(
|
||||||
textures[TetrisAssets::I_STARTR],
|
textures[TetrisAssets::I_STARTR],
|
||||||
(windowWidth - 155) + (x + 3) * blockSize,
|
(windowWidth - 155) + (x + 3) * gridSize * scale,
|
||||||
(windowHeight - 120) + y * blockSize,
|
(windowHeight - 120) + y * gridSize * scale,
|
||||||
blockSize,
|
gridSize * scale,
|
||||||
blockSize,
|
gridSize * scale,
|
||||||
nextTetromino->getColor( )
|
nextTetromino->getColor( )
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -300,10 +381,10 @@ void Renderer::renderTetrominoPreview(const shared_ptr<Tetromino> nextTetromino)
|
|||||||
if (nextTetromino->getShape( )[row][col] != 0) {
|
if (nextTetromino->getShape( )[row][col] != 0) {
|
||||||
renderTexture(
|
renderTexture(
|
||||||
textures[shapeToAsset(nextTetromino->getShapeEnumn( ))],
|
textures[shapeToAsset(nextTetromino->getShapeEnumn( ))],
|
||||||
(windowWidth - 140) + col * blockSize,
|
(windowWidth - 140) + col * gridSize * scale,
|
||||||
(windowHeight - 130) + row * blockSize,
|
(windowHeight - 130) + row * gridSize * scale,
|
||||||
blockSize,
|
gridSize * scale,
|
||||||
blockSize,
|
gridSize * scale,
|
||||||
nextTetromino->getColor( )
|
nextTetromino->getColor( )
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -312,7 +393,7 @@ void Renderer::renderTetrominoPreview(const shared_ptr<Tetromino> nextTetromino)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const Renderer::TextDimensions Renderer::renderText(const string& text, int x, int y, int fontSize, SDL_Color color, HAlign hAlign, VAlign vAlign) {
|
Renderer::TextDimensions Renderer::renderText(const string& text, int x, int y, int fontSize, SDL_Color color, HAlign hAlign, VAlign vAlign) {
|
||||||
auto font = unique_ptr<TTF_Font, decltype(&TTF_CloseFont)>(TTF_OpenFont("assets/font/tetris-gb.ttf", fontSize), TTF_CloseFont);
|
auto font = unique_ptr<TTF_Font, decltype(&TTF_CloseFont)>(TTF_OpenFont("assets/font/tetris-gb.ttf", fontSize), TTF_CloseFont);
|
||||||
if (!font) { SDL_Log("Failed to create font: %s", TTF_GetError( )); return{ 0,0,0,0 }; }
|
if (!font) { SDL_Log("Failed to create font: %s", TTF_GetError( )); return{ 0,0,0,0 }; }
|
||||||
|
|
||||||
@@ -342,15 +423,15 @@ const Renderer::TextDimensions Renderer::renderText(const string& text, int x, i
|
|||||||
return TextDimensions{ x, y, width, height };
|
return TextDimensions{ x, y, width, height };
|
||||||
}
|
}
|
||||||
|
|
||||||
const Renderer::TextureDimensions Renderer::renderTexture(
|
Renderer::TextureDimensions* Renderer::renderTexture(
|
||||||
const string& texturePath, int x, int y, int width, int height,
|
const string& texturePath, int x, int y, int width, int height,
|
||||||
SDL_Color color, float scale, HAlign textHAlign, VAlign textVAlign) {
|
SDL_Color color, float scale, HAlign textHAlign, VAlign textVAlign) {
|
||||||
|
|
||||||
auto surface = unique_ptr <SDL_Surface, decltype(&SDL_FreeSurface)>(IMG_Load(texturePath.c_str( )), SDL_FreeSurface);
|
auto surface = unique_ptr <SDL_Surface, decltype(&SDL_FreeSurface)>(IMG_Load(texturePath.c_str( )), SDL_FreeSurface);
|
||||||
if (!surface) { SDL_Log("Failed to load surface from %s: %s", texturePath, SDL_GetError( ));return{ 0,0,0,0 }; }
|
if (!surface) { SDL_Log("Failed to load surface from %s: %s", texturePath, SDL_GetError( ));return nullptr; }
|
||||||
|
|
||||||
auto texture = unique_ptr<SDL_Texture, decltype(&SDL_DestroyTexture)>(SDL_CreateTextureFromSurface(renderer.get( ), surface.get( )), SDL_DestroyTexture);
|
auto texture = unique_ptr<SDL_Texture, decltype(&SDL_DestroyTexture)>(SDL_CreateTextureFromSurface(renderer.get( ), surface.get( )), SDL_DestroyTexture);
|
||||||
if (!texture) { SDL_Log("Failed to create texture from surface: %s", SDL_GetError( )); return{ 0,0,0,0 }; }
|
if (!texture) { SDL_Log("Failed to create texture from surface: %s", SDL_GetError( )); return nullptr; }
|
||||||
|
|
||||||
SDL_SetTextureBlendMode(texture.get( ), SDL_BLENDMODE_BLEND);
|
SDL_SetTextureBlendMode(texture.get( ), SDL_BLENDMODE_BLEND);
|
||||||
SDL_SetTextureColorMod(texture.get( ), color.r, color.g, color.b);
|
SDL_SetTextureColorMod(texture.get( ), color.r, color.g, color.b);
|
||||||
@@ -372,12 +453,12 @@ const Renderer::TextureDimensions Renderer::renderTexture(
|
|||||||
SDL_Rect rect{ x,y,textureWidth,textureHeight };
|
SDL_Rect rect{ x,y,textureWidth,textureHeight };
|
||||||
SDL_RenderCopy(renderer.get( ), texture.get( ), nullptr, &rect);
|
SDL_RenderCopy(renderer.get( ), texture.get( ), nullptr, &rect);
|
||||||
|
|
||||||
return { x,y,textureWidth, textureHeight };
|
return new TextureDimensions{ x,y,textureWidth, textureHeight };
|
||||||
}
|
}
|
||||||
|
|
||||||
const int Renderer::getBlockSize( ) const { return blockSize; }
|
const int Renderer::getScale( ) const { return scale; }
|
||||||
|
|
||||||
void Renderer::setBlockSize(int newBlockSize) { blockSize = newBlockSize; }
|
void Renderer::setScale(int newScale) { scale = newScale; }
|
||||||
|
|
||||||
void Renderer::setOffset(int newX, int newY) {
|
void Renderer::setOffset(int newX, int newY) {
|
||||||
offsetX = newX;
|
offsetX = newX;
|
||||||
|
|||||||
@@ -37,13 +37,11 @@ private:
|
|||||||
void drawTetromino(const shared_ptr<Tetromino> tetromino);
|
void drawTetromino(const shared_ptr<Tetromino> tetromino);
|
||||||
void drawScoreboard(int score, int level, int lines);
|
void drawScoreboard(int score, int level, int lines);
|
||||||
|
|
||||||
const bool loadTexture(const string& filePath, const TetrisAssets shape);
|
|
||||||
|
|
||||||
const TetrisAssets shapeToAsset(const TetrominoShape shape) const;
|
const TetrisAssets shapeToAsset(const TetrominoShape shape) const;
|
||||||
|
|
||||||
const shared_ptr<SDL_Renderer> renderer;
|
const shared_ptr<SDL_Renderer> renderer;
|
||||||
|
|
||||||
int blockSize;
|
int scale = 5, gridSize = 8;
|
||||||
int offsetX, offsetY;
|
int offsetX, offsetY;
|
||||||
int windowHeight = 0, windowWidth = 0;
|
int windowHeight = 0, windowWidth = 0;
|
||||||
|
|
||||||
@@ -71,6 +69,9 @@ private:
|
|||||||
const SDL_Color color;
|
const SDL_Color color;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
TextureDimensions* scoreBoardDimensions;
|
||||||
|
TextureDimensions* leftBorder, * rightBorder;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Renderer(shared_ptr<SDL_Renderer> renderer, int w, int h);
|
Renderer(shared_ptr<SDL_Renderer> renderer, int w, int h);
|
||||||
|
|
||||||
@@ -78,18 +79,18 @@ public:
|
|||||||
|
|
||||||
void renderStartScreen( );
|
void renderStartScreen( );
|
||||||
void renderGameOver(shared_ptr<GameBoard> gameBoard);
|
void renderGameOver(shared_ptr<GameBoard> gameBoard);
|
||||||
const TextDimensions renderText(
|
TextDimensions renderText(
|
||||||
const string& text, int x, int y, int fontSize,
|
const string& text, int x, int y, int fontSize,
|
||||||
SDL_Color color, HAlign textHAlign = HAlign::LEFT, VAlign textVAlign = VAlign::TOP
|
SDL_Color color, HAlign textHAlign = HAlign::LEFT, VAlign textVAlign = VAlign::TOP
|
||||||
);
|
);
|
||||||
const TextureDimensions renderTexture(
|
TextureDimensions* renderTexture(
|
||||||
const string& texturePath, int x, int y, int width = 0, int height = 0,
|
const string& texturePath, int x, int y, int width = 0, int height = 0,
|
||||||
SDL_Color color = { 255,255,255 }, float scale = 1.0f, HAlign textHAlign = HAlign::LEFT, VAlign textVAlign = VAlign::TOP
|
SDL_Color color = { 255,255,255 }, float scale = 1.0f, HAlign textHAlign = HAlign::LEFT, VAlign textVAlign = VAlign::TOP
|
||||||
);
|
);
|
||||||
void renderTetrominoPreview(const shared_ptr<Tetromino> nextTetromino);
|
void renderTetrominoPreview(const shared_ptr<Tetromino> nextTetromino);
|
||||||
|
|
||||||
const int getBlockSize( ) const;
|
const int getScale( ) const;
|
||||||
void setBlockSize(int newBlockSize);
|
void setScale(int newBlockSize);
|
||||||
void setOffset(int newX, int newY);
|
void setOffset(int newX, int newY);
|
||||||
const int getOffsetX( ) const;
|
const int getOffsetX( ) const;
|
||||||
const int getOffsetY( ) const;
|
const int getOffsetY( ) const;
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
#include "Sound.hpp"
|
#include "Sound.hpp"
|
||||||
|
|
||||||
|
unique_ptr<unordered_map<SoundName, shared_ptr<Mix_Chunk>>> Sound::cachedSounds = nullptr;
|
||||||
|
unique_ptr<unordered_map<MusicName, shared_ptr<Mix_Music>>> Sound::cachedMusic = nullptr;
|
||||||
|
|
||||||
Sound::Sound( ) {
|
Sound::Sound( ) {
|
||||||
if (!cachedSounds) {
|
if (!cachedSounds) {
|
||||||
cachedSounds = make_unique<unordered_map<SoundName, shared_ptr<Mix_Chunk>>>( );
|
cachedSounds = make_unique<unordered_map<SoundName, shared_ptr<Mix_Chunk>>>( );
|
||||||
@@ -80,30 +83,26 @@ bool Sound::PlayMusic(MusicName musicName, int loop) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Sound::PauseMusic( ) {
|
void Sound::PauseMusic( ) {
|
||||||
if (Mix_PlayingMusic( ) != 0)
|
if (Mix_PlayingMusic( ) != 0)
|
||||||
Mix_PauseMusic( );
|
Mix_PauseMusic( );
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Sound::ResumeMusic( ) {
|
void Sound::ResumeMusic( ) {
|
||||||
if (Mix_PausedMusic( ) == 0)
|
if (Mix_PausedMusic( ))
|
||||||
Mix_ResumeMusic( );
|
Mix_ResumeMusic( );
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Sound::IncreaseVolume( ) {
|
void Sound::IncreaseVolume( ) {
|
||||||
int currentVolume = Mix_Volume(-1, -1);
|
int currentVolume = Mix_Volume(-1, -1);
|
||||||
if (currentVolume < MIX_MAX_VOLUME) {
|
if (currentVolume < MIX_MAX_VOLUME)
|
||||||
Mix_Volume(-1, currentVolume + 2);
|
Mix_Volume(-1, currentVolume + 2);
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Sound::DecreaseVolume( ) {
|
void Sound::DecreaseVolume( ) {
|
||||||
int currentVolume = Mix_Volume(-1, -1);
|
int currentVolume = Mix_Volume(-1, -1);
|
||||||
if (currentVolume > 0) {
|
if (currentVolume > 0)
|
||||||
Mix_Volume(-1, currentVolume - 2);
|
Mix_Volume(-1, currentVolume - 2);
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Sound::IsMusicPlaying( ) { return Mix_PlayingMusic( ) && !Mix_PausedMusic( ); }
|
||||||
|
|||||||
@@ -38,9 +38,9 @@ public:
|
|||||||
bool PlaySound(SoundName soundName, int loop = 0);
|
bool PlaySound(SoundName soundName, int loop = 0);
|
||||||
bool PlayMusic(MusicName musicName, int loop = -1);
|
bool PlayMusic(MusicName musicName, int loop = -1);
|
||||||
|
|
||||||
bool PauseMusic( );
|
void PauseMusic( );
|
||||||
bool ResumeMusic( );
|
void ResumeMusic( );
|
||||||
bool IncreaseVolume( );
|
void IncreaseVolume( );
|
||||||
bool DecreaseVolume( );
|
void DecreaseVolume( );
|
||||||
|
bool IsMusicPlaying( );
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -30,8 +30,8 @@ int main( ) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
Game game;
|
Game game; // 810:600
|
||||||
if (!game.init("Tetris", 810, 600)) {
|
if (!game.init("Tetris", 800, 720)) {
|
||||||
SDL_Log("Failed to init game");
|
SDL_Log("Failed to init game");
|
||||||
SDL_Quit( );
|
SDL_Quit( );
|
||||||
return 1;
|
return 1;
|
||||||
|
|||||||
Reference in New Issue
Block a user