mirror of
				https://github.com/lov3b/Pong.git
				synced 2025-10-31 21:30: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/OptionScreen.cpp | ||||||
|         src/text/Score.h |         src/text/Score.h | ||||||
|         src/text/Score.cpp |         src/text/Score.cpp | ||||||
|  |         src/text/ScrollOptionScreen.cpp | ||||||
|  |         src/text/ScrollOptionScreen.h | ||||||
| ) | ) | ||||||
|  |  | ||||||
| # Now link the libraries to the target | # 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)), |                                    score(new Score(&this->screenSize, 5)), | ||||||
|                                    ball(new Ball(&this->screenSize, leftPaddle, rightPaddle, score)), |                                    ball(new Ball(&this->screenSize, leftPaddle, rightPaddle, score)), | ||||||
|                                    startScreen( |                                    startScreen( | ||||||
|                                            new OptionScreen("Welcome to Pong!\nPress any key to get started...", |                                            new ScrollOptionScreen( | ||||||
|                                                             &this->screenSize, 4)), endScreen(nullptr), |                                                    "Welcome to Pong!\nUse arrowkeys to adjust max score.\nFinish with enter.", | ||||||
|  |                                                    &this->screenSize, 4, score->maxScore())), endScreen(nullptr), | ||||||
|                                    gameState(GameState::START_SCREEN) { |                                    gameState(GameState::START_SCREEN) { | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -86,9 +87,7 @@ bool Game::handleEvents() { | |||||||
|  |  | ||||||
|         switch (gameState) { |         switch (gameState) { | ||||||
|             case GameState::START_SCREEN: |             case GameState::START_SCREEN: | ||||||
|                 if (event.type == SDL_KEYDOWN && !startScreen->hasStartedCounting()) |                 startScreen->handleEvent(event); | ||||||
|                     startScreen->startCountDown(); |  | ||||||
|  |  | ||||||
|                 break; |                 break; | ||||||
|             case GameState::GAME: |             case GameState::GAME: | ||||||
|                 handleGameEvent(event); |                 handleGameEvent(event); | ||||||
|   | |||||||
| @@ -12,6 +12,7 @@ | |||||||
| #include "text/TextScreen.h" | #include "text/TextScreen.h" | ||||||
| #include "text/OptionScreen.h" | #include "text/OptionScreen.h" | ||||||
| #include "text/Score.h" | #include "text/Score.h" | ||||||
|  | #include "text/ScrollOptionScreen.h" | ||||||
|  |  | ||||||
| enum class GameState { | enum class GameState { | ||||||
|     START_SCREEN, GAME, END_SCREEN |     START_SCREEN, GAME, END_SCREEN | ||||||
| @@ -21,7 +22,8 @@ class Game : public SdlWrapper { | |||||||
| private: | private: | ||||||
|     Score *score; |     Score *score; | ||||||
|     PlayerPaddle *leftPaddle, *rightPaddle; |     PlayerPaddle *leftPaddle, *rightPaddle; | ||||||
|     OptionScreen *startScreen, *endScreen; |     OptionScreen *endScreen; | ||||||
|  |     ScrollOptionScreen *startScreen; | ||||||
|     Ball *ball; |     Ball *ball; | ||||||
|  |  | ||||||
| protected: | protected: | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| #include "Score.h" | #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( |                                                          TextScreen("", screenSize, std::make_optional( | ||||||
|                                                                  SDL_Point{screenSize->x / 2 - 50, 10})) { |                                                                  SDL_Point{screenSize->x / 2 - 50, 10})) { | ||||||
| } | } | ||||||
| @@ -34,6 +34,6 @@ void Score::incrementScore(const Side side) { | |||||||
|             break; |             break; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     if (incrementedScore >= MAX_SCORE) |     if (incrementedScore >= maxScore_) | ||||||
|         sideWon_ = side; |         sideWon_ = side; | ||||||
| } | } | ||||||
| @@ -18,7 +18,7 @@ | |||||||
|  |  | ||||||
| class Score : public TextScreen { | class Score : public TextScreen { | ||||||
| private: | private: | ||||||
|     const uint8_t MAX_SCORE; |     uint8_t maxScore_; | ||||||
|     std::optional<Side> sideWon_; |     std::optional<Side> sideWon_; | ||||||
|  |  | ||||||
| public: | public: | ||||||
| @@ -36,5 +36,9 @@ public: | |||||||
|     void resetScore(); |     void resetScore(); | ||||||
|  |  | ||||||
|     void incrementScore(const Side side); |     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 <string> | ||||||
| #include <sstream> | #include <sstream> | ||||||
|  | #include <utility> | ||||||
| #include "TextScreen.h" | #include "TextScreen.h" | ||||||
| #include "optional" | #include "optional" | ||||||
|  |  | ||||||
| @@ -41,14 +42,18 @@ void TextScreen::initPositions(const std::string &text) { | |||||||
|     surfaces.clear(); |     surfaces.clear(); | ||||||
|     shadowSurfaces.clear(); |     shadowSurfaces.clear(); | ||||||
|     positions.clear(); |     positions.clear(); | ||||||
|     shadowPositions.clear(); |  | ||||||
|  |  | ||||||
|     surfaces.reserve(lines.size()); |     surfaces.reserve(lines.size()); | ||||||
|     shadowSurfaces.reserve(lines.size()); |     shadowSurfaces.reserve(lines.size()); | ||||||
|     positions.reserve(lines.size()); |     positions.reserve(lines.size()); | ||||||
|     shadowPositions.reserve(lines.size()); |  | ||||||
|  |  | ||||||
|     for (int i = 0; i < lines.size(); ++i) { |     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; |     int textWidth, textHeight; | ||||||
|     TTF_SizeText(font, lines[i].c_str(), &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 regularPosition = {base.x, base.y + textHeight * i, textWidth, textHeight}; | ||||||
|     SDL_Rect shadowPosition = {base.x + shadowOffset, base.y + textHeight * i + shadowOffset, textWidth, |     SDL_Rect shadowPosition = {base.x + shadowOffset, base.y + textHeight * i + shadowOffset, textWidth, | ||||||
|                                textHeight}; |                                textHeight}; | ||||||
|         positions.push_back(regularPosition); |     return Position{.shadowPosition=shadowPosition, .regularPosition=regularPosition}; | ||||||
|         shadowPositions.push_back(shadowPosition); |  | ||||||
|     } |  | ||||||
| } | } | ||||||
|  |  | ||||||
| TextScreen::~TextScreen() { | TextScreen::~TextScreen() { | ||||||
|     // TTF_CLoseFont & SDL_FreeSurface are null-safe |     // 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); | ||||||
| @@ -81,14 +84,14 @@ void TextScreen::draw(SDL_Renderer *const renderer) { | |||||||
|         // Draw shadow |         // Draw shadow | ||||||
|         SDL_Texture *shadowTexture = SDL_CreateTextureFromSurface(renderer, shadowSurfaces[i]); |         SDL_Texture *shadowTexture = SDL_CreateTextureFromSurface(renderer, shadowSurfaces[i]); | ||||||
|         if (shadowTexture != nullptr) { |         if (shadowTexture != nullptr) { | ||||||
|             SDL_RenderCopy(renderer, shadowTexture, nullptr, &shadowPositions[i]); |             SDL_RenderCopy(renderer, shadowTexture, nullptr, &positions[i].shadowPosition); | ||||||
|             SDL_DestroyTexture(shadowTexture); |             SDL_DestroyTexture(shadowTexture); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         // Draw text |         // Draw text | ||||||
|         SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer, surfaces[i]); |         SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer, surfaces[i]); | ||||||
|         if (texture != nullptr) { |         if (texture != nullptr) { | ||||||
|             SDL_RenderCopy(renderer, texture, nullptr, &positions[i]); |             SDL_RenderCopy(renderer, texture, nullptr, &positions[i].regularPosition); | ||||||
|             SDL_DestroyTexture(texture); |             SDL_DestroyTexture(texture); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| @@ -127,3 +130,24 @@ void TextScreen::update() { | |||||||
|  |  | ||||||
|     hasUpdated = true; |     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 "../defaultfont.h" | ||||||
| #include "iostream" | #include "iostream" | ||||||
|  |  | ||||||
|  | struct Position { | ||||||
|  |     SDL_Rect shadowPosition; | ||||||
|  |     SDL_Rect regularPosition; | ||||||
|  | }; | ||||||
|  |  | ||||||
| class TextScreen { | class TextScreen { | ||||||
| private: | private: | ||||||
| @@ -22,11 +26,10 @@ private: | |||||||
|     std::optional<SDL_Point> basePosition; |     std::optional<SDL_Point> basePosition; | ||||||
|  |  | ||||||
|     // Regular |     // Regular | ||||||
|     std::vector<SDL_Rect> positions; |     std::vector<Position> positions; | ||||||
|     SDL_Color color = {243, 156, 18, 255}; |     SDL_Color color = {243, 156, 18, 255}; | ||||||
|  |  | ||||||
|     // Shadow |     // Shadow | ||||||
|     std::vector<SDL_Rect> shadowPositions; |  | ||||||
|     const SDL_Color shadowColor = {243, 156, 18, 100}; |     const SDL_Color shadowColor = {243, 156, 18, 100}; | ||||||
|     const int shadowOffset = 3; |     const int shadowOffset = 3; | ||||||
|  |  | ||||||
| @@ -48,8 +51,17 @@ public: | |||||||
|  |  | ||||||
|     void setText(const std::string &replaceText); |     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(); |     virtual void update(); | ||||||
|  |  | ||||||
| private: | private: | ||||||
|     void initPositions(const std::string &text); |     void initPositions(const std::string &text); | ||||||
|  |  | ||||||
|  |     Position calculatePositionOf(int i) const; | ||||||
|  |  | ||||||
| }; | }; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user