看什么看

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)

标签: none

评论已关闭