(Visual C++)游戏开发笔记二十三 游戏基础物理建模(五) 粒子系统模拟(二)
一.基础知识讲解
1. 概念与思路
本节讲解的星光绽放demo相当于是一个模拟爆炸(或者说是烟花)特效的demo,浅墨认为这个特效拿出来讲解很多必要性,它可以为很多问题带来的思路的火花。这个demo之中,绽放(爆炸)点为在窗口中由随机数产生的一个位置,绽放(爆炸)后,会出现很多星光以不同的速度向四方飞散而去,当粒子飞出窗口后或者超出时间后便会消失。每一次爆炸所出现的粒子全部消失后,便会重新出现绽放(爆炸)的画面,以产生不断绽放星光的效果。
2.“星光”粒子的构造
首先我们来看一下这次如何用结构体来构造出星光粒子:
[cpp]
struct flystar
{
int x; //星光所在的x坐标
int y; //星光所在的y坐标
int vx; //星光x方向的速度
int vy; //星光y方向的速度
int lasted; //星光存在的时间
BOOL exist; //星光是否存在
}flystar[50];
struct flystar
{
int x; //星光所在的x坐标
int y; //星光所在的y坐标
int vx; //星光x方向的速度
int vy; //星光y方向的速度
int lasted; //星光存在的时间
BOOL exist; //星光是否存在
}flystar[50];
6个成员分别为,粒子坐标两个值,粒子方向两个值,持续时间lasted,和粒子是否存在的标识exist。
3.核心代码讲解
最重要的当然是我们的MyPaint()绘图函数:
[cpp]
//全局变量声明
HINSTANCE hInst;
HBITMAP bg,star,mask; //用于贴图的三个HBITMAP变量
HDC hdc,mdc,bufdc;
HWND hWnd;
RECT rect;
int i,count; //定义count用于计数
//****自定义绘图函数*********************************
// 1.窗口贴图
// 2.实现星光绽放的效果
void MyPaint(HDC hdc)
{
//创建粒子
if(count == 0) //随机设置爆炸点
{
int x=rand()%rect.right;
int y=rand()%rect.bottom;
for(i=0;i<50;i++) //产生星光粒子
{
flystar[i].x = x;
flystar[i].y = y;
flystar[i].lasted = 0; //设定该粒子存在的时间为零
if(i%2==0) //按粒子编号i来决定粒子在哪个象限运动,且x,y方向的移动速度随机为1—15之间的一个值,由1+rand()%15来完成。
{
flystar[i].vx = -(1+rand()%15);
flystar[i].vy = -(1+rand()%15);
}
if(i%2==1)
{
flystar[i].vx = 1+rand()%15;
flystar[i].vy = 1+rand()%15;
}
if(i%4==2)
{
flystar[i].vx = -(1+rand()%15);
flystar[i].vy = 1+rand()%15;
}
if(i%4==3)
{
flystar[i].vx = 1+rand()%15;
flystar[i].vy = -(1+rand()%15);
}
flystar[i].exist = true; //设定粒子存在
}
count = 50; //50个粒子由for循环设置完成后,我们将粒子数量设为50,代表目前有50颗星光
}
//先在内存dc中贴上背景图片
SelectObject(bufdc,bg);
BitBlt(mdc,0,0,rect.right,rect.bottom,bufdc,0,0,SRCCOPY);
for(i=0;i<50;i++)
{
if(flystar[i].exist) //判断粒子是否还存在,若存在,则根据其坐标(flystar[i].x,flystar[i].y)进行贴图操作
{
SelectObject(bufdc,mask);
BitBlt(mdc,flystar[i].x,flystar[i].y,30,30,bufdc,0,0,SRCAND);
SelectObject(bufdc,star);
BitBlt(mdc,flystar[i].x,flystar[i].y,30,30,bufdc,0,0,SRCPAINT);
//计算下一次贴图的坐标
flystar[i].x+=flystar[i].vx;
flystar[i].y+=flystar[i].vy;
//在每进行一次贴图后,将粒子的存在时间累加1.
flystar[i].lasted++;
//进行条件判断,若某粒子跑出窗口区域一定的范围,则将该粒子设为不存在,且粒子数随之递减
if(flystar[i].x<=-10 || flystar[i].x>rect.right || flystar[i].y<=-10 || flystar[i].y>rect.bottom || flystar[i].lasted>50)
{
&n
补充:软件开发 , Vc ,