//定义粒子系统状态
#define PARTICLE_STATE_DEAD 0
#define PARTICLE_STATE_ALIVE 1
//定义粒子的类型
#define PARTICLE_TYPE_FLICKER 0
#define PARTICLE_TYPE_FADE 1
//定义粒子颜色
#define PARTICLE_COLOR_RED 0
#define PARTICLE_COLOR_GREEN 1
#define PARTICLE_COLOR_BLUE 2
#define PARTICLE_COLOR_WHITE 3
//定义粒子数
#define MAX_PARTICLES 512
//颜色调色板索引范围
#define COLOR_RED_START 32
#define COLOR_RED_END 47
#define COLOR_GREEN_START 96
#define COLOR_GREEN_END 111
#define COLOR_BLUE_START 144
#define COLOR_BLUE_END 159
#define COLOR_WHITE_START 16
#define COLOR_WHITE_END 31
//风力与重力影响x轴和y轴上速度大小
const float particle_wind = 0.0f;
const float particle_gravity = 0.0f;
typedef struct tagPARTCLE
{
int state; //粒子状态
int type; //粒子效果类型
int x,y; //位置
int xv,yv; //粒子速度
int curr_color; //当前颜色
int start_color; //开始颜色调色板索引
int end_color; //结束颜色调色板索引
int counter; //生命周期,帧数
int max_count; //最大生命周数
}PARTICLE, *PARTICLE_PTR;
class Particle {
public:
PARTICLE particles[MAX_PARTICLES];
Particle() { Init_Reset_Particles(); }
public:
void Init_Reset_Particles(void);
void Start_Particle(int type, int color, int count,
float x, float y, float xv, float yv);
void Process_Particles(void);
void Draw_Particles(void);
//模拟粒子爆炸效果
void Start_Particle_Explosion(int type, int color, int count,
int x, int y, int xv, int yv, int num_particles);
void Start_Particle_Ring(int type, int color, int count,
int x, int y, int xv, int yv, int num_particles);
};
#include "particle.h"
void Particle::Init_Reset_Particles(void)
{
for (int index=0; index= particles[index].max_count)
{
particles[index].state = PARTICLE_STATE_DEAD;
}
}
else
{
if (++particles[index].counter >= particles[index].max_count)
{
particles[index].counter = 0;
if (++particles[index].curr_color>particles[index].end_color)
{
particles[index].state = PARTICLE_STATE_DEAD;
}
}
}
//屏幕边界测试
if (particles[index].x>SCREEN_WIDTH ||
particles[index].x<0 ||
particles[index].y>SCREEN_HEIGHT||
particles[index].y<0)
{
particles[index].state = PARTICLE_STATE_DEAD;
}
}
}
}
void Particle::Draw_Particles(void)
{
DDraw_Lock_Back_Surface();
for (int index=0; index=SCREEN_WIDTH || x<0 || y>=SCREEN_HEIGHT || y<0)
continue;
Draw_Pixel(x,y,particles[index].curr_color,back_buffer, back_lpitch);
}
}
DDraw_Unlock_Back_Surface();
}
void Particle::Start_Particle_Explosion(int type, int color, int count,
int x, int y, int xv, int yv, int num_particles)
{
while(--num_particles >=0)
{
int ang=rand()%360;
float vel = 2+rand()%4;
Start_Particle(type, color, count,
x+RAND_RANGE(-50,50), y+RAND_RANGE(-50,50),
xv+cos_look[ang]*vel, yv+sin_look[ang]*vel);
}
}
void Particle::Start_Particle_Ring(int type, int color, int count,
int x, int y, int xv, int yv, int num_particles)
{
// this function starts a particle explosion at the given position and velocity
// note the use of look up tables for sin,cos
// compute random velocity on outside of loop
float vel = 200+rand()%4;
while(--num_particles >=0)
{
// compute random trajectory angle
int ang = rand()%360;
// start the particle
Start_Particle(type,color,count,
x,y,
xv+cos_look[ang]*vel,
yv+sin_look[ang]*vel);
} // end while
}