본문 바로가기
-----ETC-----/C++로 배우는 게임 엔진 개발

[C++로 배우는 게임 엔진 개발] Day 6: 이벤트 처리 및 입력 시스템 구현

by cogito21_cpp 2024. 8. 1.
반응형

이벤트 처리 및 입력 시스템 구현

오늘은 키보드와 마우스 입력을 처리하고, 게임 내에서 입력을 사용하여 캐릭터를 제어하는 방법을 학습하겠습니다. SDL2와 GLFW를 사용하여 이벤트 처리와 입력 시스템을 구현해 보겠습니다.

1. SDL2를 사용한 이벤트 처리 및 입력 시스템

헤더 파일 수정

include/GameEngine.h 파일에 입력 처리 함수를 추가합니다.

#ifndef GAMEENGINE_H
#define GAMEENGINE_H

#include <SDL2/SDL.h>

class GameEngine {
public:
    GameEngine();
    ~GameEngine();
    bool Initialize(const char* title, int width, int height);
    void Run();
    void Shutdown();

private:
    SDL_Window* window;
    SDL_Renderer* renderer;
    bool isRunning;

    void HandleEvents();
    void Update();
    void Render();
};

#endif // GAMEENGINE_H

 

소스 파일 수정

src/GameEngine.cpp 파일에 이벤트 처리 및 입력 시스템 구현을 추가합니다.

#include "GameEngine.h"
#include <iostream>

GameEngine::GameEngine()
    : window(nullptr), renderer(nullptr), isRunning(false) {}

GameEngine::~GameEngine() {
    Shutdown();
}

bool GameEngine::Initialize(const char* title, int width, int height) {
    if (SDL_Init(SDL_INIT_VIDEO) != 0) {
        std::cerr << "SDL_Init Error: " << SDL_GetError() << std::endl;
        return false;
    }

    window = SDL_CreateWindow(title, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, SDL_WINDOW_SHOWN);
    if (window == nullptr) {
        std::cerr << "SDL_CreateWindow Error: " << SDL_GetError() << std::endl;
        return false;
    }

    renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
    if (renderer == nullptr) {
        std::cerr << "SDL_CreateRenderer Error: " << SDL_GetError() << std::endl;
        return false;
    }

    isRunning = true;
    return true;
}

void GameEngine::Run() {
    while (isRunning) {
        HandleEvents();
        Update();
        Render();
    }
}

void GameEngine::HandleEvents() {
    SDL_Event event;
    while (SDL_PollEvent(&event)) {
        if (event.type == SDL_QUIT) {
            isRunning = false;
        }
        if (event.type == SDL_KEYDOWN) {
            switch (event.key.keysym.sym) {
                case SDLK_ESCAPE:
                    isRunning = false;
                    break;
                // 여기에 추가 입력 처리를 구현합니다.
                default:
                    break;
            }
        }
    }
}

void GameEngine::Update() {
    // 게임 상태 업데이트 로직을 여기에 추가합니다.
}

void GameEngine::Render() {
    // 화면을 검은색으로 지우기
    SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
    SDL_RenderClear(renderer);

    // 빨간색 직사각형 그리기
    SDL_Rect rect = { 200, 150, 400, 300 };
    SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);
    SDL_RenderFillRect(renderer, &rect);

    // 렌더링 결과를 화면에 출력
    SDL_RenderPresent(renderer);
}

void GameEngine::Shutdown() {
    if (renderer) {
        SDL_DestroyRenderer(renderer);
        renderer = nullptr;
    }
    if (window) {
        SDL_DestroyWindow(window);
        window = nullptr;
    }
    SDL_Quit();
}

 

main 파일 수정

src/main.cpp 파일은 그대로 유지합니다.

#include "GameEngine.h"

int main(int argc, char* argv[]) {
    GameEngine gameEngine;

    if (!gameEngine.Initialize("Game Engine", 800, 600)) {
        return -1;
    }

    gameEngine.Run();
    gameEngine.Shutdown();

    return 0;
}

2. GLFW를 사용한 이벤트 처리 및 입력 시스템

헤더 파일 수정

include/GameEngine.h 파일에 입력 처리 함수를 추가합니다.

#ifndef GAMEENGINE_H
#define GAMEENGINE_H

#include <GLFW/glfw3.h>

class GameEngine {
public:
    GameEngine();
    ~GameEngine();
    bool Initialize(const char* title, int width, int height);
    void Run();
    void Shutdown();

private:
    GLFWwindow* window;
    bool isRunning;

    static void KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods);
    void HandleEvents();
    void Update();
    void Render();
};

#endif // GAMEENGINE_H

 

소스 파일 수정

src/GameEngine.cpp 파일에 이벤트 처리 및 입력 시스템 구현을 추가합니다.

#include "GameEngine.h"
#include <iostream>

GameEngine::GameEngine()
    : window(nullptr), isRunning(false) {}

GameEngine::~GameEngine() {
    Shutdown();
}

bool GameEngine::Initialize(const char* title, int width, int height) {
    if (!glfwInit()) {
        std::cerr << "GLFW Initialization failed!" << std::endl;
        return false;
    }

    window = glfwCreateWindow(width, height, title, NULL, NULL);
    if (!window) {
        std::cerr << "GLFW Window creation failed!" << std::endl;
        glfwTerminate();
        return false;
    }

    glfwMakeContextCurrent(window);
    glfwSetKeyCallback(window, KeyCallback);

    isRunning = true;
    return true;
}

void GameEngine::Run() {
    while (isRunning && !glfwWindowShouldClose(window)) {
        HandleEvents();
        Update();
        Render();
        glfwSwapBuffers(window);
    }
}

void GameEngine::KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods) {
    if (action == GLFW_PRESS) {
        switch (key) {
            case GLFW_KEY_ESCAPE:
                glfwSetWindowShouldClose(window, GLFW_TRUE);
                break;
            // 여기에 추가 입력 처리를 구현합니다.
            default:
                break;
        }
    }
}

void GameEngine::HandleEvents() {
    glfwPollEvents();
}

void GameEngine::Update() {
    // 게임 상태 업데이트 로직을 여기에 추가합니다.
}

void GameEngine::Render() {
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);

    // OpenGL 삼각형 그리기
    glBegin(GL_TRIANGLES);
    glColor3f(1.0f, 0.0f, 0.0f);
    glVertex2f(0.0f, 0.5f);
    glColor3f(0.0f, 1.0f, 0.0f);
    glVertex2f(-0.5f, -0.5f);
    glColor3f(0.0f, 0.0f, 1.0f);
    glVertex2f(0.5f, -0.5f);
    glEnd();
}

void GameEngine::Shutdown() {
    if (window) {
        glfwDestroyWindow(window);
        window = nullptr;
    }
    glfwTerminate();
}

 

main 파일 수정

src/main.cpp 파일은 그대로 유지합니다.

#include "GameEngine.h"

int main(int argc, char* argv[]) {
    GameEngine gameEngine;

    if (!gameEngine.Initialize("Game Engine", 800, 600)) {
        return -1;
    }

    gameEngine.Run();
    gameEngine.Shutdown();

    return 0;
}

3. 프로젝트 빌드 및 실행

  1. Visual Studio에서 CMake 프로젝트 열기:
    • Visual Studio를 실행하고, File -> Open -> CMake...를 선택합니다.
    • GameEngine 디렉토리를 선택하여 프로젝트를 엽니다.
  2. SDL2/GLFW 라이브러리 설치:
    • SDL2 또는 GLFW 라이브러리를 프로젝트에 설정합니다.
  3. 프로젝트 빌드:
    • Visual Studio 상단의 Build 메뉴에서 Build All을 선택하여 프로젝트를 빌드합니다.
  4. 프로젝트 실행:
    • Debug 메뉴에서 Start Without Debugging을 선택하여 프로그램을 실행합니다.
    • SDL2를 사용하는 경우, 윈도우 창이 생성되고 ESC 키를 누르면 창이 닫힙니다.
    • GLFW를 사용하는 경우, 윈도우 창이 생성되고 ESC 키를 누르면 창이 닫힙니다.

마무리

오늘은 SDL2와 GLFW를 사용하여 이벤트 처리 및 입력 시스템을 구현했습니다. 다음 단계에서는 게임 루프와 타이밍 관리를 학습하여 프레임 속도를 제어하는 방법을 배워보겠습니다.

질문이나 추가적인 피드백이 있으면 언제든지 댓글로 남겨 주세요.

Day 7 예고

다음 날은 "게임 루프와 타이밍 관리"에 대해 다

룰 것입니다. 프레임 속도를 제어하고, 일정한 간격으로 게임 상태를 업데이트하는 방법을 학습하겠습니다.

반응형