184 lines
4.9 KiB
Plaintext
184 lines
4.9 KiB
Plaintext
#include "PX_Firework.h"
|
|
%定义烟花的各类属性
|
|
typedef enum
|
|
{
|
|
PX_FIREWORK_STATE_RAISING,
|
|
PX_FIREWORK_STATE_BLOOMING,
|
|
}PX_FIREWORK_STATE;
|
|
%构造结构体来表达目标的物理属性
|
|
typedef struct
|
|
{
|
|
px_point array[32];
|
|
unsigned int delay;
|
|
float size;
|
|
float vx, vy;
|
|
px_color clr;
|
|
}PX_Firework_paritcal;
|
|
%将物理结构和状态绑入一个对象
|
|
typedef struct
|
|
{
|
|
PX_Firework_paritcal particals[96];
|
|
PX_FIREWORK_STATE state;
|
|
unsigned int elapsed;
|
|
}PX_Firework;
|
|
|
|
%利用逐帧更新实现烟花动画
|
|
void PX_FireworkParticalUpdate(PX_Firework_paritcal* pdesc, unsigned int elapsed)
|
|
{
|
|
%烟花持续时间
|
|
int i;
|
|
unsigned int update_atom;
|
|
if (elapsed>1000)
|
|
{
|
|
elapsed = 1000;
|
|
}
|
|
while (elapsed)
|
|
{
|
|
if (elapsed>10)
|
|
{
|
|
update_atom = 10;
|
|
elapsed -= 10;
|
|
}
|
|
else
|
|
{
|
|
update_atom = elapsed;
|
|
elapsed = 0;
|
|
}
|
|
%运动轨迹
|
|
pdesc->array[0].x += pdesc->vx * update_atom / 1000;
|
|
pdesc->array[0].y += pdesc->vy * update_atom / 1000;
|
|
|
|
pdesc->vx -= pdesc->vx * 0.9f * update_atom / 1000;
|
|
pdesc->vy -= pdesc->vy * 0.9f * update_atom / 1000;
|
|
|
|
pdesc->delay += update_atom;
|
|
|
|
%烟花并非一个球体,是一个球体的阵列。
|
|
while (pdesc->delay > 20)
|
|
{
|
|
pdesc->delay -= 20;
|
|
for (i = PX_COUNTOF(pdesc->array) - 1; i > 0; i--)
|
|
{
|
|
pdesc->array[i] = pdesc->array[i - 1];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
%变色效果
|
|
void PX_FireworkParticalRender(PX_Firework_paritcal* pdesc, px_surface * psurface, px_bool bb,unsigned int elapsed)
|
|
{
|
|
int i;
|
|
float scale;
|
|
px_color color;
|
|
|
|
for (i = PX_COUNTOF(pdesc->array) - 1; i >= 0; i--)
|
|
{
|
|
color = pdesc->clr;
|
|
if (bb)
|
|
{
|
|
if (elapsed > 3000)
|
|
{
|
|
elapsed = 3000;
|
|
}
|
|
color._argb.a = (px_uchar)((3000 - elapsed) / 3000.f * 255);
|
|
scale = (PX_COUNTOF(pdesc->array) - i) * (0.5f + elapsed / 2000.f) / PX_COUNTOF(pdesc->array);
|
|
}
|
|
else
|
|
{
|
|
scale = (PX_COUNTOF(pdesc->array) - i) *1.0f/ PX_COUNTOF(pdesc->array);
|
|
}
|
|
color._argb.a = (px_uchar)(color._argb.a*scale);
|
|
PX_GeoDrawSolidCircle(psurface, (int)pdesc->array[i].x, (int)pdesc->array[i].y, (int)(pdesc->size * scale), color);
|
|
}
|
|
}
|
|
%绽放的过程
|
|
void PX_FireworkRender(px_surface* psurface, PX_Object* pObject, unsigned int elapsed)
|
|
{
|
|
PX_Firework* pdesc = PX_ObjectGetDesc(PX_Firework, pObject);
|
|
pdesc->elapsed += elapsed;
|
|
if (pdesc->state==PX_FIREWORK_STATE_RAISING)
|
|
{
|
|
PX_FireworkParticalUpdate(pdesc->particals, elapsed);
|
|
PX_FireworkParticalRender(pdesc->particals, psurface,0,pdesc->elapsed);
|
|
|
|
if (pdesc->elapsed>=1200)
|
|
{
|
|
int i;
|
|
int j;
|
|
px_color clr;
|
|
pdesc->elapsed = 0;
|
|
pdesc->state = PX_FIREWORK_STATE_BLOOMING;
|
|
|
|
for (i = 0; i < PX_COUNTOF(pdesc->particals); i++)
|
|
{
|
|
for (j = 0; j < PX_COUNTOF(pdesc->particals->array); j++)
|
|
{
|
|
pdesc->particals[i].array[j].x = pdesc->particals[0].array[0].x;
|
|
pdesc->particals[i].array[j].y = pdesc->particals[0].array[0].y;
|
|
}
|
|
}
|
|
clr = PX_COLOR(255, 128 + (PX_rand() % 128), 128 + (PX_rand() % 128), 128 + (PX_rand() % 128));
|
|
for (i=0;i<32;i++)
|
|
{
|
|
|
|
pdesc->particals[i].vx = 300 * PX_sin_angle(360 * i / 32.f);
|
|
pdesc->particals[i].vy = 300 * PX_cos_angle(360 * i / 32.f);
|
|
pdesc->particals[i].clr = clr;
|
|
pdesc->particals[i].size = 8;
|
|
}
|
|
%动态变色
|
|
clr = PX_COLOR(255, 128 + (PX_rand() % 128), 128 + (PX_rand() % 128), 128 + (PX_rand() % 128));
|
|
for (i = 32; i < 64; i++)
|
|
{
|
|
pdesc->particals[i].vx = 200 * PX_sin_angle(360 * (i - 32) / 32.f);
|
|
pdesc->particals[i].vy = 200 * PX_cos_angle(360 * (i - 32) / 32.f);
|
|
pdesc->particals[i].clr = clr;
|
|
pdesc->particals[i].size = 6;
|
|
}
|
|
|
|
clr = PX_COLOR(255, 128 + (PX_rand() % 128), 128 + (PX_rand() % 128), 128 + (PX_rand() % 128));
|
|
for (i = 64; i < 96; i++)
|
|
{
|
|
pdesc->particals[i].vx = 100 * PX_sin_angle(360 * (i - 64) / 32.f);
|
|
pdesc->particals[i].vy = 100 * PX_cos_angle(360 * (i - 64) / 32.f);
|
|
pdesc->particals[i].clr = clr;
|
|
pdesc->particals[i].size = 3;
|
|
}
|
|
}
|
|
|
|
}
|
|
else if (pdesc->state == PX_FIREWORK_STATE_BLOOMING)
|
|
{
|
|
int i;
|
|
for (i=0;i<PX_COUNTOF(pdesc->particals);i++)
|
|
{
|
|
PX_FireworkParticalUpdate(pdesc->particals+i, elapsed);
|
|
PX_FireworkParticalRender(pdesc->particals+i, psurface,1, pdesc->elapsed);
|
|
}
|
|
if (pdesc->elapsed>3000)
|
|
{
|
|
PX_ObjectDelayDelete(pObject);
|
|
}
|
|
}
|
|
}
|
|
|
|
%创建烟花实体
|
|
PX_Object* PX_FireworkCreate(px_memorypool* mp, PX_Object* Parent, float x, float y)
|
|
{
|
|
int i;
|
|
PX_Firework desc;
|
|
PX_memset(&desc, 0, sizeof(desc));
|
|
desc.state = PX_FIREWORK_STATE_RAISING;
|
|
desc.elapsed = 0;
|
|
for (i=0;i<PX_COUNTOF(desc.particals[0].array);i++)
|
|
{
|
|
desc.particals[0].array[i].x = x;
|
|
desc.particals[0].array[i].y = y;
|
|
}
|
|
desc.particals[0].vx = 0;
|
|
desc.particals[0].vy = -400;
|
|
desc.particals[0].size = 6;
|
|
desc.particals[0].clr = PX_COLOR(255, 128 + (PX_rand() % 128), 128 + (PX_rand() % 128), 128 + (PX_rand() % 128));
|
|
%返回函数,生成烟花,程序结束
|
|
return PX_ObjectCreateEx(mp, Parent, x, y, 0, 0, 0, 0, 0, 0, PX_FireworkRender, 0, &desc, sizeof(desc));
|
|
} |