[GpGiki 대문으로]

지피껨 만들기 02


지피껨 만들기.. (2)

샬롬~

우우우, 이런...

저번에 실수를 했더군요. ex001이 아니라 제가 실행한 것은 ex000이었습니다. -_-

ex001은 단순히 사각형 하나 출력하는 거지, 16bit 변환 이야기는 없었습니다. T_T 예, 저의 실수입니다... 목숨만은... -_-

여담이지만.. ex001을 보시면... 상당히 짧습니다. 소스가.. 적당한 매력이지요.. ^^

3. 움직이는 사각형

이번에는 실제로 코딩을.... 후후후.... 일단 간단히 움직이는 사각형을 구현하도록 하죠. 물론, 사용자의 입력에 따라서 움직여야 하겠죠? Surface니 Flip이니 하는 개념은....... 제가 예전에 (몇년 전이지?-_-) 쓴 'TC로 게임 만들기'를 참조함이.. -_- ( DOS 시절 게임 만드신 분이라면.. Page라는 개념을 아실 겁니다. 그거죠. T_T )

자, 일단..... VC++에서 GP32용 Project를 만들기 위해서는.. 상당히 귀찮은 작업이 필요한데... work/docs/dev_ko/index.htm을 보시면... 아니, 바로 가는 걸로 찾아보죠. ^^ work/docs/dev_ko/vc/project.htm을 보시면 됩니다.

그런데.... 하여튼.. 저는 귀찮아서.. work/project/template를 바로 이용하겠습니다. 원래는 이걸 가지고 복사해서 삽질하라고 써있는데.. 귀찮아서..... -_-

win32 application project 생성해주듯이.. GP32 application project 생성하는 것도 만들면 좋은데....... 나중에 시간이 나면.... 해보도록 하겠습니다만... 제가 약속은 잘 안지키는 놈이라서..... -_- 예, 그런 거죠.. 쿨럭.. 털썩.. 부들......

work/project/template/win32에 들어가면.. template.dsw가 있습니다. 그걸 더블 클릭을 하면.. 무언가 나오죠. 화면에 사각형을 출력하는 예제인데... 아래의 소스로 교체를 해봅시다. ^^

#include "gpdef.h"
#include "gpgraphic.h"
#include "gpmain.h"

GPDRAWSURFACE gpDraw;

void GpMain( void *arg )
{
	GpLcdSurfaceGet( &gpDraw, 0 );
	GpSurfaceSet( &gpDraw );

	if ( !( GPC_LCD_ON_BIT & GpLcdStatusGet() ) )	GpLcdEnable();

	GpRectFill( NULL, &gpDraw, 0, 0, gpDraw.buf_w, gpDraw.buf_h, 0x00 );
	GpRectFill( NULL, &gpDraw, 120, 60, 80, 80, 0xFF );
}

원래 예제는 Surface 하나짜리라서... 좀 바꿨습니다. 이건 쓸데 없는 건 일단 최소화를 해본 거죠.. ^^ ( 과연 최소화가 맞나? -_- ) 일단 사각형을 움직이기 전에 위의 소스부터 분석하고..... 사각형을 움직여보죠... 후후후... +_+

GP32 Application의 main은 GpMain입니다. Win32 Application의 main이 WinMain인 것과 마찬가지....

맨 첨의 GPDRAWSURFACE gpDraw;를 봅시다. 이게 바로 DOS 시절의 Page 개념인 Surface를 정의하는 겁니다. 그냥 화면...의 개념으로 보시면 됩니다. 예, 간단하죠? ^^

GpLcdSurfaceGet이란 놈은....

LCD Surface, 그냥 LCD 화면을 얻는 거죠. 위에 정의한 gpDraw란 변수는 그냥 정의만 된거지.. 아직 아무 값도 안가지는 거잖아요. 실제로 쓸 수 있게 Surface Get을 때려주는 거죠.

자, 그 담에 실제로 화면을 세팅을 해주는 건... GpSurface Set입니다. ( 이미 눈치까신 분이 있겠지만.. GP32 API는... Gp가 앞에 붙습니다. ^^ )

if ( !( GPC_LCD_ON_BIT & GpLcdStatusGet() ) )	GpLcdEnable();

이 녀석은... 실제로 LCD 화면을 사용하는 건데.... (Enable) 앞에 있는 조건은.. LCD 쓸 수 있는지 체크 정도죠. 실제로는 이게 없어도 되는데 (Default가 Enable이거든요^^) 그냥 넣었습니다.

실제로 GP32 기계에선 어떻게 되는지 모르니까... -_- 여기까지 했으면.. 준비는 끝난 겁니다. 실제로 여기까지만 하고 실행해도 하얀 화면이 뜨죠. ^^ 그런데.. 아무 것도 안그리면 좀 썰렁하니..... 일단 화면을 검게 지우고 상자를 하나 그려보죠.

GpRectFill( NULL, &gpDraw, 0, 0, gpDraw.buf_w, gpDraw.buf_h, 0x00 );

이건 (0,0)부터 화면 크기만한 상자를 그리는 겁니다. 즉, 화면을 0x00(black)으로 지우는 거죠. ^^

GpRectFill( NULL, &gpDraw, 120, 60, 80, 80, 0xFF );

이건 0xFF(white)로 상자를 그려주는 겁니다. 후후후... 대단히 간단합니다. ^^ 예, 그런 거죠. ^^

그럼 이번엔 실제로 키보드의 입력을 받아서 움직이게 해볼까요? ^^

#include "gpdef.h"
#include "gpgraphic.h"
#include "gpmain.h"

GPDRAWSURFACE gpDraw;

void GpMain( void *arg )
{
	unsigned char keydata;	// 키보드 입력을 받기 위한 녀석...

	int x = 120;	// 상자의 X 좌표
	int y = 60;`	// 상자의 Y 좌표

	GpLcdSurfaceGet( &gpDraw, 0 );
	GpSurfaceSet( &gpDraw );

	if ( !( GPC_LCD_ON_BIT & GpLcdStatusGet() ) )	GpLcdEnable();

	while( 1 )	// 루프를 돌려보죠~ +_+
	{
		keydata = GpKeyGet();	// 키 입력을 받을까요?

		if( keydata & GPC_VK_UP )	y--;	// UP
		if( keydata & GPC_VK_DOWN )	y++;	// DOWN
		if( keydata & GPC_VK_LEFT )	x--;	// LEFT
		if( keydata & GPC_VK_RIGHT )	x++;	// RIGHT

		GpRectFill( NULL, &gpDraw, 0, 0, gpDraw.buf_w, gpDraw.buf_h, 0x00 );
		GpRectFill( NULL, &gpDraw, x, y, 80, 80, 0xFF );
	}
}

아까의 소스와 달라진 부분에는 주석이 붙어있습니다. 참고하시고~ ^^ 자, 이번에는 키 입력을 받는 게 추가가 됐는데... 매우 간단합니다. 제가 뭐라고 부연 설명을 하는게 어색할 정도죠. -_-

여기까지 하면.. 우리의 목적이 일단 달성된 거 같은데... 실행해보면 조금 이상하죠? 상자가 상당히 깜빡거립니다. +_+

왜 그런가하고 식음을 전폐하고 고민을 하니.... 화면을 지우고 상자를 그리기 때문에 그런 거죠. 화면을 지울 때 상자가 함께 지워지고, 상자를 다시 그리고.. 당연히 깜빡거리는 거 아니겠습니까... ^^

그런데... 그게 당연하다고 존나 깜빡거리는 걸 게임이라고 내놓으려니.. 자존심이 허락하지 않네요. ^^;;; 그럼 어찌할까요..... 설명하기 귀찮으니.. 일단은 아래의 소스로 살짝 수정을 해볼까요?

#include "gpdef.h"
#include "gpgraphic.h"
#include "gpmain.h"

GPDRAWSURFACE gpDraw[2];	// Surface를 2개로 잡을까여? ^^
int nflip = 0;			// Surface Flip을 위한 변수

void GpMain( void *arg )
{
	unsigned char keydata;

	int x = 120;
	int y = 60;

	GpLcdSurfaceGet( &gpDraw[0], 0 );	// 자자, 0번 Surface
	GpLcdSurfaceGet( &gpDraw[1], 1 );	// 이번에는 1번 Surface

	GpSurfaceSet( &gpDraw[0] );

	if ( !( GPC_LCD_ON_BIT & GpLcdStatusGet() ) )	GpLcdEnable();

	while( 1 )
	{
		keydata = GpKeyGet();

		if( keydata & GPC_VK_UP )		y--;
		if( keydata & GPC_VK_DOWN )		y++;
		if( keydata & GPC_VK_LEFT )		x--;
		if( keydata & GPC_VK_RIGHT )	x++;

		GpRectFill( NULL, &gpDraw[nflip], 0, 0, gpDraw[nflip].buf_w, gpDraw[nflip].buf_h, 0x00 );
		GpRectFill( NULL, &gpDraw[nflip], x, y, 80, 80, 0xFF );

		GpSurfaceFlip( &gpDraw[nflip] );	// Surface Flip을 감행!!

		nflip = ( nflip + 1 ) % 2;		// Flip을 위한 변수를 변신~
	}
}

움하하핫.......... 드디어 안깜빡이는 상자다......... T_T 이제 이번 글은 접기로.. 쿨럭.. -_-

예, 간단히 설명을 하죠. 여기서 포인트는 Surface를 2개 만든다는 점과 Surface Flip이라는 녀석이죠. 아까 깜빡거리는 문제에 대한 해답을 생각해볼까요?

일단 문제가 되는 건.... 우리가 무언가 작업을 하는게-그림을 그리는게- 유저에게 보인다는 거죠. 그렇다면.... 그 화면을 두놈을 만들어서.... 한 화면을 보여주고.. 다른 화면에 그림을 그려서.. 순식간에 두 화면을 바꿔치면(Flip) 되지 않겠느냐.... 이거죠. ^^ 바로 그 개념입니다. 별로 어려운 건 없으니까요.. 그냥 쓱~하고 보시면 아항~하고 이해가 가실 겁니다. DOS 시절처럼 인터럽트 호출해서 13h모드 만들고.. 그런 짓은 없으니.. ( 아아, Plane Mode의 추억이여.. 털썩... -_-;;;;; )

일단... 이번에는 여기까지입니다. 특별한 설명이 없는 날림인 점... 대단히 죄송합니다. T_T 어짜피.. 이 글을 보시는 분들은.... 나름대로 게임 프로그래밍을 공부하신 분들이라고 가정하고... (퍽퍽) 다음에는.... 좀 더 심오한 삽질로 들어가도록 하겠습니다. ^^

--2002.04.10 아샬

P.S. 사실... 빨리 쓰려다 보니.. 좀 성의가 없네요. 오랜만에 쓰다보니.... 글 쓰는데.. 정성을 다하기가.. 어렵습니다. 죄송 T_T


지피껨 만들기로 돌아가기


제일 위로
최종 수정 일시: 01월 05일(2003년) 12:52 AM 편집 | 정보 | 차이 | 비슷한 페이지 DebugInfo
유용한 페이지들: 분류 분류 | 자유로운 연습장 SandBox | 무작위 페이지들 RandomPages | 인기있는 페이지들 MostPopular