用粒子系统模拟烟花效果

//定义粒子系统状态
#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
}


你可能感兴趣的:(Game,Programming,DirectX)