爆炸粒子效果

实现一个简单的粒子爆炸效果,通过粒子的位置、速度、寿命和颜色管理,动态生成和渲染粒子。

这个案例有意思的地方在于对表的使用,这个表并非是事先定义好参数的,而是每次在调用时临时生成的
在这里插入图片描述


代码结构概览

  • 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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值