mirror of
https://github.com/lov3b/Pong.git
synced 2025-01-18 04:30:11 +01:00
Let user select max score at start
This commit is contained in:
parent
970fdcb045
commit
16fd13d2ef
@ -46,6 +46,8 @@ add_executable(Pong src/main.cpp
|
||||
src/text/OptionScreen.cpp
|
||||
src/text/Score.h
|
||||
src/text/Score.cpp
|
||||
src/text/ScrollOptionScreen.cpp
|
||||
src/text/ScrollOptionScreen.h
|
||||
)
|
||||
|
||||
# Now link the libraries to the target
|
||||
|
@ -6,8 +6,9 @@ Game::Game(SDL_Point screenSize) : SdlWrapper("Pong", screenSize, 60),
|
||||
score(new Score(&this->screenSize, 5)),
|
||||
ball(new Ball(&this->screenSize, leftPaddle, rightPaddle, score)),
|
||||
startScreen(
|
||||
new OptionScreen("Welcome to Pong!\nPress any key to get started...",
|
||||
&this->screenSize, 4)), endScreen(nullptr),
|
||||
new ScrollOptionScreen(
|
||||
"Welcome to Pong!\nUse arrowkeys to adjust max score.\nFinish with enter.",
|
||||
&this->screenSize, 4, score->maxScore())), endScreen(nullptr),
|
||||
gameState(GameState::START_SCREEN) {
|
||||
}
|
||||
|
||||
@ -86,9 +87,7 @@ bool Game::handleEvents() {
|
||||
|
||||
switch (gameState) {
|
||||
case GameState::START_SCREEN:
|
||||
if (event.type == SDL_KEYDOWN && !startScreen->hasStartedCounting())
|
||||
startScreen->startCountDown();
|
||||
|
||||
startScreen->handleEvent(event);
|
||||
break;
|
||||
case GameState::GAME:
|
||||
handleGameEvent(event);
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "text/TextScreen.h"
|
||||
#include "text/OptionScreen.h"
|
||||
#include "text/Score.h"
|
||||
#include "text/ScrollOptionScreen.h"
|
||||
|
||||
enum class GameState {
|
||||
START_SCREEN, GAME, END_SCREEN
|
||||
@ -21,7 +22,8 @@ class Game : public SdlWrapper {
|
||||
private:
|
||||
Score *score;
|
||||
PlayerPaddle *leftPaddle, *rightPaddle;
|
||||
OptionScreen *startScreen, *endScreen;
|
||||
OptionScreen *endScreen;
|
||||
ScrollOptionScreen *startScreen;
|
||||
Ball *ball;
|
||||
|
||||
protected:
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include "Score.h"
|
||||
|
||||
Score::Score(SDL_Point *screenSize, uint8_t max_score) : MAX_SCORE(max_score), leftScore(0), rightScore(0),
|
||||
Score::Score(SDL_Point *screenSize, uint8_t max_score) : maxScore_(max_score), leftScore(0), rightScore(0),
|
||||
TextScreen("", screenSize, std::make_optional(
|
||||
SDL_Point{screenSize->x / 2 - 50, 10})) {
|
||||
}
|
||||
@ -34,6 +34,6 @@ void Score::incrementScore(const Side side) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (incrementedScore >= MAX_SCORE)
|
||||
if (incrementedScore >= maxScore_)
|
||||
sideWon_ = side;
|
||||
}
|
@ -18,7 +18,7 @@
|
||||
|
||||
class Score : public TextScreen {
|
||||
private:
|
||||
const uint8_t MAX_SCORE;
|
||||
uint8_t maxScore_;
|
||||
std::optional<Side> sideWon_;
|
||||
|
||||
public:
|
||||
@ -36,5 +36,9 @@ public:
|
||||
void resetScore();
|
||||
|
||||
void incrementScore(const Side side);
|
||||
|
||||
uint8_t &maxScore() {
|
||||
return maxScore_;
|
||||
}
|
||||
};
|
||||
|
||||
|
61
src/text/ScrollOptionScreen.cpp
Normal file
61
src/text/ScrollOptionScreen.cpp
Normal file
@ -0,0 +1,61 @@
|
||||
//
|
||||
// Created by Love on 2024-01-29.
|
||||
//
|
||||
|
||||
#include "ScrollOptionScreen.h"
|
||||
|
||||
std::string textAppendHelper(std::string string, const std::string &toAppend) {
|
||||
string.append("\nMax Score: ");
|
||||
string.append(toAppend);
|
||||
return std::move(string);
|
||||
}
|
||||
|
||||
ScrollOptionScreen::ScrollOptionScreen(const std::string &text, SDL_Point *screenSize, int seconds, uint8_t &counterRef)
|
||||
: OptionScreen(textAppendHelper(text, std::to_string(counterRef)), screenSize, seconds),
|
||||
counter(counterRef) {
|
||||
}
|
||||
|
||||
|
||||
void ScrollOptionScreen::handleEvent(SDL_Event &event) {
|
||||
if (event.type == SDL_KEYDOWN) {
|
||||
switch (event.key.keysym.sym) {
|
||||
case SDLK_w:
|
||||
[[fallthrough]];
|
||||
case SDLK_UP:
|
||||
counter++;
|
||||
shouldUpdate = true;
|
||||
break;
|
||||
case SDLK_s:
|
||||
[[fallthrough]];
|
||||
case SDLK_DOWN:
|
||||
if (counter > 0) {
|
||||
counter--;
|
||||
shouldUpdate = true;
|
||||
}
|
||||
break;
|
||||
case SDLK_RETURN:
|
||||
shouldUpdate = true;
|
||||
startCountDown();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ScrollOptionScreen::update() {
|
||||
if (shouldUpdate) {
|
||||
size_t lineIndex = getAmountOfLines() - 1;
|
||||
std::string line = getLine(lineIndex);
|
||||
size_t lastSpace = line.rfind(' ');
|
||||
if (lastSpace == std::string::npos) {
|
||||
std::cerr << "Could not find the last space..." << std::endl;
|
||||
return;
|
||||
}
|
||||
line.erase(lastSpace + 1);
|
||||
line.append(std::to_string(counter));
|
||||
|
||||
replaceLine(lineIndex, std::move(line));
|
||||
shouldUpdate = false;
|
||||
}
|
||||
|
||||
OptionScreen::update();
|
||||
}
|
24
src/text/ScrollOptionScreen.h
Normal file
24
src/text/ScrollOptionScreen.h
Normal file
@ -0,0 +1,24 @@
|
||||
//
|
||||
// Created by Love on 2024-01-29.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "OptionScreen.h"
|
||||
|
||||
class ScrollOptionScreen : public OptionScreen {
|
||||
|
||||
private:
|
||||
uint8_t &counter;
|
||||
bool shouldUpdate = true;
|
||||
|
||||
public:
|
||||
ScrollOptionScreen(const std::string &text, SDL_Point *screenSize, int seconds, uint8_t &counterRef);
|
||||
|
||||
void handleEvent(SDL_Event &event);
|
||||
|
||||
void update() override;
|
||||
};
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <utility>
|
||||
#include "TextScreen.h"
|
||||
#include "optional"
|
||||
|
||||
@ -41,34 +42,36 @@ void TextScreen::initPositions(const std::string &text) {
|
||||
surfaces.clear();
|
||||
shadowSurfaces.clear();
|
||||
positions.clear();
|
||||
shadowPositions.clear();
|
||||
|
||||
surfaces.reserve(lines.size());
|
||||
shadowSurfaces.reserve(lines.size());
|
||||
positions.reserve(lines.size());
|
||||
shadowPositions.reserve(lines.size());
|
||||
|
||||
for (int i = 0; i < lines.size(); ++i) {
|
||||
int textWidth, textHeight;
|
||||
TTF_SizeText(font, lines[i].c_str(), &textWidth, &textHeight);
|
||||
|
||||
SDL_Point base = basePosition.has_value() ? basePosition.value() : SDL_Point{(screenSize->x - textWidth) / 2,
|
||||
static_cast<int>((screenSize->y -
|
||||
textHeight *
|
||||
(lines.size())) /
|
||||
2)};
|
||||
|
||||
SDL_Rect regularPosition = {base.x, base.y + textHeight * i, textWidth, textHeight};
|
||||
SDL_Rect shadowPosition = {base.x + shadowOffset, base.y + textHeight * i + shadowOffset, textWidth,
|
||||
textHeight};
|
||||
positions.push_back(regularPosition);
|
||||
shadowPositions.push_back(shadowPosition);
|
||||
auto pair = calculatePositionOf(i);
|
||||
positions.push_back(pair);
|
||||
}
|
||||
}
|
||||
|
||||
Position TextScreen::calculatePositionOf(const int i) const {
|
||||
int textWidth, textHeight;
|
||||
TTF_SizeText(font, lines[i].c_str(), &textWidth, &textHeight);
|
||||
|
||||
SDL_Point base = basePosition.has_value() ? basePosition.value() : SDL_Point{(screenSize->x - textWidth) / 2,
|
||||
static_cast<int>((screenSize->y -
|
||||
textHeight *
|
||||
(lines.size())) /
|
||||
2)};
|
||||
|
||||
SDL_Rect regularPosition = {base.x, base.y + textHeight * i, textWidth, textHeight};
|
||||
SDL_Rect shadowPosition = {base.x + shadowOffset, base.y + textHeight * i + shadowOffset, textWidth,
|
||||
textHeight};
|
||||
return Position{.shadowPosition=shadowPosition, .regularPosition=regularPosition};
|
||||
|
||||
}
|
||||
|
||||
TextScreen::~TextScreen() {
|
||||
// TTF_CLoseFont & SDL_FreeSurface are null-safe
|
||||
|
||||
TTF_CloseFont(font);
|
||||
for (auto *surface: surfaces)
|
||||
SDL_FreeSurface(surface);
|
||||
@ -81,14 +84,14 @@ void TextScreen::draw(SDL_Renderer *const renderer) {
|
||||
// Draw shadow
|
||||
SDL_Texture *shadowTexture = SDL_CreateTextureFromSurface(renderer, shadowSurfaces[i]);
|
||||
if (shadowTexture != nullptr) {
|
||||
SDL_RenderCopy(renderer, shadowTexture, nullptr, &shadowPositions[i]);
|
||||
SDL_RenderCopy(renderer, shadowTexture, nullptr, &positions[i].shadowPosition);
|
||||
SDL_DestroyTexture(shadowTexture);
|
||||
}
|
||||
|
||||
// Draw text
|
||||
SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer, surfaces[i]);
|
||||
if (texture != nullptr) {
|
||||
SDL_RenderCopy(renderer, texture, nullptr, &positions[i]);
|
||||
SDL_RenderCopy(renderer, texture, nullptr, &positions[i].regularPosition);
|
||||
SDL_DestroyTexture(texture);
|
||||
}
|
||||
}
|
||||
@ -127,3 +130,24 @@ void TextScreen::update() {
|
||||
|
||||
hasUpdated = true;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param c to replace with
|
||||
* @param line Should be zero indexed. That means -1 from getAmountOfLines
|
||||
* @param column Should be zero indexed. That means -1 from getAmountOfColumns
|
||||
*/
|
||||
void TextScreen::replaceLine(const size_t index, std::string line) {
|
||||
lines[index] = std::move(line);
|
||||
hasUpdated = false;
|
||||
positions[index] = calculatePositionOf(index);
|
||||
}
|
||||
|
||||
std::string &TextScreen::getLine(const size_t index) {
|
||||
return lines[index];
|
||||
}
|
||||
|
||||
size_t TextScreen::getAmountOfLines() {
|
||||
return lines.size();
|
||||
}
|
||||
|
||||
|
@ -12,6 +12,10 @@
|
||||
#include "../defaultfont.h"
|
||||
#include "iostream"
|
||||
|
||||
struct Position {
|
||||
SDL_Rect shadowPosition;
|
||||
SDL_Rect regularPosition;
|
||||
};
|
||||
|
||||
class TextScreen {
|
||||
private:
|
||||
@ -22,11 +26,10 @@ private:
|
||||
std::optional<SDL_Point> basePosition;
|
||||
|
||||
// Regular
|
||||
std::vector<SDL_Rect> positions;
|
||||
std::vector<Position> positions;
|
||||
SDL_Color color = {243, 156, 18, 255};
|
||||
|
||||
// Shadow
|
||||
std::vector<SDL_Rect> shadowPositions;
|
||||
const SDL_Color shadowColor = {243, 156, 18, 100};
|
||||
const int shadowOffset = 3;
|
||||
|
||||
@ -48,8 +51,17 @@ public:
|
||||
|
||||
void setText(const std::string &replaceText);
|
||||
|
||||
void replaceLine(size_t index, std::string line);
|
||||
|
||||
std::string &getLine(size_t index);
|
||||
|
||||
size_t getAmountOfLines();
|
||||
|
||||
virtual void update();
|
||||
|
||||
private:
|
||||
void initPositions(const std::string &text);
|
||||
|
||||
Position calculatePositionOf(int i) const;
|
||||
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user