{{ :raylib:raylib.ico |raylib}}
===== 소개 =====
raylib는 c 및 c++를 위한 가벼운 게임 라이브러리 모음집(=프레임워크)이다.
opengl을 기반으로 한다.
언리얼이나 유니티등 거대 게임엔진으로 2d 게임을 만드는 것은 자원낭비일 것이다.
그리고 언리얼등의 게임엔진은 게임이 어떻게 돌아가는지 그 구조를 파악하기가 쉽지 않다.
따라서 코딩 그 자체를 배우고자 하는 사람들은 백지 위에 게임을 만들 수 있는 방법을 찾기 마련인데,
결국 게임이란게 그래픽 라이브러리만 있으면 되므로 최대한 가벼운 그래픽 라이브러리와 기타 편의 도구들이 있으면
게임 프레임워크가 될 것이다.
이렇게 c 언어에 그래픽 기능을 쉽게 해주는 것이 raylib이다.
아마 이 글을 보고 있는 대다수는 한글 입력이 잘 되는지가 궁금할 것이다.
[[raylib:flappybird:raylib_에_한글_출력하기|레이라이브에서 한글 출력하기]]를 참고하라
==== love2d와 다른 점 ====
love2d는 게임 프로그래밈 입문자에게 매우 사랑받는 lua 기반 프레임워크이다.
그런데 love2d는 lua기반이므로 언어 자체의 기능이 떨어진다.
특히 게임의 규모가 커질 수록 결국엔 객체지향 방식으로 코딩을 할 수 밖에 없는데 lua는 객체 지향을 지원해주는 것이 아니므로 별도의 classy 등의 라이브러리를 이용하여 객체지향을 흉내내기 마련이다.
이런식으로 객체지향도 흉내내야 하고, 다른 여러 부족한 언어의 기능도 꼼수를 써야만 하다 보니,
규모가 커질 수록 lua로 만든 프로그램은 더 지저분해질 수 밖에 없다.
간단히 코딩하기 위해 사용하는게 lua인데, 나중에는 더 지저분해지는 아이러니가 생기는 것이다.
참고로, love2d역시 아래에서 이야기할 sdl을 기반으로 만들었다. sdl을 기반으로 lua로 포팅한게 바로 love2인 것이다.
따라서 엄밀히 말하면 love2와 raylib를 비교하는 것은 옳지 않다.
raylib는 sdl과 비교하는 것이 옳다. opengl을 래핑한게 바로 sdl과 raylib이며,
그 sdl을 다시 루아로 래핑하여 루아 언어로 포팅한게 love2d인 것이다.
즉 raylib는 sdl과 동급이므로 루아, c#, go lang등 다양한 언어로 포팅되어 있다.
==== sdl, sfml과 다른 점 ====
sdl과 sfml도 모두 c를 기반으로 한 그래픽 라이브러리이다.
단 raylib가 더 최신이고, 업데이트도 계속 이루어지고 있다.
vs놀이는 외국인도 많이 하는지, 이러한 vs 질문이 자주 올라왔나 봐다.
따라서 raylib를 만든 raysan은 Github에 본인의 관점에서 sdl과의 비교를 한 적 아티클을 올린 적이 있다.
[[https://gist.github.com/raysan5/17392498d40e2cb281f5d09c0a4bf798|raylib vs SDL - A libraries comparison]]
==== 기타 ====
itch.io에 가보면 ruby 를 기반으로 한 dragon ruby 게임 툴킷도 존재하는 등
다양한 2d 게임 프레임워크가 존재한다.
각자 취향대로 선택하면 된다.
난 어차피 c와 c++을 공부하기 위해 이번에는 raylib를 선택했다.
===== 설치 ======
[[https://www.raylib.com/|raylib 공식 홈페이지]]에 가면 다운로드를 할 수 있다.
기부를 받고 있으나 0달러로 설정해서 공짜로 다운로드 하더라도 제약은 없다.
win64에 minGW버전을 설치하면 가장 무난하다.
minGW에는 c++을 컴파일하는 g++도 같이 들어있으므로 무난하다.
참고로, Github에서 raylib 소스파일을 다운 받은 후 이를 컴파일 하여 사용하고 싶으면,
[[raylib:컴파일_및_makefile|컴파일 및 Makefile]]을 참조하라
===== 사용할 템플릿 파일 =====
raylib를 설치하면 바탕화면에 기본적으로 notepad++이 설치된다.
이 notepad++은 raylib를 위해 npp exec 설정을 미리 해놨다.
따라서 [f6]만 누르면 알아서 컴파일을 한 후 실행해 준다.
만약에 notepad++이 싫다면 vs code 등으로 컴파일해도 된다.
raylib폴더에는 각종 에디터를 위한 컴파일 템플릿이 존재한다.
c:/raylib/raylib/projects
폴더에는 각종 에딩터를 위한 템플릿들이 놓여 있다. 만약 vs code를 사용한다면 vs code 템플릿을 사용하면 된다.
그런데 앞으로는 순수 c가 아니라 객체지향이 가능한 cpp를 이용할 것이므로 추가적인 조치가 필요하다.
[[raylib:raylib_를_cpp로_vs_code_에서_사용하기|raylib를 cpp로 VS CODE에서 사용하기]]를 참조하라
===== 잠깐 장난쳐 보기 =====
==== 타이틀과 텍스트를 바꿔보자 ====
36줄에 있는 윈도우 창의 타이틀을 다음으로 바꾸자
InitWindow(screenWidth, screenHeight, "First Game Hello!");
55줄에 있는 텍스트를 다음으로 바꾸자.
DrawText("Hello World! This is my first raylib program!!", 190, 200, 20, MAROON);
맨 뒤에 'MAROON'이라고 해서 칼라 코드를 바꿨다. 칼라코드는 보통 4개의 8비트 숫자로 이루어지나,
몇몇개는 매크로가 선언되어 있다.
선언되어 있는 매크로는 [[https://www.raylib.com/cheatsheet/cheatsheet.html|cheatsheets]] 에서 살펴보면 된다.
==== 화면 가운데에 원을 그리고 키보드로 옮겨 보자 ====
일단 원을 그릴 변수를 미리 선언하자. 스크린화면을 선언한 const 변수 뒤에 다음과 같이 변수를 선언하자
int x = 400;
int y = 225;
int r = 50;
DrawText함수 뒤에 다음과 같이 DrawCircle 함수를 호출하자. raylib함수는 [[https://www.raylib.com/cheatsheet/cheatsheet.html|cheatsheets]]를 참조하면 된다.
DrawCircle(x, y, r, PURPLE);
이제 update 부분에 키보드 인풋을 받아보자. 키보드 좌키를 누르면 x를 -2, 우키를 누르면 x를 2.. 위키를 누르면 y를 -2. 아래키를 누르면 y를 +2로 하는 코드를 짜보자. 이렇게 하면 될 것이다. [[https://www.raylib.com/examples/core/loader.html?name=core_input_keys|raylib에서 공개한 공식 샘플]]도 참고하자
if (IsKeyDown(KEY_RIGHT)) x += 2;
if (IsKeyDown(KEY_LEFT)) x -= 2;
if (IsKeyDown(KEY_UP)) y -= 2;
if (IsKeyDown(KEY_DOWN)) y += 2;
키보드 화살표 키를 누르면 보라색 원이 이동함을 알 수 있다.
==== 정리 ====
지금까지를 정리하면 다음 코드가 된다.
#include "raylib.h"
//------------------------------------------------------------------------------------
// Program main entry point
//------------------------------------------------------------------------------------
int main(void)
{
// Initialization
//--------------------------------------------------------------------------------------
const int screenWidth = 800;
const int screenHeight = 450;
int x = 400;
int y = 225;
int r = 50;
InitWindow(screenWidth, screenHeight, "First Game Hello!");
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
//--------------------------------------------------------------------------------------
// Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
{
// Update
//----------------------------------------------------------------------------------
// TODO: Update your variables here
//----------------------------------------------------------------------------------
if (IsKeyDown(KEY_RIGHT)) x += 2;
if (IsKeyDown(KEY_LEFT)) x -= 2;
if (IsKeyDown(KEY_UP)) y -= 2;
if (IsKeyDown(KEY_DOWN)) y += 2;
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(RAYWHITE);
DrawText("Hello There", 190, 200, 20, MAROON);
DrawCircle(x, y, r, PURPLE);
EndDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}
===== 객체지향으로 만들어 보기 =====
==== game.h ====
순수 c언어로 배울 수도 있겠지만 아무래도 lua 기반의 love2d보다 raylib를 선택한 이유는 객체지향을 위해서다.
따라서 처음부터 객체지향으로 코드를 짜도록 하자.
game.h는 다음과 같이 만들자
#pragma once
#include
#include "raylib.h"
class Game
{
public :
Game(int width, int height, std::string title);
~Game() noexcept;
bool GameShouldClose() const;
void Tick();
private:
void Draw();
void Update();
};
game.h 헤더파일에서 raylib.h를 참조하도록 하였고, game클래스를 생성할 때 윈도우 창을 만들고, game클래스가 파괴되면 윈도우 창도 사라지도록 하였다.
==== game.cpp 파일 ====
각 선언에 따른 Game 클래스의 구현은 다음과 같이 하도록 하였다.
#include "game.h"
#include "raylib.h"
Game::Game(int width, int height, std::string title)
{
InitWindow(width, height, title.c_str());
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
}
Game::~Game()
{
CloseWindow(); // Close window and OpenGL context
}
bool Game::GameShouldClose() const
{
return WindowShouldClose();
}
void Game::Tick()
{
BeginDrawing();
Update();
Draw();
EndDrawing();
}
void Game::Draw()
{
ClearBackground(RAYWHITE);
}
void Game::Update()
{
}
==== main.cpp 파일 ====
먼저 game 클래스를 생성하자. game 클래스를 생성하면 raylib의 Iniwindow를 불러오게 될 것이다.
Game game {screenWidth, screenHeight, "First OOP Game"};
while 문의 windowsshouldclose((Escape키나 창의 x버튼을 눌러서 종료하는 것을 판단하는 것이다.))도 Game클래스 내에 집어 넣었다. 어차피 종료 여부를 묻는 것이니까 굳이 Game클래스 내에 넣을 필요가 있을까 싶기도 하지만, 어찌되었건 모든 Game 로직을 Game클래스 내에서 처리한다는 의미는 있을 것이다.
Game클래스에서 Game 로직을 구현할 것이므로 while문에는 game.Tick()만 호출하게 된다.
// Main game loop
while (!game.GameShouldClose()) // Detect window close button or ESC key
{
game.Tick();
}
==== game.h 파일 ====
전에 쓰던 변수들을 모두 game.h로 옮겼다.
#pragma once
#include "string.h"
#include "raylib.h"
class Game
{
public :
Game(int width, int height, std::string title);
~Game() noexcept;
bool GameShouldClose() const;
void Tick();
private:
void Draw();
void Update();
int x = 400;
int y = 225;
int r = 50;
};
==== game.cpp 파일 ====
Update와 Draw를 각각 나누어서 코드를 짜게 되니까 훨씬 보기에 좋다.
#include "game.h"
#include "raylib.h"
Game::Game(int width, int height, std::string title)
{
InitWindow(width, height, title.c_str());
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
}
Game::~Game()
{
CloseWindow(); // Close window and OpenGL context
}
bool Game::GameShouldClose() const
{
return WindowShouldClose();
}
void Game::Tick()
{
BeginDrawing();
Update();
Draw();
EndDrawing();
}
void Game::Draw()
{
// Draw
//----------------------------------------------------------------------------------
ClearBackground(RAYWHITE);
DrawText("Hello There", 190, 200, 20, MAROON);
DrawCircle(x, y, r, PURPLE);
//----------------------------------------------------------------------------------
}
void Game::Update()
{
// Update
//----------------------------------------------------------------------------------
// TODO: Update your variables here
//----------------------------------------------------------------------------------
if (IsKeyDown(KEY_RIGHT)) x += 2;
if (IsKeyDown(KEY_LEFT)) x -= 2;
if (IsKeyDown(KEY_UP)) y -= 2;
if (IsKeyDown(KEY_DOWN)) y += 2;
}
지금까지의 파일은 다음 압축파일로 만들었다.
{{ :helloraylib.zip |}}
===== VS CODE 템플릿 파일 =====
raylib는 순수 c를 위한 에디터 설정파일만 있으므로 VS Code에서 c++로 만든 raylib 이용 파일을 컴파일하려면 추가 조작이 필요하다.
[[raylib:raylib_를_cpp로_vs_code_에서_사용하기|raylib를 cpp로 VS CODE에서 사용하기]] 문서를 참조하자
앞으로는 다음의 템플릿을 이용하면 vs code에서 raylib를 쉽게 컴파일하고 실행할 수 있다.
{{ :raylib:raylibtemplate.zip |Raylib 템플릿 파일}}
===== 더보기 =====
이제 실제로 게임을 만들어보자
[[raylib:pong게임|Raylib로 Pong게임 만들기]]와
[[raylib:flappybird:flappy_bird_만들기|C++와 Raylib로 플래피버드 만들기]]를 읽어보자.
그런데 의외로 많은 사람들이 C 및 c++의 컴파일을 하는 방법을 모르는 사람들이 많다.
[[raylib:컴파일_및_makefile|컴파일 및 Makefile]]은 꼭 일독할 것을 권한다.