mirror of
https://github.com/lov3b/Pong.git
synced 2025-01-18 20:50:12 +01:00
start screen working
This commit is contained in:
parent
5c87e2d918
commit
a86a3c170a
@ -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;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user