안녕하세요 ^_^ ㅋㅋㅋ VampireJK입니다
가입한지 얼마안된 뉴비입니다. 굽신굽신 아프롱 잘부탁드린다능..
간단하게 제가 제작 중인 게임을 통해서 소스를 같이 파악해보려는 의도와
잘하시는분의 도움좀 받고싶사
이렇게 강의같이 글을 올리게 되었습니다.
자~ 그럼 시작해..보기전에..
개발은 winapi, directx를 이용한 슈팅게임입니다
현재 개발 단계는 배경화면등록, 주인공비행기등장, 미사일발사, 이동 이렇게만 구현된 상태입니다.
일단 사전지식에 대해서 말씀드리겠습니다.
WinApi, C, C++ 이 정도는 어느정도 간단하게 라도 알고 계셔야 이해하기 편할것 같습니다.
그래도 최대한 자세하게 써볼려고 하니 재미있게 읽어주세요.
그리고 제작에 많은 도움을 주신 Vitamin500님에게 정말 감사의 말씀을 드립니다.
밑에 부분이 풀소스입니다.
일단 지금은 시간이 없어 소스만 올리겠습니다(회사에서 하는거라 ㅎㅎㅎ)
주석은 최대한 달아놓았으니 한번 읽어보시고
오늘안에 강의를 시작할 예정입니다 ^^
그럼 즐프하세요
#include <d3d9.h>
#include <d3dx9.h>
#pragma warning( disable : 4996 ) // disable deprecated warning
#include <strsafe.h>
#pragma warning( default : 4996 )
LPDIRECT3D9 g_pD3D = NULL; // Used to create the D3DDevice
LPDIRECT3DDEVICE9 g_pd3dDevice = NULL; // Our rendering device
LPD3DXSPRITE g_pSprite;
WNDCLASSEX g_wc;
HWND g_hWnd;
//구조체 생성
struct Object
{
BOOL bVisible; //총알 발사여부
LPDIRECT3DTEXTURE9 g_pTexture;
RECT rcSrc;
D3DXVECTOR3 vecCenter;
D3DXVECTOR3 vecPosition;
};
Object g_Obj[3];
Object g_Bullet[100];
//제작함수 2가지.
void Update();
void initvector(); //그림이 출력될 위치 변수 초기화
//Game g_Game;
LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam );
HRESULT InitD3D( HWND hWnd );
void initvector() //이미지출력 위치 초기화 함수선언
{
ZeroMemory(g_Obj, sizeof(g_Obj));
//배경화면
g_Obj[0].bVisible = TRUE;
g_Obj[0].vecPosition.x = .0f;
g_Obj[0].vecPosition.y = .0f;
g_Obj[0].vecCenter.x = .0f;
g_Obj[0].vecCenter.y = .0f;
D3DXCreateTextureFromFile(g_pd3dDevice, "배경.bmp", &g_Obj[0].g_pTexture);
g_Obj[0].rcSrc.left = 0;
g_Obj[0].rcSrc.top = 0;
g_Obj[0].rcSrc.right = 1000;
g_Obj[0].rcSrc.bottom = 550;
//비행기
g_Obj[1].bVisible = TRUE;
g_Obj[1].vecPosition.x = 100.0f;
g_Obj[1].vecPosition.y = 100.0f;
g_Obj[1].vecCenter.x = .0f;
g_Obj[1].vecCenter.y = .0f;
D3DXCreateTextureFromFile(g_pd3dDevice, "비행기1.jpg", &g_Obj[1].g_pTexture);
g_Obj[1].rcSrc.left = 0;
g_Obj[1].rcSrc.top = 0;
g_Obj[1].rcSrc.right = 30;
g_Obj[1].rcSrc.bottom = 50;
//총알이미지
g_Obj[2].bVisible = FALSE;
g_Obj[2].vecPosition.x = g_Obj[1].vecPosition.x;
g_Obj[2].vecPosition.y = g_Obj[1].vecPosition.y;
g_Obj[2].vecCenter.x = .0f;
g_Obj[2].vecCenter.y = .0f;
D3DXCreateTextureFromFile(g_pd3dDevice, "bullet.bmp", &g_Obj[2].g_pTexture);
g_Obj[2].rcSrc.left = 0;
g_Obj[2].rcSrc.top = 0;
g_Obj[2].rcSrc.right = 5;
g_Obj[2].rcSrc.bottom = 5;
//나아가는 총알이미지를 위해 총알객체 100개정도생성
g_Bullet[0].bVisible = FALSE;
g_Bullet[0].vecPosition.x = .0f;
g_Bullet[0].vecPosition.y = .0f;
g_Bullet[0].vecCenter.x = .0f;
g_Bullet[0].vecCenter.y = .0f;
D3DXCreateTextureFromFile(g_pd3dDevice, "bullet.bmp", &g_Bullet[0].g_pTexture);
g_Bullet[0].rcSrc.left = 0;
g_Bullet[0].rcSrc.top = 0;
g_Bullet[0].rcSrc.right = 50;
g_Bullet[0].rcSrc.bottom = 50;
for(int i = 1 ; i < 100 ; i++)
{
memcpy( &g_Bullet[i], &g_Bullet[0], sizeof(g_Bullet[0]));
}
}
void InitWin(void)
{
// Register the window class
WNDCLASSEX g_wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L,
GetModuleHandle(NULL), NULL, NULL, NULL, NULL,
"D3D Tutorial", NULL };
RegisterClassEx( &g_wc );
// Create the application\'s window
g_hWnd = CreateWindow( "D3D Tutorial", "D3D Tutorial 02: Vertices",
WS_OVERLAPPEDWINDOW, 100, 100, 1000, 500,
NULL, NULL, g_wc.hInstance, NULL );
}
void InitDX(void)
{
InitD3D(g_hWnd);
D3DXCreateSprite(g_pd3dDevice, &g_pSprite);
}
void Initilize(void)
{
InitWin(); //윈도 클래스등록 및 윈도우 생성
InitDX(); //Direcx 초기화
initvector();//배경화면 위치 및 비행기 위치 초기화 및 총알 초기화
// Show the window
ShowWindow( g_hWnd, SW_SHOWDEFAULT ); //윈도우 화면에 뿌려주기
UpdateWindow( g_hWnd ); //윈도화면이 바뀌면 업데이트해주기
}
//-----------------------------------------------------------------------------
// Name: InitD3D()
// Desc: Initializes Direct3D
//-----------------------------------------------------------------------------
HRESULT InitD3D( HWND hWnd )
{
g_pD3D = Direct3DCreate9( D3D_SDK_VERSION );
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory( &d3dpp, sizeof(d3dpp) );
d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&d3dpp, &g_pd3dDevice );
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: Cleanup()
// Desc: Releases all previously initialized objects
//-----------------------------------------------------------------------------
VOID Cleanup()
{
if ( g_pSprite != NULL)
g_pSprite->Release();
if( g_pd3dDevice != NULL )
g_pd3dDevice->Release();
if( g_pD3D != NULL )
g_pD3D->Release();
}
//-----------------------------------------------------------------------------
// Name: Render()
// Desc: Draws the scene
//-----------------------------------------------------------------------------
VOID Render()
{
int k = 0;
// Clear the backbuffer to a blue color
g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,255), 1.0f, 0 );
// Begin the scene
if( SUCCEEDED( g_pd3dDevice->BeginScene() ) )
{
g_pSprite->Begin(D3DXSPRITE_ALPHABLEND);
//처음에 배경화면과 비행기를 표현
for(int i=0; i<2; ++i)
{
if(g_Obj[i].bVisible == TRUE)
{
g_pSprite->Draw(g_Obj[i].g_pTexture, &g_Obj[i].rcSrc, &g_Obj[i].vecCenter, &g_Obj[i].vecPosition, 0xffffffff);
}
}
for(int i=0; i<100; ++i)
{
if(g_Bullet[i].bVisible == TRUE)
g_pSprite->Draw(g_Bullet[i].g_pTexture, &g_Bullet[i].rcSrc, &g_Bullet[i].vecCenter, &g_Bullet[i].vecPosition, 0xffffffff);
}
//g_pSprite->Draw(g_pTexture2, &rcSrcRect, &vecCenter, &vecPosition2, 0xffffffff);
//g_pSprite->Draw(g_pTexture, &rcSrcRect1, &vecCenter, &vecPosition, 0xffffffff);
g_pSprite->End();
// End the scene
g_pd3dDevice->EndScene();
}
// Present the backbuffer contents to the display
g_pd3dDevice->Present( NULL, NULL, NULL, NULL );
}
// 키값을 입력받아 처리하는 함수
void Update()
{
if(GetKeyState(VK_LEFT) & 0x80000000)//왼쪽
{
g_Obj[1].vecPosition.x -= 5.0f;
}
else if(GetKeyState(VK_RIGHT) & 0x80000000)
{
g_Obj[1].vecPosition.x += 5.0f;//오른쪽
}
else if(GetKeyState(VK_UP) & 0x80000000)
{
g_Obj[1].vecPosition.y -= 5.0f;//위
}
else if(GetKeyState(VK_DOWN) & 0x80000000)
{
g_Obj[1].vecPosition.y += 5.0f;//아래
}
if(GetKeyState(VK_SPACE) & 0x80000000)//총알발사
{
for(int i=0; i<100; ++i)
{
//총알 이미지가 false값이면 트루로 변경
if(g_Bullet[i].bVisible == FALSE)
{
g_Bullet[i].bVisible = TRUE;
//비행기의 위치에서 총알 발사하기위함
g_Bullet[i].vecPosition = g_Obj[1].vecPosition;
break;
}
}
}
for(int i=0; i<100; ++i)
{
if(g_Bullet[i].bVisible == TRUE)
g_Bullet[i].vecPosition.y -= 5.0f;
if(g_Bullet[i].vecPosition.y <= -50.0f)
g_Bullet[i].bVisible = FALSE;
}
}
//-----------------------------------------------------------------------------
// Name: MsgProc()
// Desc: The window\'s message handler
//-----------------------------------------------------------------------------
LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
switch( msg )
{
case WM_DESTROY:
Cleanup();
PostQuitMessage( 0 );
return 0;
}
return DefWindowProc( hWnd, msg, wParam, lParam );
}
//-----------------------------------------------------------------------------
// Name: WinMain()
// Desc: The application\'s entry point
//-----------------------------------------------------------------------------
INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, INT )
{
Initilize();
MSG msg;
ZeroMemory( &msg, sizeof(msg) );
while( msg.message!=WM_QUIT )
{
//메세지큐에 메시지가있으면 처리
if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
//메세지가없다면
else
{
Update(); //키보드입력에 대한 변화 비행기 이동 및 스페이스바에 의한 총알 발사위치 지정
Render(); //dx를 이용하여 화면에 비행기 및 총알 이미지출력
}
}
UnregisterClass( "D3D Tutorial", g_wc.hInstance );
return 0;
}
댓글 영역
획득법
① NFT 발행
작성한 게시물을 NFT로 발행하면 일주일 동안 사용할 수 있습니다. (최초 1회)
② NFT 구매
다른 이용자의 NFT를 구매하면 한 달 동안 사용할 수 있습니다. (구매 시마다 갱신)
사용법
디시콘에서지갑연결시 바로 사용 가능합니다.