반응형
화면 전환과 UI 요소
게임 개발에서 화면 전환과 사용자 인터페이스(UI)는 중요한 요소입니다. 오늘은 SFML을 사용하여 화면을 전환하고, 기본적인 UI 요소를 구현하는 방법을 학습하겠습니다.
화면 전환
화면 전환은 게임의 다양한 상태(예: 메인 메뉴, 게임 플레이, 게임 오버 등) 간의 전환을 의미합니다. 이를 구현하기 위해 상태(State) 패턴을 사용할 수 있습니다.
상태 패턴 구현
- 게임 상태 인터페이스 정의:
GameState
라는 인터페이스(혹은 추상 클래스)를 정의합니다. 이 클래스는 각 상태에서 필요한 공통 메서드를 선언합니다.
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;
};
- 구체적인 상태 클래스 정의:
MainMenuState
와PlayState
와 같은 구체적인 상태 클래스를 정의합니다.
class MainMenuState : public GameState {
public:
void handleEvent(sf::Event& event) override {
if (event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Enter) {
// 게임 시작 (상태 전환)
// 게임 상태를 PlayState로 변경하는 코드
}
}
void update(float deltaTime) override {
// 메인 메뉴 업데이트 로직
}
void render(sf::RenderWindow& window) override {
window.clear(sf::Color::Blue);
// 메인 메뉴 렌더링 로직
window.display();
}
};
class PlayState : public GameState {
public:
void handleEvent(sf::Event& event) override {
if (event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Escape) {
// 메인 메뉴로 돌아가기 (상태 전환)
// 게임 상태를 MainMenuState로 변경하는 코드
}
}
void update(float deltaTime) override {
// 게임 플레이 업데이트 로직
}
void render(sf::RenderWindow& window) override {
window.clear(sf::Color::Green);
// 게임 플레이 렌더링 로직
window.display();
}
};
- 게임 상태 관리:
Game
클래스를 정의하여 상태를 관리합니다.
class Game {
public:
Game() : window(sf::VideoMode(800, 600), "State Pattern Example") {
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;
}
private:
sf::RenderWindow window;
GameState* currentState;
MainMenuState mainMenuState;
PlayState playState;
};
- 상태 전환 구현:
- 상태 전환을 위해
MainMenuState
와PlayState
에서Game
객체를 참조하여 상태를 변경합니다.
- 상태 전환을 위해
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;
};
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;
};
int main() {
Game game;
game.run();
return 0;
}
기본적인 UI 요소
UI 요소는 게임 인터페이스의 일부분으로, 버튼, 텍스트, 슬라이더 등 다양한 형태로 존재합니다. SFML을 사용하여 간단한 버튼을 구현해 보겠습니다.
버튼 클래스 정의
- 버튼 클래스 구현:
class Button {
public:
Button(float x, float y, float width, float height, const std::string& text) {
shape.setPosition(sf::Vector2f(x, y));
shape.setSize(sf::Vector2f(width, height));
shape.setFillColor(sf::Color::Red);
if (!font.loadFromFile("arial.ttf")) {
std::cerr << "Error loading font" << std::endl;
}
buttonText.setFont(font);
buttonText.setString(text);
buttonText.setCharacterSize(24);
buttonText.setFillColor(sf::Color::White);
buttonText.setPosition(x + 10, y + 10);
}
void render(sf::RenderWindow& window) {
window.draw(shape);
window.draw(buttonText);
}
bool isClicked(sf::Vector2f mousePos) {
return shape.getGlobalBounds().contains(mousePos);
}
private:
sf::RectangleShape shape;
sf::Text buttonText;
sf::Font font;
};
- 버튼 사용:
class MainMenuState : public GameState {
public:
MainMenuState(Game* game) : game(game), startButton(300.0f, 250.0f, 200.0f, 50.0f, "Start Game") {}
void handleEvent(sf::Event& event) override {
if (event.type == sf::Event::MouseButtonPressed) {
if (event.mouseButton.button == sf::Mouse::Left) {
if (startButton.isClicked(sf::Vector2f(event.mouseButton.x, event.mouseButton.y))) {
game->changeState(game->getPlayState());
}
}
}
}
void update(float deltaTime) override {}
void render(sf::RenderWindow& window) override {
window.clear(sf::Color::Blue);
startButton.render(window);
window.display();
}
private:
Game* game;
Button startButton;
};
결론
오늘은 화면 전환과 UI 요소를 구현하는 방법을 학습했습니다. 상태 패턴을 사용하여 다양한 게임 상태 간의 전환을 구현하고, SFML을 사용하여 간단한 버튼 UI 요소를 추가했습니다. 질문이나 추가적인 피드백이 있으면 언제든지 댓글로 남겨 주세요. 내일은 "Day 15: 게임 이벤트 처리"에 대해 학습하겠습니다.
반응형
'-----ETC----- > C++ 게임 개발 시리즈' 카테고리의 다른 글
[C++ 게임 개발 시리즈] Day 16: 플레이어 입력 처리 (0) | 2024.08.01 |
---|---|
[C++ 게임 개발 시리즈] Day 17: 게임 상태 관리 (0) | 2024.08.01 |
[C++ 게임 개발 시리즈] Day 15: 게임 이벤트 처리 (0) | 2024.08.01 |
[C++ 게임 개발 시리즈] Day 12: 2D 물리 엔진 기초 (Box2D) (0) | 2024.08.01 |
[C++ 게임 개발 시리즈] Day 13: 충돌 처리와 반응 (0) | 2024.08.01 |