2D Game Engine 만들기 – tutorial with SDL
1. SDL Tutorial Basics
We all have to start somewhere
Tim Jones | October 17th, 2007
<목적>
These tutorials are meant to teach someone with some experience using C++, or perhaps another programming language. If you have a hard time following certain ideas related to the code itself and not conceptual ideas (those relating to games), then I urge you to first read our tutorials that explain the C++ programming language[1].
It's not vital to understand everything about C++, but every little bit will help later on.
이러한 강좌는 c + +, 또는 아마도 다른 프로그래밍 언어를 사용 하 여 약간의 경험을 가진 사람을 가르치는 대상으로 한다(에 의미가 있다).소스코드와의 관련된 어떤 아이디어나 (게임에 관련된) 개념적이지 않은 아이디어등을 (이해하면서) 따라오는 것이 힘든 시간이 된다면, c++ 프로그래밍 언어를 설명하는 강좌를 먼저 읽으라고 충고한다. C++에 대한 모든 것을 이해 하는 것이 중요 하지 않습니다 하지만 모든것이 약간은 나중에 도움이 될 것입니다.
**** <Compiler와 IDE>설정은 별도 참조
Important Note: I use #include <SDL.h> below (and in all other tutorials), when it really should be #include <SDL/SDL.h>. I moved all of my header files up a directory. So, if you want to follow my code exactly, move all your header files up a directory so they are in the include folder, not the SDL folder. Otherwise, use #include instead. Sorry for all the confusion this has caused.
중요 참고: 아래에서 #include <sdl.h>를 사용(및 모든 다른 자습서에서) 하는데, 그것 진짜로 사용하는 경우는 #include <sdl/sdl.h>를 사용한다. 나는 모든 내 헤더 파일를
상위 디렉터리를 이동 했다. 그래서, 내 코드를 정확 하 게 수행 하려는 경우, 그래서 그들은 SDL 폴더가 아닌 include폴더에서 모든 헤더 파일를 상위디렉터리를 이동해야한다. 그렇지 않으면, 대신에 #include를 사용하라. 이 모든 혼란을 드려 죄송 발생 했습니다.
Start a new "blank" project, calling it whatever you want. Save it some place. Click on "Project" on the menu bar, and then click on "Properties." A dialog will open; click on the "Project's build options..." button on the bottom right. Click on the "Linker Settings" tab and add the following to the list under "Link libraries":
당신이 무엇을 원하든지 그것을 호출 새 "빈" 프로젝트를 시작 합니다. 그것은 어떤 장소를 저장 합니다. 메뉴 표시줄에서 " Project "에 클릭 하 고 " Properties "을 클릭 대화 상자를 열 것 이다; 오른쪽 하단에 "프로젝트의 빌드 옵션..." 버튼을 클릭 합니다. " Linker Settings " 탭을 클릭 하 고 " Link libraries " 아래에 있는 목록에 다음 추가 합니다.
mingw32 SDLmain SDL
The order is important, so use the arrows to rearrange the list until it matches what is shown above. If you are having a little trouble figuring out what we are doing, we're simply "linking" code together, or, in other words, we're taking the SDL code and combining it with our own. We do this by using the include files to compile, and the lib files to link.
And once done, our code is put together to make one application.
순서가 중요하며, 그래서 화살표를 사용 하 여 무엇을 위의 일치 될 때까지 목록을 다시 정렬 합니다. 조금 문제가 있는 경우 (우리가 무엇을 하 고 있습니다 알아내는 우리 있어) 단순히 " linking " 코드 함께 하거나, 다른 말로 하면, 우리가 SDL 코드를 결합하 고 (우리 자신의 결합 있어). 우리를 컴파일하려면 include 파일 및 lib 파일 연결을 사용 하 여 (이렇게). 일단, 우리의 코드를 함께 넣어 하나의 응용 프로그램을 만들려고 합니다.
Click Ok twice, and you should be all set to go!
확인을 두 번 클릭 하 고, 당신은 모든 설정해야합니다!
<CApp Class>
Let's create two new files called CApp.h, and CApp.cpp; these will serve as the core for our program. First, open CApp.h and add the following code, in here is where our tutorial will really begin:
CApp.h, 및 CApp.cpp; 라는 두 개의 새 파일을 만들고, 이러한 우리의 프로그램에 대 한 코어 될 것입니다. 첫째, CApp.h을 열고 다음 코드를 추가, 여기에는 우리의 자습서 정말 시작 됩니다.
1 2 3 4 5 6 7 8 9 10 11 |
#ifndef _CAPP_H_ #define _CAPP_H_ #include <SDL.h> class CApp { public: CApp(); int OnExecute(); }; #endif |
Now, open up CApp.cpp and add the following code:
1 2 3 4 5 6 7 8 9 10 11 |
#include "CApp.h" CApp::CApp() { } int CApp::OnExecute() { return 0; } int main(int argc, char* argv[]) { CApp theApp; return theApp.OnExecute(); } |
The CApp class is setting the stage for our entire program.
<Game & 5 function>
Let me step aside to take special note of how games are typically setup. Most games consist of 5 functions that handle how the game processes. These processes are typically:
CApp 클래스는 우리의 전체 프로그램에 대한 단계(무대)를 설정 합니다.
어떻게 게임은 구성되는지에 대한( 잠시 벗어나서) 특별히 적어본다. 대부분의 게임은 처리하는 방법이 5가지 함수로 이루어져 있습니다. 이러한 프로세스는 일반적으로:
Initialize - 초기화
This function handles all the loading of data, whether it be textures, maps, NPCs, or whatever.
이 함수는 텍스처, 지도, NPCs, 또는 무엇이든지, 데이터의 모든것을 로드를 처리 합니다.
Event – 이벤트 (처리)
This function handles all input events from the mouse, keyboard, joysticks, or other devices.
이 함수는 마우스, 키보드, 조이스틱,또는 다른 장치로 부터의 모든 입력된 이벤트를 처리합니다.
Loop – 반복(순환) : 데이터 조작
This function handles all the data updates, such as a NPCs moving across the screen, decreasing your health bar, or whatever
감소하는 생명바, 화면을 가로질러 이동 하는 NPCs, 또는 무엇이든 , 모든 데이터의
업데이트(최신값으로 갱신)를 처리하는 함수이다.
Render – 화면출력(모델->영상)
This function handles all the rendering of anything that shows up on the screen. It does NOT handle data manipulation, as this is what the Loop function is supposed to handle.
이 함수는 아무것도 화면에 나타나기 모든 렌더링을 처리 합니다. 그것은 데이터 조작을 처리 하지 않습니다 ,이것은 루프 함수가 무엇을 처리할 해야 하는 것이기 때문입니다.
Cleanup - 정리
This function simply cleans up any resources loaded, and insures a peaceful quitting of the game.
이 함수는 단순히 로드 하는 모든 리소스를 정리 하 고 지키는 게임의 평화로운 종료.
It's important to understand that games are one gigantic loop. Within this loop we find events, update data, and render pictures. Thus, the basic structure could be thought of as:
게임에는 하나의 거대한 루프를 이해 하는 것이 중요 하다. 이 루프 내에서 데이터를 업데이트(갱신), 사진 렌더링, 이벤트를 찾는다. 따라서,기본 구조는 다음과 같이 생각될수 있다 :
1 2 3 4 5 6 7 8 9 |
Initialize(); // 1 while(true) { Events(); // 2 Loop(); // 3 Render(); // 4 } Cleanup(); // 5 |
Each iteration of the loop we do something with data, and render accordingly. Events are extra, as a means for the user to manipulate data as well. In that sense, Events aren't required to make a game, but are needed when you want the user to be able to manipulate data (such as move a NPC to the left).
우리 데이터를 갖고 뭔가를 하고 그에 따라 렌더링 하는 루프의 각 반복. 이벤트는 사용자 뿐만 아니라 데이터를 조작 하는 수단으로 추가 합니다. 그런 의미에서 이벤트는 게임을 만들 필요가 없습니다, 하지만 (왼쪽으로 이동하는 NPC와 같은) 사용자가 데이터를 조작할 수 있게 하려는 경우 필요 합니다.
Let's clarify this idea with an example. Say we have our Knight, the hero of the game. All we want to do is simply have him move around. If I press left, he goes left. We need to figure out how to do this within a loop.
Firstly, we know we want to check for events (keyboard events). Since Events are a means to manipulate data, we also know we'll need some sort of variables to modify. Then we can use these variables to render our Knight appropriatly on the screen. We could have:
예제를 갖고 아이디어를 명확히 하자. 우리는 게임의 영웅인 기사를 갖고. 우리가 하고 싶은 것은 그가 단순히 이동 하는 것입니다. 만약 왼쪽을 누르거면, 그는 왼쪽으로 갑니다. 우리는 루프 내에서 이 수행 하는 방법을 알아낼 필요가 있다.
첫째, 우리는 이벤트 (키보드 이벤트)에 대해 확인하는 것을 알고 있다. 이벤트 데이터를 조작 하는 수단 이기에, 우리는 또한 일종의 변수를 수정 해야 하는 것을 알고있다. 다음 우리는 기사 appropriatly 화면에 렌더링하기위한 여러 변수를 사용할 수 있습니다. 우리가 가질 수 있는:
1 2 3 4 5 6 |
if(Key == LEFT) X--; // left == X-- if(Key == RIGHT) X++; if(Key == UP) Y--; // up == Y-- if(Key == DOWN) Y++;//... somewhere else in our code ... RenderImage(KnightImage, X, Y); // 랜더링 ( 기사이미지, X좌표, Y좌표 ) |
This works because each loop it checks if the key is LEFT, RIGHT, etc., and if so, we decrease or increase a variable. So, if our game is running at 30 frames per second and we press LEFT, then our guy would move to the left 30 pixels per second. If you don't understand the game loop, you soon will. Games need them to function correctly.
이것은 각 키가 왼쪽, 오른쪽 등인지를 확인하고, (그리고 만약 그렇다면), 우리 변수를 증가 또는 감소 한다. 그래서, 우리의 게임을 초당 30 프레임에서 실행 하는 경우 우리가 왼쪽키을 누르고, 그리고 우리의 녀석은 초당 30 픽셀로 왼쪽으로 이동한다.만약 게임 loop를 이해 하지 못한다면, 당신은 곧 이해할 것 이다. 게임은 loop가 제대로 작동 하도록 요구한다.
<CApp class>
Going back to our conceptual code (the 5 functions), we can add these additional pages to our project:
다시 우리의 개념적 코드 (5개 함수)로 돌아가서, 우리의 프로젝트에 이러한 추가 페이지를 추가할 수 있습니다.
CApp_OnInit.cpp
CApp_OnEvent.cpp
CApp_OnLoop.cpp
CApp_OnRender.cpp
CApp_OnCleanup.cpp
Go back to CApp.h, and add the following functions and variables:
CApp.h로 돌아가서, 다음 함수 및 변수를 추가한다 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
#ifndef _CAPP_H_ #define _CAPP_H_ #include <SDL.h> class CApp { private: bool Running; public: CApp(); int OnExecute(); public: bool OnInit(); void OnEvent(SDL_Event* Event); void OnLoop(); void OnRender(); void OnCleanup(); }; #endif |
Go through each of the 5 files we just created and create the function themselves:
방금 만든 5 파일 각각을 살펴보고, 그들의 함수를 만듭니다.
1 2 3 4 5 |
#include "CApp.h" bool CApp::OnInit() { return true; } |
1 2 3 4 |
#include "CApp.h" void CApp::OnEvent(SDL_Event* Event) { } |
1 2 3 4 |
#include "CApp.h" void CApp::OnLoop() { } |
1 2 3 4 |
#include "CApp.h" void CApp::OnRender() { } |
1 2 3 4 |
#include "CApp.h" void CApp::OnCleanup() { } |
Now lets go back to our CApp.cpp code to link all of these functions together:
이제, 이런 기능을 함께 모두 링크 하여 우리의 CApp.cpp 코드에 합 칠 수 있습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
#include "CApp.h" CApp::CApp() { Running = true; } int CApp::OnExecute() { if(OnInit() == false) { return -1; } SDL_Event Event; while(Running) { while(SDL_PollEvent(&Event)) { OnEvent(&Event); } OnLoop(); OnRender(); } OnCleanup(); return 0; } int main(int argc, char* argv[]) { CApp theApp; return theApp.OnExecute(); } |
You'll notice some new variables, but let's look at what is happening first.
First, we try to Initialize our game, if it fails we return -1 (an error code), thus closing our program.
If everything is good, we continue on to the game loop. Within the game loop we use SDL_PollEvent to check for events, and pass them one at a time to OnEvent.
Once done with Events, we go to OnLoop for move data around and what not, and then render our game.
We repeat this indefinitly.
If the user exits the game, we proceed to OnCleanup cleaning up any resources. Simple enough.
일부 새 변수를 확인했을 것이다, 하지만 먼저 무엇이 일어난건지 살펴 봅시다.
첫째, 게임 초기화 실패 하면 프로그램을 닫고 (오류 코드)-1을 반환 합니다. 모두 잘된 경우, 게임 루프로 진행하고 게임 루프 내에서 sdl_pollevent를 사용 하여 이벤트에 대해 확인하고, OnEvent()에 동시에 전달한다.
이벤트와 같이 마치게 되면, 데이터 주위와 무엇이던 움직이고 Onloop로 이동하고, 그리고 나서 게임을 렌더링한다.
우리는 이것을 무한하게 반복한다.
사용자는 게임을 종료 하는 한다면, 우리는 모든 리소스를 정리 하는 Oncleanup를 진행 합니다. 간단하지만 충분하다.
Now, lets look at SDL_Event and SDL_PollEvent. The first is a structure that holds information about events. The second is a function that will grab any events waiting in the queue.
This queue can have any number of events, which is the reason why we have to loop through them.
So, for example, lets say the user presses A and moves the mouse during the OnRender() function. SDL will detect this and put two events in the queue, one for a key press and one for a mouse move.
We can grab this event from the queue by using the SDL_PollEvent, and then passing it to OnEvent to handle it accordingly.
Once there are no more events in the queue, SDL_PollEvent will return false, thus exiting out of the Event queue loop.
지금, SDL_Event 및 sdl_pollevent를 살펴본다.첫 번째 이벤트에 대 한 정보를 보유 하 고 있는 구조입니다. 두 번째는 함수고, 큐에서 대기 하는 모든 이벤트를 잡는 것입니다. 왜 우리가 그들을 반복 해야 하는 이유는, 이 큐에 임의 개수의 이벤트를 가질 수 있기때문이다.
그래서, 예를 들어, 사용자 프레스 A를 말할 수 있습니다 및 OnRender() 함수 동안 마우스를 이동 합니다.
SDL는 이를 인지하고 큐에 두개의 이벤트를 넣어, 하나의 키누르기와 마우스에 대한 이동이다.
우리는 sdl_pollevent를 사용하여, 큐에서이 이벤트를 잡을 수 있고, 다음 그에 따라 처리 하는 Onevent에 전달한다.
만약 거기에 큐에 더 이상 이벤트가 없으면, sdl_pollevent는 false를 반환하고, 바로 이벤트 큐 루프 종료한다.
--
The other variable added, Running, is our own.
This is our exit out of the game loop. When this is set to false, it will end the program, and in turn exit the program. So, for example, if the user presses the Escape key we can set this variable to false, quitting the game.
추가 하는 다른 변수인 Running은 우리의 자신의 것입니다.
이것은 게임 루프 밖으로 나가는 출구입니다. 이것이 False로 설정 되면, 그것은 프로그램을 종료 하고,이어서 프로그램을 종료 합니다. 그래서, 예를 들어, 사용자가 Esc 키를 누를 경우, 변수 false로 설정하고, 게임을 종료한다.
You should be able to compile everything so far just fine, but you may notice you can't exit out. You'll probably have to use the task manager to end the program.
여기까지 잘됐다면 모든 것을 컴파일 할 수 있다, 그러나 종료가 되지 않으것을 알 수 있다.
작업관리자를 사용해서 아마도 프로그램을 종료할 것이다.
Now that everything is setup, let's start by creating the window our game will be drawn in.
Jump over to CApp.h and add a SDL surface variable to the code:
자 설정이 이것이 전부이다, 이제는 창을 생성하는 것을 시작하여 우리게임을 그리는 것을 할것이다.
CApp.h를 점프하여, SDL 표면 변수를 코드에 추가:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
#ifndef _CAPP_H_ #define _CAPP_H_ #include <SDL.h> class CApp { private: bool Running; SDL_Surface* Surf_Display; public: CApp(); int OnExecute(); public: bool OnInit(); void OnEvent(SDL_Event* Event); void OnLoop(); void OnRender(); void OnCleanup(); }; #endif |
I suppose now would be a good time to explain exactly what a SDL Surface is. An SDL Surface is anything that can be drawn, or drawn to. Say we have a blank piece of paper, a pencil, and some stickers; this paper could be called our display "surface." We can draw to it, put stickers on it, or whatever. The stickers we have are also surfaces; we can draw on them and put other stickers on them as well. So, Surf_Display is simply our "piece of blank paper" that we will draw all our stuff on.
지금 겠 정확히 무엇을 설명 하는 좋은 시간이 될 것 이라고 SDL 표면입니다. SDL 표면입니다 그려, 또는에 그려진 수 있는 아무것도. 우리는 종이, 연필, 그리고 일부 스티커;의 빈 조각 말 이 종이 우리의 표시 "표면." 호출할 수 있습니다. 우리는 그것을, 또는 무엇 이건에 스티커를 넣어 그것을 그릴 수 있습니다. 우리는 스티커는 또한 표면; 우리는 그들에 그릴 하 고 그들 뿐만 아니라 다른 스티커를 넣어 수 있습니다. 그래서, surf_display은 단순히 우리의 "빈 종이 조각" 우리는, 우리의 모든 물건을 그릴 것입니다 그.
Now, lets jump on over to CApp_OnInit to actually create this surface:
지금, CApp_OnInit로 이동하여 표면을 실제로 생성:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
#include "CApp.h" bool CApp::OnInit() { if(SDL_Init(SDL_INIT_EVERYTHING) < 0) { return false; } if((Surf_Display = SDL_SetVideoMode(640, 480, 32, SDL_HWSURFACE | SDL_DOUBLEBUF)) == NULL) { return false; } return true; } |
The first thing we need to do is start up SDL itself, so we can access its functions.
We are telling SDL to Initialize everything it has; there are other parameters you can pass, but understanding them at this point is not important.
The next function we use is SDL_SetVideoMode.
This bad boy is what creates our window, and our surface.
우리가 해야 할 첫 번째 일은 SDL 자체를 시작하는 것이며, 그러면 (우리는)기능에 액세스할 수 있습니다. 당신이 다른 매개 변수를 전달할 수 있지만, 이 시점에서 그것을 이해하는 것은 중요하지 않습니다, (우리는)그것이 가진 모든것을 초기화하는 SDL을 말하고 있습니다.
우리가 사용하는 다음 함수는 SDL_SetVideoMode입니다.
우리의 창과 우리의 표면을 만드는 나쁜 아이다.
It takes 4 parameters: The width of the window, the height of the window, the bit resolution of the window (recommended to be 16 or 32), and then display flags.
There are quite a few display flags, but the ones shown above are fine for now.
The first flag tells SDL to use hardware memory for storing our images and such,
and the second flag tells SDL to use double buffering (which is important if you don't want flickering on your screen). Another flag that may interest you now is SDL_FULLSCREEN, which makes the window go fullscreen.
그것은 4 매개 변수를 갖는다 : 창너비, 창높이, 창의 비트 해상도(16 또는 32로 권장) 및 플래그를 표시합니다.
표시 플래그가 꽤 있지만, 위에 표시된 것들은 지금까지는 충분한 상태입니다.
첫 번째 플래그는 SDL 우리 이미지와 같은 하드웨어를 저장할 메모리를 사용하도록 지시하고, 두 번째 플래그는 (화면위에서 깜빡거리지 않으려면 중요한 것) 이중 버퍼링을 사용하는 것을 SDL에게 알려줍니다. 당신이 관심가져야 다른 flag는, 윈도우가 전체 화면되게 하는, SDL_FULLSCREEN입니다.
Now that our display is setup, lets cleanup a little bit to make sure everything works smoothly. Open up CApp_OnCleanup.cpp and add the following:
이것이 디스플레이 설정입니다, 모두것이 원활하게 작동하면, 이제 정리 좀 합니다.. CApp_OnCleanup.cpp을 열고 다음을 추가:
1 2 3 4 5 |
#include "CApp.h" void CApp::OnCleanup() { SDL_Quit(); } |
We basically quit out of SDL.
You should take note that in this function is where you would free other surfaces as well.
This keeps all your code centralized to the function its performing.
To keep things tidy, lets also set the Surf_Display pointer to NULL on the class constructor.
Open up CApp.cpp and add the following:
우리는 기본적으로 SDL 밖으로 종료합니다.
당신은, 이런 기능에서 어디에 다른 표면을 지우는 것 뿐만 아니라, 유의를 해야합니다.
이것은 모든 코드는 수행 기능에 집중 유지합니다.
상황이 깔끔한 유지하기 위해 수는 클래스 생성자에 NULL로 Surf_Display 포인터를 설정합니다. CApp.cpp을 열고 다음을 추가 :
1 2 3 4 5 |
CApp::CApp() { Surf_Display = NULL; Running = true; } |
Try compiling your code, and watching it work.
You should have a nice blank window popup.
You'll notice you can't close it though, so you'll need to use the task manager to do so.
코드를 컴파일하고 작동하고 지켜보세요.
당신은 멋진 빈 창이 팝업되는 것이 있어야합니다.
(당신은)하지만 그것을 닫을 수 없으므로, 그렇게 할려면 작업 관리자를 사용해야합니다.
Now that we have a window all setup, we're going to need a way to close it.
Open up the CApp_OnEvent.cpp file, add the following:
이제 윈도우 모든 설정을 가졌다, 우리는 그것에 접근하는 방법을 더 늘려야 할 것 같습니다.
, CApp_OnEvent.cpp 파일을 열고 다음을 추가 :
1 2 3 4 5 6 7 |
#include "CApp.h" void CApp::OnEvent(SDL_Event* Event) { if(Event->type == SDL_QUIT) { Running = false; } } |
The SDL event structure is broken down into types.
These types can range from keypresses, to mouse movements; what we simply are doing here is checking the event type.
The type above we are looking for is the request to close the window
(i.e., when the user clicks the X button).
If that event happens to take place, we set Running to false, thus ending our program.
SDL 이벤트 구조 형식으로 세분화 됩니다.
이러한 유형의 마우스 움직임; keypresses에서 범위 수 있습니다. 우리가 단순히 뭘 여기 이벤트 유형을 검사입니다.
우리는 찾고 위의 type은 창을 닫으려면 요청 (즉, 클릭할 때 X 단추).
이벤트 자리를 차지할려면, 우리 실행 false로 설정, 따라서 우리의 프로그램을 종료 합니다.
Simple enough.
We'll look more into events in a later lesson.
충분히 간단하다.
우리는 이후 단원에서 이벤트로 더 알아보겠습니다.
Now, you should everything setup, and a good structure to work with later.
It may be a good idea to take this project and turn it into an "SDL template" within CodeBlocks.
I won't go over how to do that, but feel free to Google it.
이제, 당신이 설정해야하는 모든것이고, 나중에 작업하기좋은 구조이다.
이 프로젝트를 CodeBlocks안에 "SDL template"으로 변경하는하거나 프로젝트로 만드는것은 좋은 아이디어 일지도 모른다.
나는 그렇게 하는 것을 하지 않지만, Google을 자유롭게 해봐라.
Once you have a good idea what's going on with the code we covered in this lesson, jump over to the next game tutorial lesson to learn more about SDL surfaces.
만약 이 단원에서 다룬 코드를 가지고 무엇을 할려는 좋은 아이디어가 있다면, 다음 게임 강좌 단원으로 넘어가서 SDL surface에 관한 것을 배워라.
'온라인게임' 카테고리의 다른 글
DATEADD(Transact-SQL) (0) | 2011.10.12 |
---|---|
인생게임 Man's Life Game (0) | 2011.10.12 |
3D 클라이언트 개발 (0) | 2011.10.11 |
ISNULL in a CASE Statement (0) | 2011.10.11 |
기획 방법론 문제 해결 (0) | 2011.10.10 |