mirror of
				https://github.com/lov3b/Pong.git
				synced 2025-11-04 07:10:16 +01:00 
			
		
		
		
	start screen working
This commit is contained in:
		@@ -11,7 +11,7 @@ find_package(SDL2 REQUIRED)
 | 
				
			|||||||
include_directories(${SDL2_INCLUDE_DIRS})
 | 
					include_directories(${SDL2_INCLUDE_DIRS})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# SDL2 Gfx
 | 
					# SDL2 Gfx
 | 
				
			||||||
find_library(SDL2_GFX_LIBRARY NAMES SDL2_gfx SDL2_gfxd)
 | 
					find_library(SDL2_GFX_LIBRARY NAMES SDL2_gfx SDL2_gfxd libSDL2_gfx)
 | 
				
			||||||
if (NOT SDL2_GFX_LIBRARY)
 | 
					if (NOT SDL2_GFX_LIBRARY)
 | 
				
			||||||
    message(FATAL_ERROR "SDL2_gfx not found")
 | 
					    message(FATAL_ERROR "SDL2_gfx not found")
 | 
				
			||||||
endif ()
 | 
					endif ()
 | 
				
			||||||
@@ -34,7 +34,8 @@ add_executable(Pong src/main.cpp
 | 
				
			|||||||
        src/VisibleObjects/Side.h
 | 
					        src/VisibleObjects/Side.h
 | 
				
			||||||
        src/VisibleObjects/Score.h
 | 
					        src/VisibleObjects/Score.h
 | 
				
			||||||
        src/TextScreen.h
 | 
					        src/TextScreen.h
 | 
				
			||||||
        src/defaultfont.h)
 | 
					        src/defaultfont.h
 | 
				
			||||||
 | 
					        src/StartScreen.h)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Now link the libraries to the target
 | 
					# Now link the libraries to the target
 | 
				
			||||||
target_link_libraries(Pong ${SDL2_LIBRARIES} ${SDL2_GFX_LIBRARY} ${SDL2_TTF_LIBRARY})
 | 
					target_link_libraries(Pong ${SDL2_LIBRARIES} ${SDL2_GFX_LIBRARY} ${SDL2_TTF_LIBRARY})
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										13
									
								
								src/Game.h
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								src/Game.h
									
									
									
									
									
								
							@@ -10,6 +10,7 @@
 | 
				
			|||||||
#include "VisibleObjects/PlayerPaddle.h"
 | 
					#include "VisibleObjects/PlayerPaddle.h"
 | 
				
			||||||
#include "VisibleObjects/Score.h"
 | 
					#include "VisibleObjects/Score.h"
 | 
				
			||||||
#include "TextScreen.h"
 | 
					#include "TextScreen.h"
 | 
				
			||||||
 | 
					#include "StartScreen.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum class GameState {
 | 
					enum class GameState {
 | 
				
			||||||
    START_SCREEN, GAME, END_SCREEN
 | 
					    START_SCREEN, GAME, END_SCREEN
 | 
				
			||||||
@@ -20,7 +21,8 @@ private:
 | 
				
			|||||||
    Ball *ball;
 | 
					    Ball *ball;
 | 
				
			||||||
    Score *score;
 | 
					    Score *score;
 | 
				
			||||||
    PlayerPaddle *leftPaddle, *rightPaddle;
 | 
					    PlayerPaddle *leftPaddle, *rightPaddle;
 | 
				
			||||||
    TextScreen *startScreen, *endScreen;
 | 
					    StartScreen *startScreen;
 | 
				
			||||||
 | 
					    TextScreen *endScreen;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
protected:
 | 
					protected:
 | 
				
			||||||
    GameState gameState;
 | 
					    GameState gameState;
 | 
				
			||||||
@@ -37,7 +39,7 @@ public:
 | 
				
			|||||||
        };
 | 
					        };
 | 
				
			||||||
        score = new Score(5, &this->screenSize, func);
 | 
					        score = new Score(5, &this->screenSize, func);
 | 
				
			||||||
        ball = new Ball(&this->screenSize, leftPaddle, rightPaddle, score);
 | 
					        ball = new Ball(&this->screenSize, leftPaddle, rightPaddle, score);
 | 
				
			||||||
        startScreen = new TextScreen("Welcome to Pong!\nPress any key to get started...", &this->screenSize);
 | 
					        startScreen = new StartScreen(&this->screenSize, 4);
 | 
				
			||||||
        endScreen = new TextScreen("", &this->screenSize);
 | 
					        endScreen = new TextScreen("", &this->screenSize);
 | 
				
			||||||
        gameState = GameState::START_SCREEN;
 | 
					        gameState = GameState::START_SCREEN;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -76,6 +78,8 @@ public:
 | 
				
			|||||||
        switch (gameState) {
 | 
					        switch (gameState) {
 | 
				
			||||||
            case GameState::START_SCREEN:
 | 
					            case GameState::START_SCREEN:
 | 
				
			||||||
                startScreen->update();
 | 
					                startScreen->update();
 | 
				
			||||||
 | 
					                if (startScreen->isDone())
 | 
				
			||||||
 | 
					                    gameState = GameState::GAME;
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
            case GameState::GAME:
 | 
					            case GameState::GAME:
 | 
				
			||||||
                ball->update();
 | 
					                ball->update();
 | 
				
			||||||
@@ -97,8 +101,9 @@ public:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            switch (gameState) {
 | 
					            switch (gameState) {
 | 
				
			||||||
                case GameState::START_SCREEN:
 | 
					                case GameState::START_SCREEN:
 | 
				
			||||||
                    if (event.type == SDL_KEYDOWN)
 | 
					                    if (event.type == SDL_KEYDOWN && !startScreen->hasStartedCounting())
 | 
				
			||||||
                        gameState = GameState::GAME;
 | 
					                        startScreen->startCountDown();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    return true;
 | 
					                    return true;
 | 
				
			||||||
                case GameState::GAME:
 | 
					                case GameState::GAME:
 | 
				
			||||||
                    handleGameEvent(event);
 | 
					                    handleGameEvent(event);
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										64
									
								
								src/StartScreen.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								src/StartScreen.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,64 @@
 | 
				
			|||||||
 | 
					//
 | 
				
			||||||
 | 
					// Created by Love on 2024-01-29.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "TextScreen.h"
 | 
				
			||||||
 | 
					#include "chrono"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int_least64_t getCurrentEpochTimeMillis() {
 | 
				
			||||||
 | 
					    auto now = std::chrono::system_clock::now();
 | 
				
			||||||
 | 
					    auto now_ms = std::chrono::time_point_cast<std::chrono::milliseconds>(now);
 | 
				
			||||||
 | 
					    auto epoch = now_ms.time_since_epoch();
 | 
				
			||||||
 | 
					    auto value = std::chrono::duration_cast<std::chrono::milliseconds>(epoch);
 | 
				
			||||||
 | 
					    return value.count();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class StartScreen : public TextScreen {
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					    bool hasStartedCounting_ = false;
 | 
				
			||||||
 | 
					    int_least64_t nextMsEpoch = 0;
 | 
				
			||||||
 | 
					    int stepsToDo, stepsDone = 0;
 | 
				
			||||||
 | 
					    bool isDone_ = false;
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    [[nodiscard]] const bool &isDone() const {
 | 
				
			||||||
 | 
					        return isDone_;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    [[nodiscard]] const bool &hasStartedCounting() const {
 | 
				
			||||||
 | 
					        return hasStartedCounting_;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    StartScreen(SDL_Point *screenSize, int seconds)
 | 
				
			||||||
 | 
					            : TextScreen("Welcome to Pong!\nPress any key to get started...", screenSize), stepsToDo(seconds) {
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void update() override {
 | 
				
			||||||
 | 
					        auto now = getCurrentEpochTimeMillis();
 | 
				
			||||||
 | 
					        if (hasStartedCounting_ && nextMsEpoch <= now) {
 | 
				
			||||||
 | 
					            if (stepsDone < stepsToDo) {
 | 
				
			||||||
 | 
					                std::string s = std::to_string(stepsToDo - stepsDone);
 | 
				
			||||||
 | 
					                setText(s);
 | 
				
			||||||
 | 
					                nextMsEpoch = now + 1000;
 | 
				
			||||||
 | 
					                hasUpdated = false;
 | 
				
			||||||
 | 
					                stepsDone++;
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                isDone_ = true;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        TextScreen::update();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void startCountDown() {
 | 
				
			||||||
 | 
					        auto epochMs = getCurrentEpochTimeMillis();
 | 
				
			||||||
 | 
					        nextMsEpoch = epochMs + 1000;
 | 
				
			||||||
 | 
					        hasStartedCounting_ = true;
 | 
				
			||||||
 | 
					        stepsDone = 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -16,7 +16,7 @@ class TextScreen {
 | 
				
			|||||||
private:
 | 
					private:
 | 
				
			||||||
    std::vector<std::string> lines;
 | 
					    std::vector<std::string> lines;
 | 
				
			||||||
    TTF_Font *font;
 | 
					    TTF_Font *font;
 | 
				
			||||||
    bool hasUpdated;
 | 
					    SDL_Point *screenSize;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Regular
 | 
					    // Regular
 | 
				
			||||||
    std::vector<SDL_Rect> positions;
 | 
					    std::vector<SDL_Rect> positions;
 | 
				
			||||||
@@ -29,13 +29,16 @@ private:
 | 
				
			|||||||
    std::vector<SDL_Surface *> shadowSurfaces;
 | 
					    std::vector<SDL_Surface *> shadowSurfaces;
 | 
				
			||||||
    const int shadowOffset = 3;
 | 
					    const int shadowOffset = 3;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					protected:
 | 
				
			||||||
 | 
					    bool hasUpdated;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
     * @param text This class takes care of freeing text
 | 
					     * @param text This class takes care of freeing text
 | 
				
			||||||
     * @param screenSize This won't be freed by this class
 | 
					     * @param screenSize This won't be freed by this class
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    TextScreen(const std::string& text, SDL_Point *screenSize) : hasUpdated(false) {
 | 
					    TextScreen(const std::string &text, SDL_Point *screenSize) : hasUpdated(false), screenSize(screenSize) {
 | 
				
			||||||
        if (defaultFontPath == nullptr) {
 | 
					        if (defaultFontPath == nullptr) {
 | 
				
			||||||
            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);
 | 
				
			||||||
@@ -46,7 +49,17 @@ public:
 | 
				
			|||||||
            exit(-1);
 | 
					            exit(-1);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        initPositions(text);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					    void initPositions(const std::string &text) {
 | 
				
			||||||
        lines = splitString(text, '\n');
 | 
					        lines = splitString(text, '\n');
 | 
				
			||||||
 | 
					        surfaces.clear();
 | 
				
			||||||
 | 
					        shadowSurfaces.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());
 | 
				
			||||||
@@ -67,9 +80,9 @@ public:
 | 
				
			|||||||
            positions.push_back(regularPosition);
 | 
					            positions.push_back(regularPosition);
 | 
				
			||||||
            shadowPositions.push_back(shadowPosition);
 | 
					            shadowPositions.push_back(shadowPosition);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
    ~TextScreen() {
 | 
					    ~TextScreen() {
 | 
				
			||||||
        if (font)
 | 
					        if (font)
 | 
				
			||||||
            TTF_CloseFont(font);
 | 
					            TTF_CloseFont(font);
 | 
				
			||||||
@@ -80,7 +93,7 @@ public:
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void draw(SDL_Renderer *renderer) {
 | 
					    virtual void draw(SDL_Renderer *renderer) {
 | 
				
			||||||
        for (int i = 0; i < surfaces.size(); ++i) {
 | 
					        for (int i = 0; i < surfaces.size(); ++i) {
 | 
				
			||||||
            // Draw shadow
 | 
					            // Draw shadow
 | 
				
			||||||
            SDL_Texture *shadowTexture = SDL_CreateTextureFromSurface(renderer, shadowSurfaces[i]);
 | 
					            SDL_Texture *shadowTexture = SDL_CreateTextureFromSurface(renderer, shadowSurfaces[i]);
 | 
				
			||||||
@@ -98,8 +111,9 @@ public:
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void setText(std::string &replaceText) {
 | 
					    void setText(const std::string &replaceText) {
 | 
				
			||||||
        lines = splitString(replaceText, '\n');
 | 
					        lines = splitString(replaceText, '\n');
 | 
				
			||||||
 | 
					        initPositions(replaceText);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void replaceCharAtIndex(char c, int line, int index) {
 | 
					    void replaceCharAtIndex(char c, int line, int index) {
 | 
				
			||||||
@@ -118,7 +132,7 @@ public:
 | 
				
			|||||||
        lines[line][index] = c;
 | 
					        lines[line][index] = c;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void update() {
 | 
					    virtual void update() {
 | 
				
			||||||
        if (hasUpdated)
 | 
					        if (hasUpdated)
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user