mirror of
				https://github.com/lov3b/Pong.git
				synced 2025-10-31 13:20:24 +01:00 
			
		
		
		
	Let user select max score at start
This commit is contained in:
		| @@ -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,14 +42,18 @@ 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) { | ||||
|         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); | ||||
|  | ||||
| @@ -61,14 +66,12 @@ void TextScreen::initPositions(const std::string &text) { | ||||
|     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); | ||||
|     } | ||||
|     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; | ||||
|  | ||||
| }; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user