读了那篇文章后自己也去动手,嘿嘿,没想到真的做出来了,可惜不是很好,但是还算可以看的过去……
下雪,对于我们北方的朋友来说一定很熟悉了,南方的朋友也一定从电视等等看过了吧,嘿嘿,下雪的时候还是挺美的,这么大了,还没有仔细的看过下雪呢,=。=,请勿见笑!好了开始正题了……
(-)特征描述
(1)雪花有不同的形状或大小
(2)雪花不是直线落下的,受空气阻力会到处飘荡
(3)雪花受空气阻力不同,其下落速度也不同
(4)雪花因视觉关系,离我们越远看起来感觉越小
(5)雪有时下得大,有时下得小
(6)下雪时,有时会刮风
要使雪花具备以上特征,这样会真实点,有的时候根据地图的不同等等因素也需要适当的改变(随机应变了^_^)
(二)着手写代码
先写头文件,CGame_ParticleSnow.h
#ifndef _CGAME_PARTICLESNOW_H
#define _CGAME_PARTICLESNOW_H
#pragma message("This File Have Load Bitmap!")
#i nclude <stdlib.h>
#i nclude <math.h>
#i nclude <time.h>
#i nclude "CGame_Engine.h"
typedef struct{
int x,y; //粒子坐标
int z; //雪,粒子层次
int vx,vy; //粒子在X,Y轴的速度
RECT rect; //粒子图片格子
bool bDeath; //粒子已死亡?
}PARTICLE_SNOW; //粒子体
typedef struct PARTICLE_SNOW_NODE{
PARTICLE_SNOW *snow; //一个层次的雪
int snow_num; //改层次雪的数目
PARTICLE_SNOW_NODE *next;
}PARTICLE_SNOW_NODE; //粒子节点(其实这里可以不用链表的,比如数组就可以解决问题了)
class CGame_ParticleSnow
{
private:
PARTICLE_SNOW_NODE *first_node; //头节点
PARTICLE_SNOW_NODE *cur_node; //当前节点
PARTICLE_SNOW_NODE *arragement_node[5]; //用于保存每个层次的节点,为了更快的速度
LPDIRECTDRAWSU***CE7 lpDDSPic;
bool bShowSnow; //下雪?
int s_width; //下雪区域宽度 默认800×600
int s_height; //下雪区域高度
DWORD beg_time; //用于延时计算
DWORD cur_time;
char wind_dir; //当前雪的方位
public:
CGame_ParticleSnow(void); //构造
~CGame_ParticleSnow(void); //析构
BOOL Init(void); //初始化
BOOL Draw(LPDIRECTDRAWSU***CE7 lpDDSTemp); //画雪花
BOOL Restore(void); //恢复
void Release(void); //释放
void Enshow(bool val = true); //可见?
void SetSize(int &width, int &height); //设定屏幕大小
private:
void CreateNode(void); //创建节点
PARTICLE_SNOW CreateParticle(void); //创建雪花
void GetPoint(PARTICLE_SNOW &tmp); //得到改雪花的下一个坐标
void GetSpeed(int &vx, int &vy, int &z); //雪花速度
void GetArrangement(int &ar); //雪花层次
int Random(int min, int max); //随机函数
};
#endif
呵呵,粒子系统真的很充分利用随机函数了,原以为没什么用rand()终于排上用场喽,关于随机函数我是这样写的:
int Random(int min, int max)
{
int back = -1;
while ((back = rand()*max/MAX_RAND) < min);
return back;
} 可以得到min-(max-1)之间的随机数,更好的可以在执行该函数前执行srand((unsigned int)time(NULL)); 逝每次随机数不相同……
接下来是源文件了:
#i nclude "CGame_ParticleSnow.h"
#define _MAX_SNOW_PARTICLE 100 //每个层次的最大雪花数
#define _MAX_H_RESTISTANCE 10 //水平阻力
#define _MAX_V_RESTISTANCE 10 //垂直阻力
#define _MAX_ARRANGEMENT 5 //层次数
#define _MAX_SPEED 100 //最大速度
#define _DELAY_TIME 40 //延时
#define _MAX_SNOW_PIC 4 //雪花类型的数量,依源图片文件而定
CGame_ParticleSnow::CGame_ParticleSnow(void)
{
lpDDSPic = NULL;
first_node = NULL;
cur_node = NULL;
}
CGame_ParticleSnow::~CGame_ParticleSnow(void)
{
Release();
}
BOOL CGame_ParticleSnow::Init(void)
{
s_width = 800;
s_height = 600;
if (!CreateSu***ce(&lpDDSPic, 5, 20)){
return -1;
}
if (!LoadBitmap(lpDDSPic, "Pic//GSnowPic.bmp", TRUE, 0)){
return -2;
}
srand((unsigned)time(NULL));
CreateNode();
bShowSnow = true;
beg_time = 0;
cur_time = 0;
return TRUE;
}
BOOL CGame_ParticleSnow::Draw(LPDIRECTDRAWSU***CE7 lpDDSTemp)
{
if (!bShowSnow){
return TRUE;
}
PARTICLE_SNOW_NODE *tmp_node = first_node;
PARTICLE_SNOW snow;
wind_dir = Random(0, 3);
int death_snow = 0;
while (tmp_node != NULL){
for (int i = 0; i<tmp_node->snow_num; i++){
if (tmp_node->snow.bDeath){
death_snow++;
}
}
tmp_node = tmp_node->next;
}
bool z[4] = {false, false, false, false};
for (int i = 0; i<death_snow; i++){
bool isFind = false;
snow = CreateParticle();
if (!z[snow.z]){
for (int j = 0; j<arragement_node[snow.z]->snow_num; j++){
if (arragement_node[snow.z]->snow[j].bDeath){
arragement_node[snow.z]->snow[j] = snow;
isFind = true;
break;
}
}
if (!isFind){
z[snow.z] = true;
}
}
}
bool isRest = false;
cur_time = timeGetTime();
if ((cur_time-beg_time)>=_DELAY_TIME){
isRest = true;
beg_time = cur_time;
}
tmp_node = first_node;
while (tmp_node != NULL){
for (int i = 0; i<tmp_node->snow_num; i++){
if (isRest){
GetPoint(tmp_node->snow);
if ((tmp_node->snow.x>=(s_width))||(tmp_node->snow.x<0)||(tmp_node->snow.y>=(s_height))||(tmp_node->snow.y<0)){
tmp_node->snow.bDeath = true;
}
}
if (!tmp_node->snow.bDeath){
if (!Blt(lpDDSTemp, tmp_node->snow.x, tmp_node->snow.y, lpDDSPic, tmp_node->snow.rect, TRUE)){
return -1;
}
}
}
tmp_node = tmp_node->next;
}
return TRUE;
}
BOOL CGame_ParticleSnow::Restore(void)
{
return TRUE;
}
void CGame_ParticleSnow::Release(void)
{
ReleaseSu***ce(lpDDSPic);
if (first_node != NULL){
PARTICLE_SNOW_NODE *tmp = first_node->next;
while (tmp!=NULL){
tmp = first_node->next;
delete []first_node->snow;
delete first_node;
first_node = tmp;
}
first_node = NULL;
}
}
void CGame_ParticleSnow::CreateNode(void)
{
first_node = new PARTICLE_SNOW_NODE;
cur_node = first_node;
first_node->snow_num = Random(2, _MAX_SNOW_PARTICLE);
first_node->snow = new PARTICLE_SNOW[first_node->snow_num];
for (int i = 0; i<first_node->snow_num; i++){
first_node->snow = CreateParticle();
}
arragement_node[0] = first_node;
for (i = 0; i<4; i++){
PARTICLE_SNOW_NODE *tmp = new PARTICLE_SNOW_NODE;
tmp->next = NULL;
tmp->snow_num = Random(2, _MAX_SNOW_PARTICLE);
tmp->snow = new PARTICLE_SNOW[tmp->snow_num];
for (int j = 0; j<tmp->snow_num; j++){
tmp->snow[j] = CreateParticle();
}
arragement_node = tmp;
cur_node->next = tmp;
cur_node = tmp;
}
}
PARTICLE_SNOW CGame_ParticleSnow::CreateParticle(void)
{
PARTICLE_SNOW back;
GetArrangement(back.z);
GetSpeed(back.vx, back.vy, back.z);
int i = Random(0, _MAX_SNOW_PIC);
if (i>=4){
i = 3;
}
back.rect.left = 0;
back.rect.right = 5;
back.rect.top = i*5;
back.rect.bottom = (i+1)*5;
back.x = Random(0, s_width);
back.y = Random(0, 10);
back.bDeath = false;
return back;
}
void CGame_ParticleSnow::GetPoint(PARTICLE_SNOW &tmp)
{
tmp.x+=tmp.vx;
tmp.y+=tmp.vy;
}
void CGame_ParticleSnow::GetArrangement(int &ar)
{
ar = Random(0, _MAX_ARRANGEMENT);
if (ar>=5){
ar = 4;
}
}
void CGame_ParticleSnow::GetSpeed(int &vx, int &vy, int &z)
{
int power = Random(1, _MAX_H_RESTISTANCE);
if (wind_dir){
vx = _MAX_SPEED/power/(z+1);
}else if (wind_dir == 0){
vx = -(_MAX_SPEED/power/(z+1));
}else if (wind_dir == 3){
vx = 0;
}
power = Random(1, _MAX_V_RESTISTANCE);
vy = _MAX_SPEED/power/(z+1);
}
void CGame_ParticleSnow::SetSize(int &width, int &height)
{
s_width = width;
s_height = height;
}
void CGame_ParticleSnow::Enshow(bool val)
{
bShowSnow = val;
}
int CGame_ParticleSnow::Random(int min, int max)
{
int back;
while ((back = (rand()*max/RAND_MAX))<min);
return back;
}
自己去动手吧,做出属于自己的粒子系统,为了游戏,去描述奇妙的大自然吧,^_^
关于2D游戏编程-粒子系统(雪)的实现
最新推荐文章于 2024-05-29 14:48:22 发布