⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ch21p1_plasmagun.cpp

📁 游戏开发特殊技巧-special.effects.game.programming
💻 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 + -