📄 game_particle.cpp
字号:
else if( fLengthSq < 9.00f ) dwSteps = 4;
else if( fLengthSq < 12.25f ) dwSteps = 5;
else if( fLengthSq < 16.00f ) dwSteps = 6;
else if( fLengthSq < 20.25f ) dwSteps = 7;
else dwSteps = 8;
dwSteps=1;
vVel *= -0.04f / (FLOAT)dwSteps;
DWORD dwDiffuse=ColorLerp(pParticle->m_clrEmit,
pParticle->m_clrFade,
1-pParticle->m_fFade/(m_fParticleFade));
for( DWORD i = 0; i < dwSteps; i++ )
{
pVertices->v = vPos;
pVertices->color = dwDiffuse;
pVertices++;
if( ++dwNumParticlesToRender == m_dwFlush )
{
m_pVB->Unlock();
if(FAILED(hr = m_pDevice->DrawPrimitive( D3DPT_POINTLIST, m_dwBase, dwNumParticlesToRender)))
return hr;
m_dwBase += m_dwFlush;
if(m_dwBase >= m_dwDiscard)
m_dwBase = 0;
if( FAILED( hr = m_pVB->Lock( m_dwBase * sizeof(POINTVERTEX), m_dwFlush * sizeof(POINTVERTEX),
(void**) &pVertices, m_dwBase ? D3DLOCK_NOOVERWRITE : D3DLOCK_DISCARD ) ) )
{
return hr;
}
dwNumParticlesToRender = 0;
}
vPos += vVel;
}
pParticle = pParticle->m_pNext;
}
// 把顶点缓冲存储器的锁打开
m_pVB->Unlock();
// 放弃停留粒子
if( dwNumParticlesToRender )
{
if(FAILED(hr = m_pDevice->DrawPrimitive( D3DPT_POINTLIST, m_dwBase, dwNumParticlesToRender )))
return hr;
}
m_pDevice->SetRenderState( D3DRS_POINTSPRITEENABLE, FALSE );
m_pDevice->SetRenderState( D3DRS_POINTSCALEENABLE, FALSE );
m_pDevice->SetRenderState( D3DRS_ZWRITEENABLE, TRUE );
m_pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );
m_pDevice->SetRenderState( D3DRS_LIGHTING,FALSE);
m_pDevice->SetTextureStageState(0,D3DTSS_COLOROP ,D3DTOP_SELECTARG1);
return S_OK;
}
HRESULT CParticleSystem::LoadFromFile(char* strFile,char *strSection)
{
#define STRTEMP_SIZE 128
char strTemp[STRTEMP_SIZE];
float fTemp;
DWORD dwTemp;
GetPrivateProfileString(strSection,"GravityField","0",strTemp,STRTEMP_SIZE,strFile);
fTemp=(float)atof(strTemp);
m_fGravity=fTemp;
GetPrivateProfileString(strSection,"EmitWidth","0",strTemp,STRTEMP_SIZE,strFile);
fTemp=(float)atof(strTemp);
m_EmitWidth=fTemp;
//发射角度
GetPrivateProfileString(strSection,"EmitAngle","0",strTemp,STRTEMP_SIZE,strFile);
fTemp=(float)atof(strTemp);
m_EmitAngle=fTemp*D3DX_PI/180;
//发射频率
GetPrivateProfileString(strSection,"EmitRate","0",strTemp,STRTEMP_SIZE,strFile);
fTemp=(float)atof(strTemp);
if(fTemp>0) m_EmitRate=fTemp;
//发射速率
GetPrivateProfileString(strSection,"EmitVel","0",strTemp,STRTEMP_SIZE,strFile);
fTemp=(float)atof(strTemp);
if(fTemp>0) m_EmitVel=fTemp;
GetPrivateProfileString(strSection,"EmitColor","0",strTemp,STRTEMP_SIZE,strFile);
m_clrEmit=StrOct(strTemp);
GetPrivateProfileString(strSection,"FadeColor","0",strTemp,STRTEMP_SIZE,strFile);
m_clrFade=StrOct(strTemp);
GetPrivateProfileString(strSection,"EmitType","0",strTemp,STRTEMP_SIZE,strFile);
m_dwType=StrOct(strTemp);
//发射方向
float yaw,pitch;
GetPrivateProfileString(strSection,"EmitYaw","0",strTemp,STRTEMP_SIZE,strFile);
yaw=(float)atof(strTemp)*D3DX_PI/180;
GetPrivateProfileString(strSection,"EmitPitch","0",strTemp,STRTEMP_SIZE,strFile);
pitch=(float)atof(strTemp)*D3DX_PI/180;
SetYawPitch(yaw,pitch);
//粒子大小
GetPrivateProfileString(strSection,"ParticleSize","0",strTemp,STRTEMP_SIZE,strFile);
fTemp=(float)atof(strTemp);
if(fTemp>0) m_fParticleSize=fTemp;
//粒子生命周期
GetPrivateProfileString(strSection,"ParticleLife","0",strTemp,STRTEMP_SIZE,strFile);
fTemp=(float)atof(strTemp);
if(fTemp>0) m_fParticleLife=fTemp;
GetPrivateProfileString(strSection,"ParticleFade","0",strTemp,STRTEMP_SIZE,strFile);
fTemp=(float)atof(strTemp);
if(fTemp>0) m_fParticleFade=fTemp;
//粒子数量上限
GetPrivateProfileString(strSection,"ParticlesLimit","0",strTemp,STRTEMP_SIZE,strFile);
dwTemp=atol(strTemp);
if(dwTemp>0) m_dwParticlesLim=dwTemp;
//纹理
GetPrivateProfileString(strSection,"ParticleTexture","\0",strTemp,STRTEMP_SIZE,strFile);
if(strTemp[0]!=0)
{
SAFE_RELEASE(m_pTexture);
D3DXCreateTextureFromFile(m_pDevice,strTemp,&m_pTexture);
}
return S_OK;
}
HRESULT CParticleSystem::Update2( float fSecsPerFrame)
{
static PARTICLE *pParticle, **ppParticle;
static D3DMATRIX matLocal; //用于将粒子的本地坐标,转换到世界空间的矩阵
static D3DVECTOR vLocal;
static float fT=0.0f;
//本地空间:
// xAxis- vDirection X (0,1,0)
// yAxis- vAix*yAxis
// zAxis- vDirection
//本地坐标矩阵的z方向
matLocal._31=m_vDirection.x;
matLocal._32=m_vDirection.y;
matLocal._33=m_vDirection.z;
//本地坐标矩阵的x方向
if(fabsf(m_vDirection.y)<1)
{
matLocal._11=m_vDirection.z;
matLocal._12=0 ;
matLocal._13=-m_vDirection.x;
}
else
{
matLocal._11=1;
matLocal._12=0;
matLocal._13=0;
}
//本地坐标矩阵的y方向
matLocal._21=-matLocal._12*matLocal._33+matLocal._13*matLocal._32;
matLocal._22=-matLocal._13*matLocal._31+matLocal._11*matLocal._33;
matLocal._23=-matLocal._11*matLocal._32+matLocal._12*matLocal._31;
matLocal._41=0;
matLocal._42=0;
matLocal._43=0;
matLocal._44=1;
m_fTime += fSecsPerFrame;
ppParticle = &m_pParticles;
//更新粒子状态
while( *ppParticle )
{
pParticle = *ppParticle;
// 计算新位置
fT = m_fTime - pParticle->m_fTime0;
//活动
pParticle->m_fFade -= fSecsPerFrame;
static bool bArrive = true;
switch(m_dwType)
{
case 0:
//删除旧粒子,到达目标地点的粒子
if(m_bMoving && m_dwParticles > 1)
{
//删除这个粒子,把它加入到消亡链表
*ppParticle = pParticle->m_pNext;
pParticle->m_pNext = m_pParticlesFree;
m_pParticlesFree = pParticle;
m_dwParticles--;
}
else
{
ppParticle = &pParticle->m_pNext;
}
break;
case 1:
if(!m_bLive)
pParticle->m_bMove = TRUE;
if(pParticle->m_bMove)
bArrive = MoveTo(m_vIntersectPoint, &pParticle->m_vPos, 0.1f, 200.0f);
//删除旧粒子,到达目标地点的粒子
if(!bArrive|| m_fTime-pParticle->m_fTime0>m_fParticleLife )// m_fRadius)
{
//删除这个粒子,把它加入到消亡链表
pParticle->m_bMove = FALSE;
*ppParticle = pParticle->m_pNext;
pParticle->m_pNext = m_pParticlesFree;
m_pParticlesFree = pParticle;
m_dwAttackNum++;
m_dwParticles--;
if(!m_dwParticles)
{
m_bMoving = false;
}
}
else
{
ppParticle = &pParticle->m_pNext;
}
break;
case 2:
//删除旧粒子,到达目标地点的粒子
if(m_bMoving)
{
//删除这个粒子,把它加入到消亡链表
*ppParticle = pParticle->m_pNext;
pParticle->m_pNext = m_pParticlesFree;
m_pParticlesFree = pParticle;
m_dwParticles--;
if(!m_dwParticles)
{
m_bMoving = false;
}
}
else
{
ppParticle = &pParticle->m_pNext;
}
break;
}
}
if(m_bLive || (m_dwType == 0 && m_dwParticles < 1))
{
//发射新粒子,每次至少发射一个粒子
DWORD dwParticlesEmit;
switch(m_dwType)
{
case 0:
case 2:
dwParticlesEmit = 3;
break;
case 1:
dwParticlesEmit = m_dwParticles+
DWORD(fSecsPerFrame*m_EmitRate>=1?m_EmitRate*fSecsPerFrame: //发射率算出来的数量大于1
fmodf(m_fTime,1/m_EmitRate)<fSecsPerFrame?1:0); //波形分析,t2=t%T2<T1时,应该发射一个粒子
break;
}
while( m_dwParticles < m_dwParticlesLim && m_dwParticles < dwParticlesEmit )
{
if( m_pParticlesFree ) //如果消亡粒子链表里有,就从消亡链表里取出一个节点
{
pParticle = m_pParticlesFree;
m_pParticlesFree = pParticle->m_pNext;
}
else //如果没有,就再创建
{
if( NULL == ( pParticle = new PARTICLE ) )
return E_OUTOFMEMORY;
}
pParticle->m_pNext = m_pParticles; //加入到活动链表
m_pParticles = pParticle;
pParticle->m_bMove = FALSE;
m_dwParticles++;
m_dwMagicNum++;
// Emit new particle
FLOAT fRand1 = ((FLOAT)rand()/(FLOAT)RAND_MAX) * D3DX_PI * 2.0f;
FLOAT fRand2 = ((FLOAT)rand()/(FLOAT)RAND_MAX) * m_EmitAngle*0.5f; // m_EmitAngle锥形角度,所以是一半
FLOAT Speed = ((FLOAT)rand()/(FLOAT)RAND_MAX*0.2f+0.8f) * m_EmitVel;
//初始化新加入的粒子
vLocal.x=Speed* cosf(fRand1) * sinf(fRand2);
vLocal.y=Speed* sinf(fRand1) * sinf(fRand2);
vLocal.z=Speed* cosf(fRand2);;
pParticle->m_vPos0 = m_vPosition ;
pParticle->m_vVel0.x = vLocal.x*matLocal._11+vLocal.y*matLocal._21+vLocal.z*matLocal._31;//10* cosf(fRand1) * sinf(fRand2) * 2.5f;
pParticle->m_vVel0.y = vLocal.x*matLocal._12+vLocal.y*matLocal._22+vLocal.z*matLocal._32;//10* cosf(fRand1) * sinf(fRand2) * 2.5f;
pParticle->m_vVel0.z = vLocal.x*matLocal._13+vLocal.y*matLocal._23+vLocal.z*matLocal._33;//10* cosf(fRand1) * sinf(fRand2) * 2.5f;
pParticle->m_vPos = pParticle->m_vPos0;
pParticle->m_vVel = pParticle->m_vVel0;
pParticle->m_clrEmit=m_clrEmit;
pParticle->m_clrFade=m_clrFade;
pParticle->m_fFade = m_fParticleFade;
pParticle->m_fTime0 = m_fTime;
}
}
return S_OK;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -