참고페이지 : C로 게임만들기 3장-게임의 기본
프레임워크란?
- 소프트웨어 제작이 편리하도록 미리 뼈대를 이루는 클래스와 인터페이스를 제작해놓은 틀/구조
게임 프레임워크란?
- 게임 제작에 필요한 기본 구조 및 긱능을 만들어 놓는 것을 말한다. 게임을 화면에 표시하기 위한 기본 기능들은 미리 구현해 두고, 실제 게임을 제작할때는 이 틀에 맞게 게임의 기능만 만들면 된다.
C언어 콘솔 게임 프레임워크에 필요한 기능
- ScreenInit() : 화면 버퍼 초기화, 전위버퍼-백버퍼 두개 생성
- ScreenClear() : 하나의 버퍼가 그려지고 있는 동안, 다음 장면을 위한 버퍼는 지워져야 한다.
- ScreenFliping() : 환성화된 버퍼와 비활성화된 버퍼의 상태를바꾸는 함수
- ScreenRelease() : 생성한 두개의 버퍼를 모두 해제하는 함수
- ScreenPrint(int x, int y, char* string) : x,y 좌표에 string출력
- SetColor(unsigned short color) : 화면에 출력할 문자색상값 지정
기존에 만들어 놓았던 게임 구조에 적용하면, 아래와 같이 작성할 수 있다.
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 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | #include<stdio.h> #include<time.h> #include<conio.h> void Init() { } void Update() { } void Render() { ScreenClear(); //출력코드 ScreenFlipping(); } void Release() { } int main() { int nKey; clock_t CurTime, OldTime; ScreenInit(); Init();//초기화 while (1) { if (_kbhit()) { nKey = _getch(); if (nKey == 'q') break; switch (nKey) { case 'j': break; case 'l': break; } } OldTime = clock(); Update();//데이터 갱신 Render();//화면 출력 while (1) { CurTime = clock(); if (CurTime - OldTime > 33) break; } } Release();//해제 ScreenRelease(); return 0; } |
Render() 함수의 내부는 GL과 유사한 구조라고 할 수 있다.
그릴 버퍼를지우고 -> 출력 코드 -> 화면에 그리기
1 2 3 4 5 6 7 8 | void Render() { glClear(GL_COLOR_BUFFERR_BIT); glBegin(GL_POLYGON); //출력코드 glEnd(); glFlush(); } | cs |
위와 같은 기능을 실제로 하는 Screen.h와 Screen.c는 아래와 같다.
Screen.h
1 2 3 4 5 6 | void ScreenInit(); void ScreenFlipping(); void ScreenClear(); void ScreenRelease(); void ScreenPrint(int x, int y, char* string); void SetColor(unsigned short color); | cs |
Screen.c
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 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | #include <windows.h> static int g_nScreenIndex; static HANDLE g_hScreen[2]; void ScreenInit() { CONSOLE_CURSOR_INFO cci; //화면 버퍼 2개를 만든다. g_hScreen[0] = CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE, 0, NULL, CONSOLE_TEXTMODE_BUFFER, NULL); g_hScreen[1] = CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE, 0, NULL, CONSOLE_TEXTMODE_BUFFER, NULL); //커서 숨기기 cci.dwSize = 1; cci.bVisible = FALSE; SetConsoleCursorInfo(g_hScreen[0], &cci); SetConsoleCursorInfo(g_hScreen[1], &cci); } void ScreenFlipping() { SetConsoleActiveScreenBuffer(g_hScreen[g_nScreenIndex]); g_nScreenIndex = !g_nScreenIndex; } void ScreenClear() { COORD Coor = { 0,0 }; DWORD dw; FillConsoleOutputCharacter(g_hScreen[g_nScreenIndex], ' ', 80 * 25, Coor, &dw); } void ScreenRelease() { CloseHandle(g_hScreen[0]); CloseHandle(g_hScreen[1]); } void ScreenPrint(int x, int y, char* string) { DWORD dw; COORD CursorPosition = { x, y }; SetConsoleCursorPosition(g_hScreen[g_nScreenIndex], CursorPosition); WriteFile(g_hScreen[g_nScreenIndex], string, strlen(string), &dw, NULL); } void SetColor(unsigned short color) { SetConsoleTextAttribute(g_hScreen[g_nScreenIndex], color); } | cs |
간단하게 사용하고 있는 API를 설명하면,(API 이름을 보면 무슨기능인지 유추가 가능하다)
#include <windows.h>-> https://en.wikipedia.org/wiki/Windows
- windows관련 헤더파일로 Windows API의 모든 함수에 대한 선언(매크로, 함수 및 하위 시스템)이 포함되어 있다.
1. ScreenInit() : 두개의 버퍼 생성 후, 커서 설정
- CreateConsoleScreenBuffer()->참고
: Screen Buffer를 생성한다. 여기선 두개의 버퍼를 생성하여, Flipping을 구현하고 있다.
- CONSOLE_CURSOR_INFO ->참고
: 콘솔의 커서에 대한 정보를 갖고 있다.
: dwSize : 커서로 채워지는 문자 셀의 비율(1~100)
: bVisible : 화면 표시 여부
- SetConsoleCursorInfo->참고
: 생성한 스크린 버퍼에 정의한 커서의 정보를 설정한다.
2. ScreenFlipping() : 버퍼 교환, 활성화된 버퍼를 화면에 그린다.
- SetConsoleActiveScreenBuffer : 이함수가 위에말한 그 역할, 파라미터로 넘겨주는 버퍼를 콘솔화면에 그린다. ->참고
3. ScreenClear() : 화면을 지워준다.
- FillConsoleOutputCharacter -> 참고
: FillConsoleOutputCharacter(buffer, ' ', 80*25, Coor(0,0), &dw)
-> buffe에 0,0(x,y)부터 시작하여 80x25만큼 ' '로 채운다. dw값은 버퍼에 실제 기록된 문자수를 받는 변수 포인터
4. ScreenRelease() : 화면 해제, CloseHandle()
5. ScreenPrrint(int x, int y, char* sting) : x,y 좌표에 string 출력, SetConsoleCursorPosition()으로 좌표 이동, WriteFile()함수로 string입력
6. SetColor() : 색상 변경, SetConsoleTextAttribute()
이제 Screen.h만 포함시켜주면 렌더링 기능은 완료되게 된다.
이제 완성된 소스에 FPS를 출력해보면 아래와 같이 완성된다.
*FPS란, Frame Per Second로 1초당 출력되는 프레임 수를 의미한다.
저의 경우엔 아래 노란 음영과 같이 만들었습니다.
한번 렌더링 될때마다 그리는 프레임의 갯수를 counting 한 후,
1초(1000ms)가 되었을 때 프레임 갯수를 출력합니다. 그 후 다시 초기화
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 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 | #include<stdio.h> #include<time.h> #include<conio.h> #include<malloc.h> #include"screen.h" clock_t FPSCurTime, FPSOldTime; int FrameCnt; char *FPSTextBuffer; void Init() { FrameCnt = 0; FPSTextBuffer = (char*)malloc(sizeof(char) * 10); sprintf(FPSTextBuffer, "FPS:%d", FrameCnt); FPSOldTime = clock(); } void Update() { } void Render() { ScreenClear(); //출력코드 FrameCnt++; FPSCurTime = clock(); if (FPSCurTime - FPSOldTime >= 1000) { sprintf(FPSTextBuffer, "FPS:%d", FrameCnt); FPSOldTime = clock(); FrameCnt = 0; } ScreenPrint(0, 0, FPSTextBuffer); //ScreenPrint(0, 0, FPSTextBuffer); ScreenFlipping(); } void Release() { free(FPSTextBuffer); } int main() { int nKey; clock_t CurTime, OldTime; ScreenInit(); Init();//초기화 while (1) { if (_kbhit()) { nKey = _getch(); if (nKey == 'q') break; switch (nKey) { case 'j': break; case 'l': break; } } OldTime = clock(); Update();//데이터 갱신 Render();//화면 출력 while (1) { CurTime = clock(); if (CurTime - OldTime > 33) break; } } Release();//해제 ScreenRelease(); return 0; } | cs |
출력된 화면,
'Software Development > C, C++' 카테고리의 다른 글
C언어로 게임만들기 - 5. 첫번째 게임_1)Player 만들기 (3) | 2017.03.19 |
---|---|
C언어로 게임만들기 - 4. 코드정리(전체코드) (3) | 2017.03.18 |
C언어로 게임만들기 - 2. 게임 프로그래밍 용어 (0) | 2017.03.14 |
C언어로 게임만들기 - 1. 게임 기본구조 (3) | 2017.03.14 |
현재 디렉토리 경로 알아오기 (0) | 2014.10.20 |