爆炸粒子效果
实现一个简单的粒子爆炸效果,通过粒子的位置、速度、寿命和颜色管理,动态生成和渲染粒子。
这个案例有意思的地方在于对表的使用,这个表并非是事先定义好参数的,而是每次在调用时临时生成的
代码结构概览
exps
:粒子列表,存储所有活跃的粒子对象。cols
:定义粒子颜色的数组,粒子寿命变化时颜色会渐变。_init()
:初始化函数,启动时调用,清理屏幕并初始化粒子列表。_update()
:核心更新函数,每帧调用,处理粒子运动、生命周期及新粒子生成。_draw()
:绘制函数,每帧调用,负责将粒子渲染到屏幕。
代码详细分析
1. 全局变量定义
exps = {} -- 粒子列表,存储所有粒子
cols = {5, 9, 10, 7} -- 颜色列表,粒子颜色根据寿命变化选择
2. 初始化函数 _INIT()
function _init()cls() -- 清除屏幕exps = {} -- 初始化粒子数组为空
end
- 清屏为粒子显示做好准备。
- 重新初始化粒子列表,避免残留数据。
3. 更新函数 _UPDATE()
3.1 粒子遍历与状态更新
for i in all(exps) doi.x += i.spdx -- 更新x位置,根据速度spdxi.y += i.spdy -- 更新y位置,根据速度spdyi.scale -= 0.1 -- 粒子逐渐缩小i.l -= 0.1 -- 寿命递减
- 粒子根据其速度移动。
- 通过缩小和寿命递减模拟粒子逐渐消散。
3.2 颜色动态选择
local idx = flr(i.l) + 1 if idx < 1 then idx = 1 endif idx > #cols then idx = #cols endi.c = cols[idx] -- 根据寿命从颜色列表中取得颜色
- 利用寿命浮点数和颜色数组索引映射,使颜色随寿命变化,达到渐变效果。
3.3 粒子生命周期检测与移除
if i.l <= 0 thendel(exps, i) -- 寿命结束,删除该粒子end
3.4 新粒子生成(按钮触发)
if btnp(4) thenlocal xp = rnd(128) -- 随机生成爆炸中心x坐标local yp = rnd(128) -- 随机生成爆炸中心y坐标for i=0,20 doadd(exps, {x = xp,y = yp,spdx = 1 - rnd(2), -- x方向速度,随机[-1,1)spdy = 1 - rnd(2), -- y方向速度,随机[-1,1)scale = 2 + rnd(5), -- 大小,随机[2,7)l = 5, -- 寿命,初始为5c = cols[#cols] -- 初始颜色为cols数组最后一个颜色})end
end
- 当玩家按下按钮4时,随机位置生成21个新粒子,模拟爆炸效果。
- 每个粒子速度和大小都随机,增加视觉多样性。
4. 绘制函数 _DRAW()
function _draw()cls() -- 清屏for i in all(exps) docircfill(i.x, i.y, i.scale, i.c) -- 用填充圆绘制每个粒子end
end
- 每帧先清除屏幕,再用粒子数据绘制所有粒子。
- circfill根据粒子位置、大小和颜色渲染,呈现粒子效果。
总结
- 粒子系统核心思想:大量粒子独立更新,模拟复杂视觉效果。
- 生命周期管理:粒子逐步消失并自动删除,节省资源。
- 颜色渐变效果:利用寿命映射到离散颜色数组,实现颜色动态变化。
- 事件触发生成:按钮触发新粒子生成,增强交互性和动态性。
- 渲染循环遍历:使用for循环更新和绘制所有粒子,保证每个粒子都呈现。
完整代码
exps = {}
cols = {5, 9, 10, 7}function _init()cls()exps = {}
endfunction _update()for i in all(exps) doi.x += i.spdxi.y += i.spdyi.scale -= 0.1i.l -= 0.1local idx = flr(i.l) + 1 if idx < 1 then idx = 1 endif idx > #cols then idx = #cols endi.c = cols[idx]if i.l <= 0 thendel(exps, i)endendif btnp(4) thenlocal xp = rnd(128)local yp = rnd(128)for i=0,20 doadd(exps, {x = xp,y = yp,spdx = 1 - rnd(2),spdy = 1 - rnd(2),scale = 2 + rnd(5),l = 5,c = cols[#cols] })endend
endfunction _draw()cls()for i in all(exps) docircfill(i.x, i.y, i.scale, i.c)end
end