📄 game.cpp
字号:
#include "Game.h"
//构造函数,初始化类成员中的窗口句柄和摄像机参数
//参数是主函数中传进来的,代表窗口句柄
Game::Game(HWND hwnd)
{
action=IDLE;
m_hWnd=hwnd;
}
//析构函数 ,负责清空处理
Game::~Game()
{
delete m_pTree1;
delete m_pCamera;
delete m_pTerrain;
m_pd3dDevice->Release ();
m_pD3D->Release ();
}
//初始化整个游戏,包括D3D和游戏元素的初始化
HRESULT Game::Initilise()
{
this->InitiD3D ();//初始化D3D
this->InitiGame ();//初始化游戏要素(地形等)
return S_OK;
}
//初始化D3D
HRESULT Game::InitiD3D()
{
// Create the D3D object.
if( NULL == ( m_pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) )
return E_FAIL;
// Set up the structure used to create the D3DDevice
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory( &d3dpp, sizeof(d3dpp) );
d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
d3dpp.EnableAutoDepthStencil =TRUE;
d3dpp.AutoDepthStencilFormat =D3DFMT_D16;
// Create the D3DDevice
if( FAILED( m_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, m_hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&d3dpp, &m_pd3dDevice ) ) )
{
return E_FAIL;
}
//以下为特效的设置
m_pd3dDevice->SetRenderState (D3DRS_ZENABLE,TRUE);
// 裁减模式为不裁减
m_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
// 关闭光照
m_pd3dDevice->SetRenderState( D3DRS_LIGHTING, FALSE );
//填充模式为线框方式
m_pd3dDevice->SetRenderState (D3DRS_FILLMODE,D3DFILL_WIREFRAME);
return S_OK;
}
//初始化整个游戏要素
HRESULT Game::InitiGame()
{
//初始化地形new(设备接口指针,行数,列数,最大高度,每个格子方块的宽度)
m_pTerrain=new Mesh(m_pd3dDevice,20,16,16,".\\texture.jpg");
//初始化地形,初始化顶点和索引缓冲区
m_pTerrain->Initilise ();
m_pTree1=new Sphere(m_pd3dDevice);
m_pCamera=new Camera();
// 得到鼠标的位置
POINT pt;
GetCursorPos( &pt );
m_dwMouseX = pt.x;
m_dwMouseY = pt.y;
return S_OK;
}
//设置3个变换,(几何,取景,投影变换)
//注意:摄像机参数都是变量m_Player来控制的,可以通过按键来改变摄像机
//注意: 投影的范围要设计好。
HRESULT Game::SetupMatrices()
{
//几何变换,这儿只要设单位矩阵即可。
D3DXMATRIXA16 matWorld;
D3DXMatrixIdentity(&matWorld);
m_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );
//取景变换,按键控制m_Player的值。
D3DXMATRIXA16 matView;
matView=*(m_pCamera->GetViewMatrix ());
m_pd3dDevice->SetTransform( D3DTS_VIEW, &matView );
//投影变换,范围要控制好。(根据地形的大小来控制范围)
D3DXMATRIXA16 matProj;
D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI/4, 1.0f, 1.0f, 5000.0f );//1000为最远范围
m_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj );
return S_OK;
}
//根据屏幕的像素坐标点获取3D空间的坐标点
HRESULT Game::Get3DCoord (POINT p)
{
FLOAT clientWidth,clientHeight;
RECT rc;
GetClientRect(this->m_hWnd ,&rc);
clientWidth = (float)rc.right - rc.left;
clientHeight = (float)rc.bottom - rc.top;
D3DVIEWPORT9 viewPort;
D3DXMATRIX matProj,matView,matWorld;
m_pd3dDevice->GetViewport(&viewPort);
m_pd3dDevice->GetTransform(D3DTS_PROJECTION,&matProj);
m_pd3dDevice->GetTransform(D3DTS_VIEW,&matView);
m_pd3dDevice->GetTransform(D3DTS_WORLD,&matWorld);
viewPort.Height = (DWORD)clientHeight;
viewPort.Width = (DWORD)clientWidth;
D3DXVECTOR3 clientPt = D3DXVECTOR3((float)p.x,(float)p.y,0.0f);
D3DXVECTOR3 ray,nearRay,farRay;
D3DXVec3Unproject(&nearRay,&clientPt,&viewPort,&matProj,&matView,&matWorld);
clientPt.z = 1.0f;
D3DXVec3Unproject(&farRay,&clientPt,&viewPort,&matProj,&matView,&matWorld);
ray = farRay - nearRay;
BOOL hit;
DWORD indexFace;
FLOAT u,v;
/*HRESULT D3DXIntersect
(
LPD3DXBASEMESH pMesh,参数指定用于判断是否和指定射线相交的网格模型
CONST D3DXVECTOR3* pRayPos,指定射线的发出点
CONST D3DXVECTOR3* pRayDir,指定射线方向
BOOL* pHit,用于判断射线是否与网格相交
DWORD * pFaceIndex,返回所有相交三角行中距离最进射线发出最近三角行面的索引
FLOAT * pU ,返回用于计算射线和最近相交三角面的U , V坐标
FLOAT * pV,
FLOAT *pDist,返回从射线出发点到最近交点的距离
LPD3DXBUFFER* ppAllHits,返回结构数组D3DXINTERSECTINFO三角行的相关信息
DWORD* pCountOfHits返回相交三角行数量
)*/
//判断是否与模型相交
D3DXIntersect(m_pTerrain->GetMesh (),m_pCamera->GetCameraPos(),&ray,&hit,&indexFace,&u,&v,NULL,NULL,NULL);
if(hit)
{
//如果相交,获取相交点的坐标
m_pTerrain->GetTerrainVertex(&mouseCross,indexFace,u,v);
}
return S_OK;
}
//按键的处理,分别是上、下、左、右键控制
HRESULT Game::SetInput()
{
POINT pt;
float fDelta = 0.001f; // 鼠标的移动速度
//获取当前鼠标的位置
GetCursorPos( &pt );
ScreenToClient(this->m_hWnd ,&pt);
int dx = pt.x - m_dwMouseX;
int dy = pt.y - m_dwMouseY;
//if(GetAsyncKeyState(VK_RBUTTON))
//{
// m_pCamera->RotateLocalX( dy * fDelta );
// m_pCamera->RotateLocalY( dx * fDelta );
//}
//处理左键按下
if(GetAsyncKeyState(VK_LBUTTON) == -32767)
{
Get3DCoord(pt);
m_pTree1->ReMove();
action = MOVE;
}
//记录下现在鼠标的位置
m_dwMouseX = pt.x;
m_dwMouseY = pt.y;
return S_OK;
}
//游戏的渲染
HRESULT Game::Render ()
{
static DWORD StartTime = timeGetTime();
DWORD ThisTime = timeGetTime();
//清空处理,包括颜色缓冲和深度缓冲
m_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0,0,0), 1.0f, 0 );
// Begin the scene
if( SUCCEEDED( m_pd3dDevice->BeginScene() ) )
{
SetupMatrices();
SetInput();
// Setup the world, view, and projection matrices
D3DXMATRIXA16 matWorld;
D3DXMatrixIdentity(&matWorld);
m_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );
// 开始渲染地形
D3DXMatrixIdentity(&matWorld);
m_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );
m_pTerrain->Render();
D3DXMatrixIdentity(&matWorld);
switch(action)
{
case IDLE:
m_pd3dDevice->SetTransform(D3DTS_WORLD,&(m_pTree1->idle()));
break;
case MOVE:
m_pd3dDevice->SetTransform(D3DTS_WORLD,&(m_pTree1->move(mouseCross,2.5f)));
break;
}
m_pTree1->Render();
m_pd3dDevice->EndScene();
}
m_pd3dDevice->Present( NULL, NULL, NULL, NULL );
return S_OK;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -