粒子撞击效果
看什么看
import "android.graphics.*"
layout = {
FrameLayout,
layout_width="fill",
layout_height="fill",
{
View,
id="dview",
layout_width="fill",
layout_height="fill",
},
{
CardView,
id="targetCard",
layout_width="300dp",
layout_height="150dp",
layout_gravity="center",
cardBackgroundColor=0xFF333333,
cardElevation="8dp",
radius="15dp",
},
}
activity.setContentView(loadlayout(layout))
-- 物理常量与容器
local rains = {} -- 下落中的雨滴
local splashes = {} -- 飞溅中的粒子
local GRAVITY = 1.5 -- 重力加速度
local MAX_RAIN = 150 -- 最大雨滴密度
-- 初始化一个雨滴
function createRain(w)
return {
x = math.random(0, w),
y = math.random(-500, 0),
speed = math.random(15, 30),--雨滴速度
len = math.random(50, 100),--雨丝长度
alpha = math.random(100, 200)--雨丝透明的
}
end
-- 初始化飞溅粒子
function createSplash(x, y)
for i=1, 5 do
table.insert(splashes, {
x = x,
y = y,
-- 使用整数随机后再除法,获取带小数的速度
vx = math.random(-60, 60) / 10, -- 相当于 -6.0 到 6.0
vy = math.random(-120, -40) / 10, -- 相当于 -12.0 到 -4.0
life = 1.0,
decay = math.random(50, 100) / 1000 -- 修复后的行:0.05 到 0.1
})
end
end
-- 创建 LuaDrawable
local drawable = LuaDrawable(function(canvas, paint, view)
paint.setAntiAlias(true)
local w = canvas.getWidth()
local h = canvas.getHeight()
-- 获取 CardView 在屏幕上的区域用于碰撞检测
local cardLoc = int[2]
targetCard.getLocationOnScreen(cardLoc)
local viewLoc = int[2]
dview.getLocationOnScreen(viewLoc)
-- 计算相对坐标
local relX = cardLoc[0] - viewLoc[0]
local relY = cardLoc[1] - viewLoc[1]
local cardRect = Rect(relX, relY, relX + targetCard.getWidth(), relY + targetCard.getHeight())
-- 绘制背景
canvas.drawColor(0xFF111111)
-- 1. 处理雨滴逻辑
if #rains < MAX_RAIN then
table.insert(rains, createRain(w))
end
paint.setStrokeWidth(5)--雨丝粗细
for i=#rains, 1, -1 do
local r = rains[i]
r.y = r.y + r.speed
-- 碰撞检测:判断是否碰到 CardView 顶部
local hitCard = r.x > cardRect.left and r.x < cardRect.right and r.y >= cardRect.top and r.y <= cardRect.top + r.speed
if hitCard or r.y > h then
if hitCard then createSplash(r.x, cardRect.top) end
table.remove(rains, i) -- 移除雨滴
else
-- 绘制雨丝
paint.setColor(0xFFFFFFFF)
paint.setAlpha(r.alpha)
canvas.drawLine(r.x, r.y, r.x, r.y + r.len, paint)
end
end
-- 2. 处理飞溅粒子逻辑
paint.setStyle(Paint.Style.FILL)
for i=#splashes, 1, -1 do
local s = splashes[i]
s.x = s.x + s.vx
s.y = s.y + s.vy
s.vy = s.vy + GRAVITY -- 受重力影响下落
s.life = s.life - s.decay
if s.life <= 0 then
table.remove(splashes, i)
else
paint.setColor(0xFFFFFFFF)
paint.setAlpha(math.floor(s.life * 255))
canvas.drawCircle(s.x, s.y, 4, paint) -- 绘制水滴点
end
end
-- 强制重绘,形成动画
view.invalidateSelf()
end)
dview.setBackground(drawable)
评论已关闭