API, Direct X를 이용한 그림 띄우기 | (분류:프로그래밍) 2005-10-09 오후 7:49:14 |
먼저 VC++에서 Alt + F7을 눌러 링크에 ddraw.lib, dxguid.lib를 추가시켜 준비를 마춘다.
설명은 다음에 하겠습니다. 몸이 불편하여 ㅡㅡ;
#include
#include
#include "ddutil.h"
#define MAX 256 //미사일의 최대 개수
//키보드의 정보를 담을 버퍼
BOOL NowKeyState[256];
//전역으로 사용될 윈도우 핸들
HWND GlobalWnd;
LPDIRECTDRAW7 lpDirectOBJ; //LPDIRECTDRAW7의 객체
LPDIRECTDRAWSURFACE7 lpPrimarySurface; //Primary Surface의 객체를 생성
LPDIRECTDRAWSURFACE7 lpBackSurface; //Back Surface 객체를 생성합니다.
LPDIRECTDRAWSURFACE7 lpPlayer; //플레이어 그림 객체
LPDIRECTDRAWSURFACE7 lpEnermy;//적기 그림 객체
LPDIRECTDRAWSURFACE7 lpPMissile;//미사일 그림 객체
LPDIRECTDRAWSURFACE7 lpBoom; // 충돌시 출력 이미지 객체
LPDIRECTDRAWSURFACE7 lpBackGround;//배경 그림 객체
int Frame = 0; //프레임의 초기값 설정
int inc =0 ; // 증가값
int PPlaneX =500, PPlaneY=500; // 플레이어 시작 위치
int PMX[MAX], PMY[MAX]; // 미사일 좌표.
int PMissileState;//미사일 증가 값 0~255
int PMOn[MAX], PMCount[MAX]; //PMOn[MAX]는 미사일 온, 오프, PMCount[MAX]는 출려되는 미사일 갯수.
int Total = 0; // 미사일의 전체적인 증가값
int Bx =0 ,By =0; // 미사일그림 출발 좌표값
//에러 메시지를 출력해 줌
BOOL ErrorMessage(HWND hwnd, char *str)
{
MessageBox(hwnd, str, "연산실패", MB_OK);
DestroyWindow(hwnd);
return FALSE;
}
//#########################################################
// 용도 : 생성한 객체를 모두 삭제한다.
// 연결 관계 : MsgProc 부분에서 메시지가 종료될 때
// 그 부분에서 호출되어 윈도우와 동시에 삭제된다.
//##########################################################
void DeleteAll(void)
{
//Primary Surface를 소멸시킨다.
if(lpPrimarySurface != NULL)
{
lpPrimarySurface ->Release();
lpPrimarySurface = NULL;
}
if(lpBackGround != NULL)
{
lpBackGround ->Release();
lpBackGround = NULL;
}
if(lpEnermy!= NULL)
{
lpEnermy ->Release();
lpEnermy = NULL;
}
if(lpBoom != NULL)
{
lpBoom ->Release();
lpBoom = NULL;
}
//화면 객체로 사용한 그림을 삭제한다.
if(lpPMissile != NULL)
{
lpPMissile->Release();
lpPMissile = NULL;
}
if(lpPlayer != NULL)
{
lpPlayer->Release();
lpPlayer = NULL;
}
//LPDIRECTDRAW7 객체를 삭제한다.
if(lpDirectOBJ != NULL)
{
lpDirectOBJ ->Release();
lpDirectOBJ = NULL;
}
}
//###################################################
// 용도 : 윈도우에서 발생하는 메시지의 처리
// 연결관계 : 메시지를 처리할 부분에서 사용된다.
//###################################################
long FAR PASCAL WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch(message)
{
case WM_KEYDOWN: //키가 눌렸을 때의 처리
NowKeyState[wParam] = TRUE;
break;
case WM_KEYUP: //키가 놓여졌을 때의 처리
NowKeyState[wParam] = FALSE;
break;
case WM_TIMER: //타이머가 호출될 때마다 한프레임씩 증가한다.
if(Frame { Frame
= Frame + 1; } else { Frame
= 0; } break; case WM_DESTROY: DeleteAll(); //종료 시 생성한 객체를
모두 삭제한다. KillTimer(GlobalWnd,
NULL); PostQuitMessage(0); break; } return DefWindowProc(hWnd, message, wParam,
lParam); } //################################################################ // 용도 : 윈도우 생성을 초기화 한다. // 연결관계 : 윈도우를 처음 생성 시에 메인에서 호출하여 생성한다. //################################################################ BOOL InitWindow(HINSTANCE hInstance, int nCmdShow) { WNDCLASS wc; //윈도우 클래스의 선언 wc.style = CS_HREDRAW | CS_HREDRAW | CS_DBLCLKS; wc.lpfnWndProc = WindowProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = GetStockBrush(BLACK_BRUSH); wc.lpszMenuName = NULL; wc.lpszClassName = "EXAM3_1"; RegisterClass(&wc); //윈도우의 생성 GlobalWnd = CreateWindowEx (0, "EXAM3_1", NULL,
WS_POPUP, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CXSCREEN),
NULL, NULL, hInstance, NULL); //생성에 실패하였을 경우 if ( !GlobalWnd) return FALSE; //윈도우를 업데이트하는 부분 SetFocus(GlobalWnd); ShowWindow(GlobalWnd, nCmdShow); UpdateWindow(GlobalWnd); ShowCursor(FALSE); return TRUE; } //################################################################ // 용도 : 다이렉트 드로우를 초기화 하는 부분 // 연결관계 : 다이렉트 드로우상의 실질적인 작업을 할 수 있게 한다. //################################################################ BOOL InitDirectDraw(int x, int y, int bpp) { HRESULT hr; //결과값을 담을 변수 DDSURFACEDESC2 ddsd; //표면을 담을 객체 DDSCAPS2 ddscaps; //표면의 정보를 저장한다 LPDIRECTDRAW pdd; //다이렉트 드로우의 객체를 생성한다. //다이렉트 드로우들 생성한다. hr = DirectDrawCreate(NULL, &pdd, NULL); if (hr !=DD_OK) return
ErrorMessage(GlobalWnd, "DirectDrawCreate의 실패"); //버전 검사하기 hr = pdd->QueryInterface (IID_IDirectDraw7,
(LPVOID * ) &lpDirectOBJ); if (hr !=DD_OK) return
ErrorMessage(GlobalWnd, "QueryInterface의 실패"); //협력수준을 검사합니다. hr = lpDirectOBJ->SetCooperativeLevel(GlobalWnd,
DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN); if (hr != DD_OK) return ErrorMessage(GlobalWnd,
"SetCooperativeLevel의 실패"); //화면보드를 설정합니다. hr = lpDirectOBJ
->SetDisplayMode(x,y,bpp,0,0); if (hr != DD_OK) return
ErrorMessage(GlobalWnd, "SetDisplayMode의 실패"); //Primary Surface를 만들어 정보를 담는다. memset(&ddsd,0,sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE |
DDSCAPS_FLIP | DDSCAPS_COMPLEX; ddsd.dwBackBufferCount = 1; //담겨진 정보를 가지고 실질적인 표면을 생성한다. hr = lpDirectOBJ -> CreateSurface(&ddsd,
&lpPrimarySurface, NULL); if (hr != DD_OK) return
ErrorMessage(GlobalWnd, "CreateSurface의 실패"); //Back Surface 표면을 생성하기 위한 표면의 저장을 저장한다. memset(&ddscaps, 0, sizeof(ddscaps)); ddscaps.dwCaps = DDSCAPS_BACKBUFFER; //후위면과 Primary Surface와의 연결을 설정한다. hr = lpPrimarySurface ->
GetAttachedSurface(&ddscaps, &lpBackSurface); if (hr != DD_OK) return
ErrorMessage(GlobalWnd, "GetAttachedSurface의 실패 "); return TRUE; } //######################################################################### // 용도 : 출력할 그림을 모두 불러오는 기능. // 연결관계 : DD초기화후 그림이미지를 불러와 화면으로 그림출력. //######################################################################### BOOL InitGraphicLoad(void) { //그림 이미지를 로드 하는 작업 lpBackGround = DDLoadBitmap(lpDirectOBJ,
"Surface\\BackGround.BMP",0,0); lpPlayer = DDLoadBitmap(lpDirectOBJ,
"Surface\\play.BMP",0,0); lpBoom = DDLoadBitmap(lpDirectOBJ,
"Surface\\Boom.BMP",0,0); lpEnermy = DDLoadBitmap(lpDirectOBJ,
"Surface\\enermy.BMP",0,0); lpPMissile= DDLoadBitmap(lpDirectOBJ,
"Surface\\missile.BMP",0,0); DDSetColorKey(lpPlayer,RGB(0,255,0));
DDSetColorKey(lpBoom,RGB(0,255,0)); DDSetColorKey(lpEnermy,RGB(0,255,0));
DDSetColorKey(lpPMissile,RGB(0,255,0));
return TRUE; } //######################################################################### // 용도 : 매 프레임임마다 다른 그림을 출력할 수 있는 역할 // 연결관계 : 화면 갱신 //######################################################################### void FrameMove(void) { RECT BackRect = {0, 0, 1280, 800}; //후위면의 영역 설정 RECT BackGroundRect = {0,0, 1024, 768}; RECT PlayerRect = {0, 0, 36, 62}; RECT EnermyRect = {0,0, 100,89}; RECT PMissileRect = {0, 0, 21, 18}; RECT BoomRect = {0,0,45,40}; RECT ; //Back Surface로 이미지를 로드한다. lpBackSurface -> Blt( &BackRect, lpBackGround,
&BackGroundRect, DDBLT_WAIT | DDBLTFAST_NOCOLORKEY,NULL ); //////////////////////////////////////////플레이어 조정
부분////////////////////////// if(NowKeyState[VK_RIGHT]) { PPlaneX = PPlaneX + 10; } else if(NowKeyState[VK_LEFT]) { PPlaneX = PPlaneX - 10; } if(NowKeyState[VK_UP]) { PPlaneY = PPlaneY -10; } else if(NowKeyState[VK_DOWN]) { PPlaneY = PPlaneY +10; } lpBackSurface -> BltFast(PPlaneX,PPlaneY,
lpPlayer, &PlayerRect, DDBLTFAST_WAIT | DDBLTFAST_SRCCOLORKEY); ////////////////////////////////////////////////////////////////////////////////////////////// lpBackSurface -> BltFast(500,300,lpEnermy,
&EnermyRect, DDBLTFAST_WAIT | DDBLTFAST_SRCCOLORKEY); ///////////////////////////////////////////플레이어 미사일
부분///////////////////////////// if(NowKeyState[VK_SPACE]) { PMissileState ++; Total ++; if(PMissileState >MAX-1
&& Total > MAX-1) { PMissileState
= 0; Total
= 0; } PMOn[Total] = 1; PMCount[Total] = 0; if(PMOn[Total] == 1) { PMX[Total]
= PPlaneX; PMY[Total]
= PPlaneY; PMOn[Total]
=0; } } for(PMissileState =0 ; PMissileState < MAX ;
PMissileState++) { PMY[PMissileState] =
PMY[PMissileState] - 10; //적기와 미사일의 충돌 처리// if(PMY[PMissileState] <
389 && PMX[PMissileState] > 490 && PMX[PMissileState] <
600) { By=PMY[PMissileState]
; Bx=PMX[PMissileState]
; PMY[PMissileState]
= -389; } lpBackSurface ->
BltFast(Bx,By,lpBoom, &BoomRect, DDBLTFAST_WAIT |
DDBLTFAST_SRCCOLORKEY); lpBackSurface ->
BltFast(PMX[PMissileState],PMY[PMissileState],lpPMissile, &PMissileRect,
DDBLTFAST_WAIT | DDBLTFAST_SRCCOLORKEY); } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //프리핑을 통한 화면으로의 고속복사를 시도한다. lpPrimarySurface -> Flip (NULL, DDFLIP_WAIT); } //######################################################################### // 용도 : 메인으로 모든 연산을 처리한다. // 연결관계 : 모든연산을 묶어서 처리하는 메인부분 //######################################################################### int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR
lpCmdLine, int nCmdShow) { MSG msg; if(!InitWindow(hInstance, nCmdShow)) return FALSE;
//윈도우를 초기화 한다 if(!InitDirectDraw(1280,800,32)) return FALSE; //다이렉트
드로우를 초기화헌다. if(!InitGraphicLoad() ) return FALSE; //그림을 로드하는 일을
한다. SetTimer(GlobalWnd, NULL,10, NULL); //타이머로 화면을
갱신한다. while ( !NowKeyState[VK_ESCAPE]) //ESC키가 눌렸는지
확인한다. { if (PeekMessage(&msg,
GlobalWnd,0,0,PM_NOREMOVE)) { if(!GetMessage(&msg,
GlobalWnd, 0,0)) return msg.wParam; TranslateMessage(&msg); DispatchMessage(&msg); } else { FrameMove();
//변화된 프레임을 출력한다. } } DestroyWindow(GlobalWnd); return TRUE; } |
... devpia에서
'- 음악과 나 - > 『 짬 통 』' 카테고리의 다른 글
CMapEditor.. (0) | 2006.04.17 |
---|---|
4월 17일.. 디다. (0) | 2006.04.17 |
충돌체크 (0) | 2006.04.17 |
[스크랩] 게임프로그래밍/게임기획 게임제작의 기술.. (0) | 2006.04.17 |
소스 세이프. (0) | 2006.04.17 |