#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;iparticals);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