📄 explosion.cpp
字号:
#include "explosion.h"
CExplosion::CExplosion(int numParticles, CVector origin, float spread, GLuint texture)
: m_texture(texture), m_spread(spread), CParticleSystem(numParticles, origin)
{
srand(timeGetTime());
CParticleSystem::InitializeSystem();
Emit(numParticles);
}
// 设置初始粒子的属性
void CExplosion::InitializeParticle(int index)
{
// 在发射区域的随机位置开始粒子运动
m_particleList[index].m_pos.x = m_origin.x + FRAND * m_spread;
m_particleList[index].m_pos.y = m_origin.y + FRAND * m_spread;
m_particleList[index].m_pos.z = m_origin.z + FRAND * m_spread;
// 设置粒子的大小
m_particleList[index].m_size = PARTICLE_SIZE + FRAND * SIZE_VARIATION;
// 给定粒子一个随机速度
m_particleList[index].m_velocity.x = PARTICLE_VELOCITY.x + FRAND * VELOCITY_VARIATION.x;
m_particleList[index].m_velocity.y = PARTICLE_VELOCITY.y + FRAND * VELOCITY_VARIATION.y;
m_particleList[index].m_velocity.z = PARTICLE_VELOCITY.z + FRAND * VELOCITY_VARIATION.z;
m_particleList[index].m_acceleration = PARTICLE_ACCELERATION;
m_particleList[index].m_color[0] = 1.0;
m_particleList[index].m_color[1] = 0.5 + FRAND * 0.5;
m_particleList[index].m_color[2] = 0.0;
m_particleList[index].m_color[3] = 1.0;
m_particleList[index].m_energy = 1.5 + FRAND/2.0;
m_particleList[index].m_colorDelta[0] = 0.0;
m_particleList[index].m_colorDelta[1] = -(m_particleList[index].m_color[1]/2.0)/m_particleList[index].m_energy;
m_particleList[index].m_colorDelta[2] = 0.0;
m_particleList[index].m_colorDelta[3] = -1.0/m_particleList[index].m_energy;
m_particleList[index].m_sizeDelta = -m_particleList[index].m_size/m_particleList[index].m_energy;
}
// 更新存在的粒子,消灭死亡的粒子和创建新的粒子
void CExplosion::Update(float elapsedTime)
{
for (int i = 0; i < m_numParticles; )
{
// 根据速度和时间,更新粒子的位置
m_particleList[i].m_pos = m_particleList[i].m_pos + m_particleList[i].m_velocity * elapsedTime;
m_particleList[i].m_velocity = m_particleList[i].m_velocity + m_particleList[i].m_acceleration * elapsedTime;
m_particleList[i].m_energy -= elapsedTime;
m_particleList[i].m_size += m_particleList[i].m_sizeDelta * elapsedTime;
m_particleList[i].m_color[3] += m_particleList[i].m_colorDelta[3] * elapsedTime;
m_particleList[i].m_color[1] += m_particleList[i].m_colorDelta[1] * elapsedTime;
// 如果粒子碰到地面,则该粒子死亡
if (m_particleList[i].m_energy <= 0.0)
{
// 将最后的粒子运动到当前的位置,并减少数量
m_particleList[i] = m_particleList[--m_numParticles];
}
else
{
++i;
}
}
}
// 绘制粒子
void CExplosion::Render()
{
float viewMatrix[16];
glGetFloatv(GL_MODELVIEW_MATRIX, viewMatrix);
CVector right(viewMatrix[0], viewMatrix[4], viewMatrix[8]);
CVector up(viewMatrix[1], viewMatrix[5], viewMatrix[9]);
glDisable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_DST_ALPHA);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, m_texture);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
GLfloat size;
CVector pos;
glBegin(GL_QUADS);
for (int i = 0; i < m_numParticles; ++i)
{
size = m_particleList[i].m_size/2;
pos = m_particleList[i].m_pos;
glColor4fv(m_particleList[i].m_color);
glTexCoord2f(0.0, 0.0); glVertex3fv((pos + (right + up) * -size).v);
glTexCoord2f(1.0, 0.0); glVertex3fv((pos + (right - up) * size).v);
glTexCoord2f(1.0, 1.0); glVertex3fv((pos + (right + up) * size).v);
glTexCoord2f(0.0, 1.0); glVertex3fv((pos + (up - right) * size).v);
}
glEnd();
glDisable(GL_TEXTURE_2D);
glDisable(GL_BLEND);
glEnable(GL_DEPTH_TEST);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -