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

995

被折叠的 条评论
为什么被折叠?



