This commit is contained in:
Love 2024-01-29 12:30:00 +01:00
parent b002cb62e5
commit 2a29f01fc2
5 changed files with 30 additions and 60 deletions

View File

@ -19,29 +19,24 @@ enum class GameState {
class Game : public SdlWrapper { class Game : public SdlWrapper {
private: private:
Ball *ball;
Score *score; Score *score;
PlayerPaddle *leftPaddle, *rightPaddle; PlayerPaddle *leftPaddle, *rightPaddle;
OptionScreen *startScreen, *endScreen; OptionScreen *startScreen, *endScreen;
Ball *ball;
protected: protected:
GameState gameState; GameState gameState;
public: public:
explicit Game(SDL_Point screenSize) : SdlWrapper("Pong", screenSize, 60) { explicit Game(SDL_Point screenSize) : SdlWrapper("Pong", screenSize, 60),
leftPaddle = new PlayerPaddle(&this->screenSize, Side::LEFT); leftPaddle(new PlayerPaddle(&this->screenSize, Side::LEFT)),
rightPaddle = new PlayerPaddle(&this->screenSize, Side::RIGHT); rightPaddle(new PlayerPaddle(&this->screenSize, Side::RIGHT)),
score(new Score(&this->screenSize, 5)),
auto func = [this](Side side) { ball(new Ball(&this->screenSize, leftPaddle, rightPaddle, score)),
const char *player = side == Side::LEFT ? "one" : "two"; startScreen(
std::cout << "Player " << player << " won" << std::endl; new OptionScreen("Welcome to Pong!\nPress any key to get started...",
this->running = false; &this->screenSize, 4)), endScreen(nullptr),
}; gameState(GameState::START_SCREEN) {
score = new Score(&this->screenSize, 5, func);
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;
gameState = GameState::START_SCREEN;
} }
~Game() override { ~Game() override {
@ -56,7 +51,6 @@ public:
SDL_SetRenderDrawColor(renderer, 128, 0, 128, 0); SDL_SetRenderDrawColor(renderer, 128, 0, 128, 0);
SDL_RenderClear(renderer); SDL_RenderClear(renderer);
switch (gameState) { switch (gameState) {
case GameState::START_SCREEN: case GameState::START_SCREEN:
startScreen->draw(renderer); startScreen->draw(renderer);
@ -93,8 +87,9 @@ public:
if (score->sideWon().has_value()) { if (score->sideWon().has_value()) {
const char *player = score->sideWon().value() == Side::LEFT ? "left" : "right"; const char *player = score->sideWon().value() == Side::LEFT ? "left" : "right";
std::stringstream ss; std::stringstream ss;
ss << "The " << player << " player won with " << std::to_string(score->leftScore) << " - " << std::to_string(score->rightScore) ss << "The " << player << " player won with " << std::to_string(score->leftScore) << " - "
<< "\nWould you like to play again?" << "\nIf so, press any button..."; << std::to_string(score->rightScore) << "\nWould you like to play again?"
<< "\nIf so, press any button...";
score->resetScore(); score->resetScore();
endScreen = new OptionScreen(ss.str(), &screenSize, 4); endScreen = new OptionScreen(ss.str(), &screenSize, 4);
gameState = GameState::END_SCREEN; gameState = GameState::END_SCREEN;

View File

@ -14,18 +14,17 @@
class Ball { class Ball {
private: private:
static const uint8_t RADIUS = 15; static const uint8_t RADIUS = 15;
const SDL_Point *screen; const SDL_Point *const screen;
Sint16 x, y; Sint16 x, y;
Vec2d *vec2d; Vec2d *vec2d;
static const uint32_t color = 0xCD5C5CFF; static const uint32_t color = 0xCD5C5CFF;
const PlayerPaddle *leftPaddle, *rightPaddle; const PlayerPaddle *const leftPaddle, *const rightPaddle;
Score *score; Score *const score;
public: public:
explicit Ball(const SDL_Point *screen, const PlayerPaddle *leftPaddle, const PlayerPaddle *rightPaddle, explicit Ball(const SDL_Point *screen, const PlayerPaddle *leftPaddle, const PlayerPaddle *rightPaddle,
Score *score) : Score *score) : score(score), screen(screen), leftPaddle(leftPaddle), rightPaddle(rightPaddle),
score(score), screen(screen), leftPaddle(leftPaddle), rightPaddle(rightPaddle), x(screen->x / 2), x(screen->x / 2), y(screen->y / 2), vec2d(new Vec2d(6)) {
y(screen->y / 2), vec2d(new Vec2d(6)) {
} }
void resetPosition() { void resetPosition() {
@ -76,15 +75,11 @@ private:
[[nodiscard]] std::optional<Side> collidedPaddle() const { [[nodiscard]] std::optional<Side> collidedPaddle() const {
// Right paddle // Right paddle
if (x + RADIUS >= rightPaddle->x && if (x + RADIUS >= rightPaddle->x && y >= rightPaddle->y && y <= rightPaddle->y + rightPaddle->h) {
y >= rightPaddle->y &&
y <= rightPaddle->y + rightPaddle->h) {
return Side::RIGHT; return Side::RIGHT;
} }
// Left paddle // Left paddle
if (x - RADIUS <= leftPaddle->x + leftPaddle->w && if (x - RADIUS <= leftPaddle->x + leftPaddle->w && y >= leftPaddle->y && y <= leftPaddle->y + leftPaddle->h) {
y >= leftPaddle->y &&
y <= leftPaddle->y + leftPaddle->h) {
return Side::LEFT; return Side::LEFT;
} }
return std::nullopt; return std::nullopt;

View File

@ -12,18 +12,15 @@ class PlayerPaddle : public SDL_Rect {
private: private:
static const int MOVE_PER_TICK = 5; static const int MOVE_PER_TICK = 5;
const SDL_Point *screen; const SDL_Point *screen;
bool movingUp, movingDown; bool movingUp = false, movingDown = false;
uint8_t color[4]{}; uint8_t color[4]{};
public: public:
PlayerPaddle(const SDL_Point *screen, const Side side) : SDL_Rect() { PlayerPaddle(const SDL_Point *screen, const Side side) : SDL_Rect() , screen(screen){
w = 20; w = 20;
h = 80; h = 80;
x = side == Side::LEFT ? 0 : screen->x - w; x = side == Side::LEFT ? 0 : screen->x - w;
y = (screen->y - h) / 2; y = (screen->y - h) / 2;
movingUp = false;
movingDown = false;
this->screen = screen;
color[0] = 255; color[0] = 255;
color[1] = 234; color[1] = 234;

View File

@ -18,7 +18,6 @@
class Score : public TextScreen { class Score : public TextScreen {
private: private:
const uint8_t MAX_SCORE; const uint8_t MAX_SCORE;
const std::function<void(Side)> whenWon;
std::optional<Side> sideWon_; std::optional<Side> sideWon_;
public: public:
@ -29,8 +28,8 @@ public:
} }
public: public:
explicit Score(SDL_Point *screenSize, uint8_t max_score, const std::function<void(Side)> &whenWon) : MAX_SCORE( explicit Score(SDL_Point *screenSize, uint8_t max_score) : MAX_SCORE(max_score), leftScore(0), rightScore(0),
max_score), whenWon(whenWon), leftScore(0), rightScore(0), TextScreen("", screenSize, std::make_optional( TextScreen("", screenSize, std::make_optional(
SDL_Point{screenSize->x / 2 - 50, 10})) { SDL_Point{screenSize->x / 2 - 50, 10})) {
} }

View File

@ -29,7 +29,6 @@ private:
const SDL_Color shadowColor = {243, 156, 18, 100}; const SDL_Color shadowColor = {243, 156, 18, 100};
const int shadowOffset = 3; const int shadowOffset = 3;
protected: protected:
std::vector<std::string> lines; std::vector<std::string> lines;
bool hasUpdated; bool hasUpdated;
@ -46,7 +45,7 @@ public:
std::cerr << "Font path is not set for this platform (null)" << std::endl; std::cerr << "Font path is not set for this platform (null)" << std::endl;
exit(-1); exit(-1);
} }
this->font = TTF_OpenFont(defaultFontPath, 42); font = TTF_OpenFont(defaultFontPath, 42);
if (font == nullptr) { if (font == nullptr) {
std::cerr << "Failed to load font: " << TTF_GetError() << std::endl; std::cerr << "Failed to load font: " << TTF_GetError() << std::endl;
exit(-1); exit(-1);
@ -86,7 +85,8 @@ private:
public: public:
~TextScreen() { ~TextScreen() {
if (font) // TTF_CLoseFont & SDL_FreeSurface are null-safe
TTF_CloseFont(font); TTF_CloseFont(font);
for (auto *surface: surfaces) for (auto *surface: surfaces)
SDL_FreeSurface(surface); SDL_FreeSurface(surface);
@ -118,22 +118,6 @@ public:
initPositions(replaceText); initPositions(replaceText);
} }
void replaceCharAtIndex(char c, int line, int index) {
if (lines.size() <= line) {
if (lines[line].length() <= index) {
std::cerr << "string lines is of length " << lines.size() << ", but line index is " << index
<< std::endl;
return;
}
}
if (lines[line].length() <= index) {
std::cerr << "text string is of length " << lines[line].length() << ", but index is " << index << std::endl;
return;
}
hasUpdated = false;
lines[line][index] = c;
}
virtual void update() { virtual void update() {
if (hasUpdated) if (hasUpdated)
return; return;
@ -163,7 +147,7 @@ public:
} }
private: private:
static std::vector<std::string> splitString(const std::string &string, const char delim) { static std::vector<std::string> splitString(const std::string &string, const char &delim) {
int size = 0; int size = 0;
for (char c: string) for (char c: string)
if (c == delim) size++; if (c == delim) size++;