📄 ch21p1_plasmagun.cpp
字号:
#include "Ch21p1_PlasmaGun.h"
#include "D3DUtil.h"
CPlasmaGun::CPlasmaGun()
{
m_pBulletArray = NULL;
}
CPlasmaGun::~CPlasmaGun()
{
}
HRESULT CPlasmaGun::RestoreDeviceObjects(LPDIRECT3DDEVICE8 pDev, const char *strMeshFilename)
{
CGun::RestoreDeviceObjects(pDev, strMeshFilename);
return S_OK;
}
void CPlasmaGun::InvalidateDeviceObjects()
{
CGun::InvalidateDeviceObjects();
}
void CPlasmaGun::Render(CCamera &camera)
{
if (!m_pd3dDevice) return;
// create a light
{
D3DLIGHT8 light; ZeroMemory(&light, sizeof(D3DLIGHT8));
// plasma gun looks metallic & while
D3DUtil_InitLight(light, D3DLIGHT_DIRECTIONAL, -10.0f, 20.0f, -20.0f);
light.Ambient.a = 1.0f;
light.Ambient.g = 0.1f;
light.Ambient.b = light.Ambient.r = 0.0f;
light.Diffuse.a = 1.0f;
light.Diffuse.g = 0.3f;
light.Diffuse.b = light.Diffuse.r = 0.0f;
light.Direction = D3DXVECTOR3(1.0f, -1.0f, 1.0f);
m_pd3dDevice->SetRenderState( D3DRS_LIGHTING, TRUE);
m_pd3dDevice->SetLight(0, &light);
m_pd3dDevice->LightEnable(0, true);
}
// render gun model
{
float fOffsetZ = -1.0f+(m_Timer.GetTime()*5.0f);
if (fOffsetZ > 0.0f) fOffsetZ = 0.0f;
D3DXMATRIX matWorld;
AssembleWorldMatrix(camera, matWorld,
m_Timer.IsRunning() ?
D3DXVECTOR3(0.0f, 0.0f, fOffsetZ) :
D3DXVECTOR3(0.0f, 0.0f, 0.0f));
m_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );
m_pd3dDevice->SetRenderState(D3DRS_ZENABLE, TRUE);
m_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW );
m_pd3dDevice->SetRenderState( D3DRS_LIGHTING, TRUE);
m_pMesh->Render(m_pd3dDevice);
}
}
void CPlasmaGun::Fire(CCamera &camera)
{
if (m_pBulletArray == NULL) {
OutputDebugString("\nCPlasmaGun::Fire: error - I can't fire a bullet because I'm not hooked up to any bullet array.");
return;
}
try {
D3DXMATRIX matWorld, matInvView;
D3DXVECTOR3 vPosition = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
D3DXVECTOR3 vVelocity = D3DXVECTOR3(0.0f, 0.0f, 1.0f);
D3DXVECTOR3 vPositionOut, vVelocityOut;
float fDet;
// invert view and remove translation
D3DXMatrixInverse(&matInvView, &fDet, &camera.GetViewMatrix());
matInvView._41 = 0.0f;
matInvView._42 = 0.0f;
matInvView._43 = 0.0f;
AssembleWorldMatrix(camera, matWorld);
D3DXVec3TransformCoord(&vPositionOut,&vPosition, &matWorld);
D3DXVec3TransformCoord(&vVelocityOut,&vVelocity, &matInvView);
m_pBulletArray->AddBullet(vPositionOut, vVelocityOut*50.0f);
m_Timer.Begin();
}
catch(...) { return; }
}
bool CPlasmaGun::CanFire()
{
if (m_Timer.GetTime() > 0.1f) {
m_Timer.Stop();
}
return(!m_Timer.IsRunning());
}
///////////////////////////////////////////////////////////////////////////////
//
// CPlasmaBulletArray
//
///////////////////////////////////////////////////////////////////////////////
// maximum of 20 plasma bullets at once
const int CPlasmaBulletArray::NUMBULLETS = 100;
CPlasmaBulletArray::CPlasmaBulletArray()
{
}
CPlasmaBulletArray::~CPlasmaBulletArray()
{
}
HRESULT CPlasmaBulletArray::RestoreDeviceObjects(LPDIRECT3DDEVICE8 pDev)
{
HRESULT hr;
m_pd3dDevice = pDev;
m_pBullets = new CRecyclingArrayDyn<CPlasmaBullet>(NUMBULLETS);
hr = m_pd3dDevice->CreateVertexBuffer(
NUMBULLETS*sizeof(VERTEX_XYZ_DIFFUSE_TEX1)*6,
0, D3DFVF_XYZ_DIFFUSE_TEX1, D3DPOOL_MANAGED, &m_pVB);
if (FAILED(hr)) return(hr);
m_pAnim = new CAnimSequence(pDev);
m_pAnim->AddFrame("Ch21p1_PlasmaBullet_01.dds", 20.0f);
return(S_OK);
}
void CPlasmaBulletArray::AddBullet(D3DXVECTOR3 vPos, D3DXVECTOR3 vVelocity)
{
try {
CPlasmaBullet *newbullet = m_pBullets->New();
newbullet->Pos() = vPos;
newbullet->Velocity() = vVelocity;
newbullet->m_Sprite.SetAnim(m_pAnim);
newbullet->m_Sprite.Timer().Begin();
newbullet->m_Sprite.SetSize(RandomNumber(5.0f, 10.0f));
}
catch(...) { return; }
}
HRESULT CPlasmaBulletArray::InvalidateDeviceObjects()
{
SAFE_DELETE(m_pBullets);
SAFE_RELEASE(m_pVB);
SAFE_DELETE(m_pAnim);
return(S_OK);
}
void CPlasmaBulletArray::UpdateAll(float fElapsedTime)
{
for (int q=0; q < NUMBULLETS; q++) {
if (m_pBullets->IsAlive(q)) {
CPlasmaBullet &bullet = m_pBullets->GetAt(q);
bullet.Pos() += bullet.Velocity()*fElapsedTime;
if (bullet.m_Sprite.Timer().IsRunning() &&
bullet.m_Sprite.Timer().GetTime() > 5.0f) {
m_pBullets->Delete(q);
}
}
}
}
void CPlasmaBulletArray::RenderAll(CCamera &camera)
{
m_pd3dDevice->SetRenderState(D3DRS_LIGHTING, FALSE );
m_pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE );
m_pd3dDevice->SetRenderState(D3DRS_ZENABLE, FALSE);
m_pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE);
m_pd3dDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_ONE );
m_pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ONE );
m_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
m_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
m_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
m_pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
m_pd3dDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
// render all the bullets via one call to DrawPrimitive
for (int q=0; q < NUMBULLETS; q++) {
if (m_pBullets->IsAlive(q)) {
CPlasmaBullet &bullet = m_pBullets->GetAt(q);
bullet.m_Sprite.Pos() = bullet.Pos();
bullet.m_Sprite.Render(camera.GetViewMatrix());
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -