📄 game.cpp
字号:
// D3DTemple.cpp : Defines the entry point for the application.
//
#include <windows.h>
#include <d3d9.h>
#include <d3dx9.h>
#include <mmsystem.h>
#include "Terrain.h"
#include "SkinMesh.h"
#include "GInput.h"
#include "Camera.h"
#pragma comment (lib,"winmm.lib")
#pragma comment (lib,"d3d9.lib")
#pragma comment (lib,"d3dx9.lib")
LPDIRECT3D9 g_pD3D;
LPDIRECT3DDEVICE9 g_pD3DDevice;
//D3DXVECTOR3 vRole;
//D3DXVECTOR3 vDir;
CSkinMesh *g_pRole;
CSkinMesh *g_pCar;
CGInput *g_pInput;
CCamera *g_pCamera;
//////////////////////////////////////////////
CTerrain *pTerrain;
LPD3DXFONT g_pFont;
float startTime;
float timeNow;
float tFrameTime;
#ifndef SAFE_DELETE
#define SAFE_DELETE(p) { if(p) { delete (p); (p)=NULL; } }
#endif
#ifndef SAFE_DELETE_ARRAY
#define SAFE_DELETE_ARRAY(p) { if(p) { delete[] (p); (p)=NULL; } }
#endif
#ifndef SAFE_RELEASE
#define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } }
#endif
/////////////////////////////////////////////////
LRESULT ClearD3D()
{
SAFE_RELEASE(g_pFont);
SAFE_DELETE(g_pCamera);
SAFE_DELETE(g_pRole);
SAFE_DELETE(pTerrain);
SAFE_DELETE(g_pInput);
SAFE_RELEASE(g_pD3DDevice);
SAFE_RELEASE(g_pD3D);
return D3D_OK;
}
//绘制AABB盒
static void RenderAABB(LPDIRECT3DDEVICE9 pDevice,D3DXVECTOR3 *pVmin,D3DXVECTOR3 *pVmax)
{
/*
0------MAX
/ /|
/ / |
3-----2 5
| | /
| |/
min------6
*/
struct VERTEX_BOUNDINGBOX
{
float x,y,z;
DWORD color;
};
#define D3DFVF_CUSTOM_BOUNDINGBOX D3DFVF_XYZ|D3DFVF_DIFFUSE
VERTEX_BOUNDINGBOX VB[]
={
{pVmin->x,pVmax->y,pVmax->z,0xffff0000}, //上表面
{pVmax->x,pVmax->y,pVmax->z,0xffff0000},
{pVmax->x,pVmax->y,pVmin->z,0xffff0000},
{pVmin->x,pVmax->y,pVmin->z,0xffff0000},
{pVmin->x,pVmin->y,pVmax->z,0xffff0000}, //下边四条线
{pVmax->x,pVmin->y,pVmax->z,0xffff0000},
{pVmax->x,pVmin->y,pVmin->z,0xffff0000},
{pVmin->x,pVmin->y,pVmin->z,0xffff0000},
};
WORD IB[]=
{0,1,1,2,2,3,3,0,
4,5,5,6,6,7,7,4,
0,4,1,5,2,6,3,7};
D3DXMATRIX matIdentity;
D3DXMatrixIdentity(&matIdentity);
pDevice->SetTransform(D3DTS_WORLD, &matIdentity);
pDevice->SetTexture(0,NULL);
pDevice->SetFVF(D3DFVF_CUSTOM_BOUNDINGBOX);
pDevice->DrawIndexedPrimitiveUP(D3DPT_LINELIST,0,24,12,IB,D3DFMT_INDEX16,
VB,sizeof(VERTEX_BOUNDINGBOX));
};
LRESULT InitD3D(HWND hwnd)
{
g_pD3D=Direct3DCreate9(D3D_SDK_VERSION);
D3DPRESENT_PARAMETERS d3dpp;
D3DDISPLAYMODE d3ddm;
g_pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT,&d3ddm);
memset(&d3dpp,0,sizeof(d3dpp));
d3dpp.SwapEffect=D3DSWAPEFFECT_DISCARD ; //设置交换模式
d3dpp.Windowed=TRUE;
d3dpp.BackBufferFormat=d3ddm.Format;
d3dpp.BackBufferCount=1;
d3dpp.hDeviceWindow=hwnd;
d3dpp.EnableAutoDepthStencil=TRUE;
d3dpp.AutoDepthStencilFormat=D3DFMT_D16;
g_pD3D->CreateDevice(D3DADAPTER_DEFAULT ,D3DDEVTYPE_HAL,NULL,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,&d3dpp, &g_pD3DDevice);
OutputDebugString("创建设备\n");
// g_pD3DDevice->SetRenderState(D3DRS_CULLMODE,D3DCULL_NONE);
// g_pD3DDevice->SetRenderState(D3DRS_FILLMODE,D3DFILL_WIREFRAME);
g_pD3DDevice->SetRenderState(D3DRS_LIGHTING,FALSE);
g_pD3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
g_pD3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
g_pD3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
g_pD3DDevice->SetSamplerState(0,D3DSAMP_MINFILTER,D3DTEXF_LINEAR);
g_pD3DDevice->SetSamplerState(0,D3DSAMP_MAGFILTER,D3DTEXF_LINEAR);
g_pD3DDevice->SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_BLENDTEXTUREALPHA);
#if(D3D_SDK_VERSION==32)
D3DXCreateFont(g_pD3DDevice,16,0,0,1,0,ANSI_CHARSET,0,0,0,"Comic Sans MS",&g_pFont);
#else
HFONT hFont = CreateFont(16, 0, 1, 0, 0, 1, 0, 0,
ANSI_CHARSET, 0, 0, 0, 0, "Comic Sans MS");
D3DXCreateFont(g_pD3DDevice,hFont,&g_pFont);
#endif
pTerrain=new CTerrain(g_pD3DDevice,D3DXVECTOR3(0,0,0));
pTerrain->Initialize("Terrain_128_RGB.bmp","terr_dirt-grass.jpg",20,200,5);
g_pRole=new CSkinMesh(g_pD3DDevice);
g_pRole->LoadFromXFile("Hero.x");
g_pRole->SetAnimationName("walk");
g_pCar=new CSkinMesh(g_pD3DDevice);
g_pCar->LoadFromXFile("cardealers.X");
g_pCar->SetScale(5.0f);
g_pCar->SetPosition(200,0,0);
g_pCamera=new CCamera(g_pD3DDevice,&D3DXVECTOR3(0,0,0));
g_pCamera->SetTrackMode(FALSE);
return D3D_OK;
}
LRESULT FrameStart()
{
tFrameTime=timeGetTime()/1000.0f-timeNow;
timeNow+=tFrameTime;
g_pInput->Update(); //更新,获取输入
float fYaw=0,fPitch=0;
float dForward=0,dSide=0;
fYaw=g_pInput->GetLX()*0.2f*D3DX_PI/180;
fPitch=g_pInput->GetLY()*0.2f*D3DX_PI/180;
float speed=100.0f;
if(0x80&g_pInput->GetIsKeyDown(DIK_W))
dForward+=speed*tFrameTime;
else if(0x80&g_pInput->GetIsKeyDown(DIK_S))
dForward-=speed*tFrameTime;
if(0x80&g_pInput->GetIsKeyDown(DIK_D))
dSide+=speed*tFrameTime;
else if(0x80&g_pInput->GetIsKeyDown(DIK_A))
dSide-=speed*tFrameTime;
dSide*=60*tFrameTime*D3DX_PI/180; //按一次转0.25角度
g_pCamera->MoveRelative(0,g_pInput->GetLZ()/10.0f);
if(g_pInput->GetIsKeyDown(MK_RIGHT))
{
g_pCamera->YawPitchAt(fYaw,fPitch);
g_pRole->Turn(fYaw+dSide);
}
else
{
g_pRole->Turn(dSide);
}
g_pRole->WalkFoward(dForward);
//碰撞检测
if(g_pRole->CollisionTestAABB(g_pCar))
g_pRole->Back(); //如果产生碰撞就退回
//设置角色高度
g_pRole->SetAltitude(pTerrain->GetHeight(g_pRole->GetPosition()->x,
g_pRole->GetPosition()->z));
g_pCamera->SetLookAt(&(*g_pRole->GetPosition()+D3DXVECTOR3(0,15,0)));
//是否以线框方式显示
if(g_pInput->GetIsKeyDown(DIK_F1)&0x80)
g_pD3DDevice->SetRenderState(D3DRS_FILLMODE,D3DFILL_WIREFRAME);
else if(g_pInput->GetIsKeyDown(DIK_F2)&0x80)
g_pD3DDevice->SetRenderState(D3DRS_FILLMODE,D3DFILL_SOLID);
return D3D_OK;
}
LRESULT RenderLine(int x,int y,char *strText,DWORD color)
{
RECT rect={x,y,x+500,y+30};
#if(D3D_SDK_VERSION==32)
g_pFont->DrawText(NULL,strText,(INT)strlen(strText),&rect,DT_LEFT,color);
#else
g_pFont->DrawText(strText,strlen(strText),&rect,DT_LEFT,color);
#endif
return S_OK;
}
LRESULT RenderText()
{ char *strInf[]=
{"[F1]WireFrame",
"[F2]Solid",
"[WS]Walk Foward/Back",
"[AD]Turn",
"[RButton]Turn Camera",
"[Wheel]Zoom In/Out"
};
for(int i=0;i<6;i++)
{
DWORD t=255*(0.55f+0.45f*sinf(5*timeNow+D3DX_PI*i/5.0f));
RenderLine(0,i*20,strInf[i],(0xFF*t+0xFFFF0000));
}
return S_OK;
}
LRESULT Render()
{
FrameStart();
g_pD3DDevice->Clear(NULL,NULL,D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,D3DCOLOR_XRGB(0,0,0),1.0,0);
g_pD3DDevice->BeginScene();
g_pCamera->Update3DMatrix(tFrameTime);
g_pRole->Render(tFrameTime);
D3DXVECTOR3 vMin,vMax;
g_pRole->GetBoundingBox(&vMin,&vMax);
RenderAABB(g_pD3DDevice, &vMin,&vMax);
g_pCar->Render(tFrameTime);
g_pCar->GetBoundingBox(&vMin,&vMax);
RenderAABB(g_pD3DDevice, &vMin,&vMax);
pTerrain->Render();
RenderText();
g_pD3DDevice->EndScene();
g_pD3DDevice->Present(0,0,0,0);
return D3D_OK;
}
LRESULT CALLBACK WndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch( message )
{
case WM_CREATE:
return 0;
case WM_KEYDOWN:
if(wParam==VK_ESCAPE)
PostQuitMessage( 0 );
return 0;
case WM_DESTROY:
PostQuitMessage( 0 );
return 0;
}
return DefWindowProc( hwnd, message, wParam, lParam );
}
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
static TCHAR szAppName[]= TEXT("HelloWin");
static TCHAR szClassName[]= TEXT("HelloWinClass");
HWND hwnd;
MSG msg;
WNDCLASS wndclass=
{CS_HREDRAW|CS_VREDRAW,WndProc,0,0,hInstance,
NULL,LoadCursor(NULL,IDC_ARROW),(HBRUSH)GetStockObject(WHITE_BRUSH),NULL,szClassName};
if(! RegisterClass(&wndclass))
{
MessageBox(NULL,"Register Class Failed!",MB_OK,MB_ICONERROR);
}
hwnd = CreateWindow( szClassName, TEXT("使用AABB碰撞检测"),WS_OVERLAPPED|WS_SYSMENU|WS_MINIMIZEBOX,
CW_USEDEFAULT,CW_USEDEFAULT,640,480,
NULL,NULL, hInstance,NULL );
ShowWindow(hwnd,nCmdShow);
UpdateWindow( hwnd );
InitD3D(hwnd);
g_pInput=new CGInput(hInstance,hwnd);
// InitVB();
GetMessage( &msg, NULL, 0, 0 );
while (msg.message!=WM_QUIT)
{
// bMessage=GetMessage( &msg, NULL, 0, 0 );
if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
else
{
Render();
Sleep(10);
}
}
UnregisterClass(szClassName,wndclass.hInstance);
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -