taptap制造png序列动画相关代码(性能问题自行解决)
03/15136 浏览开发心得
-- ============================================================================
-- NanoVG 画布项目 - 帧序列动画播放
-- 设计分辨率: 750 x 1334 (竖版)
-- 分辨率模式: A(设计分辨率)
-- ============================================================================
-- ============================================================================
-- 1. 全局变量
-- ============================================================================
local physW, physH
local dpr
local logicalW, logicalH
-- 设计分辨率
local designW, designH = 750, 1334
-- 布局变量
local scale
local screenDesignW, screenDesignH
local designOffsetX, designOffsetY
-- NanoVG
local vg = nil
local fontNormal
-- 帧动画
local FRAME_COUNT = 35
local frameImages = {} -- NanoVG 图片句柄
local frameW, frameH = 0, 0 -- 帧图片尺寸
local currentFrame = 1
local frameTimer = 0
local FPS = 24 -- 播放帧率
-- ============================================================================
-- 2. 布局计算
-- ============================================================================
local function RecalcLayout()
physW, physH = graphics:GetWidth(), graphics:GetHeight()
dpr = graphics:GetDPR()
logicalW, logicalH = physW / dpr, physH / dpr
scale = math.min(logicalW / designW, logicalH / designH)
screenDesignW = logicalW / scale
screenDesignH = logicalH / scale
designOffsetX = (screenDesignW - designW) / 2
designOffsetY = (screenDesignH - designH) / 2
end
-- ============================================================================
-- 3. 加载帧序列
-- ============================================================================
local function LoadFrames()
for i = 0, FRAME_COUNT - 1 do
local filename = string.format("image/skill_100004_tx-animation_%02d.png", i)
local handle = nvgCreateImage(vg, filename, 0)
if handle and handle > 0 then
frameImages[i + 1] = handle
-- 取第一帧的尺寸
if i == 0 then
frameW, frameH = nvgImageSize(vg, handle)
print(string.format("帧尺寸: %dx%d", frameW, frameH))
end
else
print("加载失败: " .. filename)
end
end
print(string.format("已加载 %d/%d 帧", #frameImages, FRAME_COUNT))
end
-- ============================================================================
-- 4. 生命周期
-- ============================================================================
function Start()
-- 初始化 NanoVG
vg = nvgCreate(1) -- 1 = NVG_ANTIALIAS
fontNormal = nvgCreateFont(vg, "sans", "Fonts/MiSans-Regular.ttf")
-- 计算布局
RecalcLayout()
-- 加载帧序列
LoadFrames()
-- 订阅事件
SubscribeToEvent("NanoVGRender", "HandleNanoVGRender")
SubscribeToEvent("Update", "HandleUpdate")
SubscribeToEvent("ScreenMode", "HandleScreenMode")
print("=== 画布已启动: " .. designW .. "x" .. designH .. " ===")
end
-- ============================================================================
-- 5. 更新逻辑
-- ============================================================================
---@param eventType string
---@param eventData UpdateEventData
function HandleUpdate(eventType, eventData)
local dt = eventData["TimeStep"]:GetFloat()
-- 帧计时
frameTimer = frameTimer + dt
local interval = 1.0 / FPS
if frameTimer >= interval then
frameTimer = frameTimer - interval
currentFrame = currentFrame + 1
if currentFrame > #frameImages then
currentFrame = 1 -- 循环播放
end
end
end
-- ============================================================================
-- 6. 渲染
-- ============================================================================
function HandleNanoVGRender()
nvgBeginFrame(vg, logicalW, logicalH, dpr)
nvgScale(vg, scale, scale)
-- 屏幕空间:填满整个屏幕(灰色)
nvgBeginPath(vg)
nvgRect(vg, 0, 0, screenDesignW, screenDesignH)
nvgFillColor(vg, nvgRGBA(128, 128, 128, 255))
nvgFill(vg)
-- 进入设计空间 (750 x 1334)
nvgTranslate(vg, designOffsetX, designOffsetY)
-- 绘制当前帧(居中显示)
local imgHandle = frameImages[currentFrame]
if imgHandle then
local drawX = (designW - frameW) / 2
local drawY = (designH - frameH) / 2
local paint = nvgImagePattern(vg, drawX, drawY, frameW, frameH, 0, imgHandle, 1)
nvgBeginPath(vg)
nvgRect(vg, drawX, drawY, frameW, frameH)
nvgFillPaint(vg, paint)
nvgFill(vg)
end
nvgEndFrame(vg)
end
function HandleScreenMode()
RecalcLayout()
end



