반응형
이벤트 처리 및 입력 시스템 구현
오늘은 키보드와 마우스 입력을 처리하고, 게임 내에서 입력을 사용하여 캐릭터를 제어하는 방법을 학습하겠습니다. 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. 프로젝트 빌드 및 실행
- Visual Studio에서 CMake 프로젝트 열기:
- Visual Studio를 실행하고,
File
->Open
->CMake...
를 선택합니다. GameEngine
디렉토리를 선택하여 프로젝트를 엽니다.
- Visual Studio를 실행하고,
- SDL2/GLFW 라이브러리 설치:
- SDL2 또는 GLFW 라이브러리를 프로젝트에 설정합니다.
- 프로젝트 빌드:
- Visual Studio 상단의
Build
메뉴에서Build All
을 선택하여 프로젝트를 빌드합니다.
- Visual Studio 상단의
- 프로젝트 실행:
Debug
메뉴에서Start Without Debugging
을 선택하여 프로그램을 실행합니다.- SDL2를 사용하는 경우, 윈도우 창이 생성되고 ESC 키를 누르면 창이 닫힙니다.
- GLFW를 사용하는 경우, 윈도우 창이 생성되고 ESC 키를 누르면 창이 닫힙니다.
마무리
오늘은 SDL2와 GLFW를 사용하여 이벤트 처리 및 입력 시스템을 구현했습니다. 다음 단계에서는 게임 루프와 타이밍 관리를 학습하여 프레임 속도를 제어하는 방법을 배워보겠습니다.
질문이나 추가적인 피드백이 있으면 언제든지 댓글로 남겨 주세요.
Day 7 예고
다음 날은 "게임 루프와 타이밍 관리"에 대해 다
룰 것입니다. 프레임 속도를 제어하고, 일정한 간격으로 게임 상태를 업데이트하는 방법을 학습하겠습니다.
반응형
'-----ETC----- > C++로 배우는 게임 엔진 개발' 카테고리의 다른 글
[C++로 배우는 게임 엔진 개발] Day 4: 윈도우 창 생성 (SDL2/GLFW) (0) | 2024.08.01 |
---|---|
[C++로 배우는 게임 엔진 개발] Day 5: 기본 렌더링 파이프라인 이해 (0) | 2024.08.01 |
[C++로 배우는 게임 엔진 개발] Day 7: 게임 루프와 타이밍 관리 (0) | 2024.08.01 |
[C++로 배우는 게임 엔진 개발] Day 8: 2D 그래픽스 기초 (SDL2) (0) | 2024.08.01 |
[C++로 배우는 게임 엔진 개발] Day 9: 스프라이트 렌더링 (0) | 2024.08.01 |