Pong/src/Game.h

171 lines
5.6 KiB
C
Raw Normal View History

2024-01-19 15:06:48 +01:00
//
// Created by love on 2024-01-18.
//
#pragma
#include "SdlWrapper.h"
#include "SDL.h"
#include "VisibleObjects/Ball.h"
#include "VisibleObjects/PlayerPaddle.h"
#include "text/Score.h"
#include "text/TextScreen.h"
#include "text/OptionScreen.h"
#include "text/Score.h"
2024-01-19 15:06:48 +01:00
2024-01-28 21:07:18 +01:00
enum class GameState {
START_SCREEN, GAME, END_SCREEN
};
2024-01-19 15:06:48 +01:00
class Game : public SdlWrapper {
private:
2024-01-19 18:41:26 +01:00
Score *score;
2024-01-19 15:06:48 +01:00
PlayerPaddle *leftPaddle, *rightPaddle;
2024-01-29 10:46:27 +01:00
OptionScreen *startScreen, *endScreen;
2024-01-29 12:30:00 +01:00
Ball *ball;
2024-01-19 15:06:48 +01:00
2024-01-28 21:07:18 +01:00
protected:
GameState gameState;
2024-01-19 15:06:48 +01:00
public:
2024-01-29 12:30:00 +01:00
explicit Game(SDL_Point screenSize) : SdlWrapper("Pong", screenSize, 60),
leftPaddle(new PlayerPaddle(&this->screenSize, Side::LEFT)),
rightPaddle(new PlayerPaddle(&this->screenSize, Side::RIGHT)),
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),
gameState(GameState::START_SCREEN) {
2024-01-19 15:06:48 +01:00
}
~Game() override {
delete ball;
delete leftPaddle;
delete rightPaddle;
2024-01-19 18:41:26 +01:00
delete score;
2024-01-19 15:06:48 +01:00
}
void draw(SDL_Renderer *renderer) override {
// Background
SDL_SetRenderDrawColor(renderer, 128, 0, 128, 0);
SDL_RenderClear(renderer);
2024-01-28 21:07:18 +01:00
switch (gameState) {
case GameState::START_SCREEN:
2024-01-29 00:43:01 +01:00
startScreen->draw(renderer);
2024-01-28 21:07:18 +01:00
break;
case GameState::GAME:
ball->draw(renderer);
score->draw(renderer);
leftPaddle->draw(renderer);
rightPaddle->draw(renderer);
break;
case GameState::END_SCREEN:
endScreen->draw(renderer);
2024-01-28 21:07:18 +01:00
break;
}
2024-01-19 15:06:48 +01:00
SDL_RenderPresent(renderer);
}
2024-01-29 00:43:01 +01:00
void update() override {
2024-01-28 21:07:18 +01:00
switch (gameState) {
case GameState::START_SCREEN:
2024-01-29 00:43:01 +01:00
startScreen->update();
2024-01-29 10:46:27 +01:00
if (startScreen->isDone()) {
2024-01-29 10:26:05 +01:00
gameState = GameState::GAME;
2024-01-29 10:46:27 +01:00
delete startScreen; // We will never get back to this state
}
2024-01-28 21:07:18 +01:00
break;
case GameState::GAME:
ball->update();
leftPaddle->update();
rightPaddle->update();
score->update();
if (score->sideWon().has_value()) {
const char *player = score->sideWon().value() == Side::LEFT ? "left" : "right";
2024-01-29 10:46:27 +01:00
std::stringstream ss;
2024-01-29 12:30:00 +01:00
ss << "The " << player << " player won with " << std::to_string(score->leftScore) << " - "
<< std::to_string(score->rightScore) << "\nWould you like to play again?"
<< "\nIf so, press any button...";
score->resetScore();
2024-01-29 10:46:27 +01:00
endScreen = new OptionScreen(ss.str(), &screenSize, 4);
gameState = GameState::END_SCREEN;
2024-01-29 10:46:27 +01:00
}
break;
case GameState::END_SCREEN:
2024-01-29 10:46:27 +01:00
endScreen->update();
if (endScreen->isDone()) {
gameState = GameState::GAME;
delete endScreen; // The text will not be the same if we get back here. We might as well free it.
}
2024-01-28 21:07:18 +01:00
break;
}
2024-01-19 15:06:48 +01:00
}
bool handleEvents() override {
SDL_Event event;
2024-01-29 00:43:01 +01:00
while (SDL_PollEvent(&event)) {
2024-01-19 15:06:48 +01:00
if (event.type == SDL_QUIT)
return false;
2024-01-29 00:43:01 +01:00
switch (gameState) {
case GameState::START_SCREEN:
2024-01-29 10:26:05 +01:00
if (event.type == SDL_KEYDOWN && !startScreen->hasStartedCounting())
startScreen->startCountDown();
break;
2024-01-29 00:43:01 +01:00
case GameState::GAME:
handleGameEvent(event);
break;
2024-01-29 00:43:01 +01:00
case GameState::END_SCREEN:
if (event.type == SDL_KEYDOWN && !endScreen->hasStartedCounting())
endScreen->startCountDown();
2024-01-29 00:43:01 +01:00
break;
2024-01-19 15:06:48 +01:00
}
}
2024-01-29 00:43:01 +01:00
2024-01-19 15:06:48 +01:00
return true;
}
2024-01-29 00:43:01 +01:00
void handleGameEvent(SDL_Event &event) {
if (event.type == SDL_KEYDOWN) {
switch (event.key.keysym.sym) {
case SDLK_w:
leftPaddle->startMoving(true);
break;
case SDLK_s:
leftPaddle->startMoving(false);
break;
case SDLK_UP:
rightPaddle->startMoving(true);
break;
case SDLK_DOWN:
rightPaddle->startMoving(false);
break;
}
} else if (event.type == SDL_KEYUP) {
switch (event.key.keysym.sym) {
case SDLK_w:
leftPaddle->stopMoving(true);
break;
case SDLK_s:
leftPaddle->stopMoving(false);
break;
case SDLK_UP:
rightPaddle->stopMoving(true);
break;
case SDLK_DOWN:
rightPaddle->stopMoving(false);
break;
}
}
}
2024-01-19 15:06:48 +01:00
};