반응형
게임 상태 관리
게임 상태 관리는 게임이 다양한 상태(예: 메인 메뉴, 게임 플레이, 일시 정지, 게임 오버 등)를 가질 수 있도록 하는 중요한 개념입니다. 상태 패턴(State Pattern)을 사용하여 이러한 상태 전환을 관리할 수 있습니다.
상태 패턴(State Pattern)
상태 패턴은 객체의 상태에 따라 다른 동작을 수행하도록 하는 디자인 패턴입니다. 이를 통해 상태 전환을 간단하고 명확하게 관리할 수 있습니다.
게임 상태 인터페이스 정의
먼저, 게임 상태 인터페이스를 정의합니다. 이 인터페이스는 각 상태에서 필요한 공통 메서드를 선언합니다.
class GameState {
public:
virtual ~GameState() {}
virtual void handleEvent(sf::Event& event) = 0;
virtual void update(float deltaTime) = 0;
virtual void render(sf::RenderWindow& window) = 0;
};
구체적인 상태 클래스 정의
그 다음, 메인 메뉴 상태와 게임 플레이 상태와 같은 구체적인 상태 클래스를 정의합니다.
class MainMenuState : public GameState {
public:
MainMenuState(Game* game) : game(game) {}
void handleEvent(sf::Event& event) override {
if (event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Enter) {
game->changeState(game->getPlayState());
}
}
void update(float deltaTime) override {}
void render(sf::RenderWindow& window) override {
window.clear(sf::Color::Blue);
// 메인 메뉴 렌더링 로직
window.display();
}
private:
Game* game;
};
class PlayState : public GameState {
public:
PlayState(Game* game) : game(game) {}
void handleEvent(sf::Event& event) override {
if (event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Escape) {
game->changeState(game->getMainMenuState());
}
}
void update(float deltaTime) override {
// 게임 플레이 업데이트 로직
}
void render(sf::RenderWindow& window) override {
window.clear(sf::Color::Green);
// 게임 플레이 렌더링 로직
window.display();
}
private:
Game* game;
};
게임 상태 관리 클래스 정의
게임 상태를 관리하는 Game
클래스를 정의합니다. 이 클래스는 현재 상태를 보관하고, 상태 전환을 처리합니다.
class Game {
public:
Game() : window(sf::VideoMode(800, 600), "State Pattern Example"),
mainMenuState(this), playState(this), currentState(&mainMenuState) {}
void run() {
sf::Clock clock;
while (window.isOpen()) {
sf::Event event;
while (window.pollEvent(event)) {
if (event.type == sf::Event::Closed)
window.close();
currentState->handleEvent(event);
}
float deltaTime = clock.restart().asSeconds();
currentState->update(deltaTime);
currentState->render(window);
}
}
void changeState(GameState* state) {
currentState = state;
}
GameState* getMainMenuState() { return &mainMenuState; }
GameState* getPlayState() { return &playState; }
private:
sf::RenderWindow window;
GameState* currentState;
MainMenuState mainMenuState;
PlayState playState;
};
전체 코드
다음은 전체 코드입니다. 이 코드는 게임 상태 관리를 위해 상태 패턴을 사용합니다.
#include <SFML/Graphics.hpp>
#include <SFML/Window.hpp>
#include <SFML/System.hpp>
#include <iostream>
class GameState;
class Game {
public:
Game();
void run();
void changeState(GameState* state);
GameState* getMainMenuState();
GameState* getPlayState();
private:
sf::RenderWindow window;
GameState* currentState;
MainMenuState mainMenuState;
PlayState playState;
};
class GameState {
public:
virtual ~GameState() {}
virtual void handleEvent(sf::Event& event) = 0;
virtual void update(float deltaTime) = 0;
virtual void render(sf::RenderWindow& window) = 0;
};
class MainMenuState : public GameState {
public:
MainMenuState(Game* game) : game(game) {}
void handleEvent(sf::Event& event) override {
if (event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Enter) {
game->changeState(game->getPlayState());
}
}
void update(float deltaTime) override {}
void render(sf::RenderWindow& window) override {
window.clear(sf::Color::Blue);
window.display();
}
private:
Game* game;
};
class PlayState : public GameState {
public:
PlayState(Game* game) : game(game) {}
void handleEvent(sf::Event& event) override {
if (event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Escape) {
game->changeState(game->getMainMenuState());
}
}
void update(float deltaTime) override {}
void render(sf::RenderWindow& window) override {
window.clear(sf::Color::Green);
window.display();
}
private:
Game* game;
};
Game::Game() : window(sf::VideoMode(800, 600), "State Pattern Example"),
mainMenuState(this), playState(this), currentState(&mainMenuState) {}
void Game::run() {
sf::Clock clock;
while (window.isOpen()) {
sf::Event event;
while (window.pollEvent(event)) {
if (event.type == sf::Event::Closed)
window.close();
currentState->handleEvent(event);
}
float deltaTime = clock.restart().asSeconds();
currentState->update(deltaTime);
currentState->render(window);
}
}
void Game::changeState(GameState* state) {
currentState = state;
}
GameState* Game::getMainMenuState() { return &mainMenuState; }
GameState* Game::getPlayState() { return &playState; }
int main() {
Game game;
game.run();
return 0;
}
결론
오늘은 상태 패턴을 사용하여 게임 상태를 관리하는 방법을 학습했습니다. 상태 패턴을 사용하면 다양한 게임 상태 간의 전환을 쉽게 관리할 수 있습니다. 질문이나 추가적인 피드백이 있으면 언제든지 댓글로 남겨 주세요. 내일은 "Day 18: 간단한 AI 기초 (상태 머신)"에 대해 학습하겠습니다.
반응형
'-----ETC----- > C++ 게임 개발 시리즈' 카테고리의 다른 글
[C++ 게임 개발 시리즈] Day 18: 간단한 AI 기초 (상태 머신) (0) | 2024.08.01 |
---|---|
[C++ 게임 개발 시리즈] Day 16: 플레이어 입력 처리 (0) | 2024.08.01 |
[C++ 게임 개발 시리즈] Day 14: 화면 전환과 UI 요소 (0) | 2024.08.01 |
[C++ 게임 개발 시리즈] Day 15: 게임 이벤트 처리 (0) | 2024.08.01 |
[C++ 게임 개발 시리즈] Day 12: 2D 물리 엔진 기초 (Box2D) (0) | 2024.08.01 |