Painter/flash_star

184 lines
4.9 KiB
Plaintext
Raw Permalink Normal View History

2024-05-31 15:46:28 +08:00
#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));
}