动态地将精灵表添加到电晕中的sequenceData数组

时间:2019-02-26 19:51:26

标签: lua lazy-loading corona

问题:我有一个长时间的基于帧的动画,为此我创建了许多子画面(例如50个子画面,每个子画面10张图像-每个子画面2 MB)。根据下面的示例代码片段(这是在corona文档中建议的),使用代码播放动画之前,需要花费大量时间(和内存)来预加载所有50个Spritesheet,然后才能播放动画:

local function spriteListener( event )
    thisSprite = event.target  -- "event.target" references the sprite

    if ( event.phase == "ended" ) then 
        sequenceNumer = sequenceNumer + 1;

        if (sequenceNumer <=10) then
            thisSprite:setSequence(filenameArray[sequenceNumer])
            thisSprite:play()
        end
    end
end
local spriteWidth = 551
local spriteHeight = 401
local numFrames1 = 15
local startFrame = 1

frameInfoSet1 = {width = spriteWidth , height = spriteHeight, numFrames = numFrames1}

filenameArray = {"001-015","016-030","031-045","046-060","061-075","076-090","091-105","106-120","121-135","136-150"}

fullSequence = 
{
    {name=filenameArray[1], sheet=graphics.newImageSheet("spritesheets/" .. filenameArray[1] .. ".png", frameInfoSet1), start = startFrame, count=numFrames1, time=2250, loopCount=1},
    {name=filenameArray[2], sheet=graphics.newImageSheet("spritesheets/" .. filenameArray[2] .. ".png", frameInfoSet1), start = startFrame, count=numFrames1, time=2250, loopCount=1},
    {name=filenameArray[3], sheet=graphics.newImageSheet("spritesheets/" .. filenameArray[3] .. ".png", frameInfoSet1), start = startFrame, count=numFrames1, time=2250, loopCount=1},
-- more such spritesheets are loaded further...
}

firstSpriteSheet = fullSequence[1]["sheet"]

sequenceNumer = 1

tt = display.newSprite (firstSpriteSheet, fullSequence)
tt.x = display.contentWidth/2 ; tt.y = display.contentHeight/2
tt:addEventListener( "sprite", spriteListener )
tt:play()

但是,我想实现的是该技术的“流式”版本。即,我将只加载50个中的3个Spritesheet,因此需要6 MB才能开始播放动画并继续加载其他Spritesheet,因为已经加载的Spritesheet仍在播放。因此,为了进一步说明,i加载了表1,2,3,并开始播放动画,并且在时间表1之前完成了加载表4,在时间表2之前完成了加载表5,依此类推。

任何建议都值得赞赏!预先感谢。

1 个答案:

答案 0 :(得分:0)

我看到这是一个古老的问题,但是我会根据自己的经验添加一些想法:

这不是一件容易的事,但是有可能

  1. 出发前预装纸

我建议添加一个简单的加载场景,您将在加载时显示进度条。

local filenameArray = ... -- this is from your code
local preloadedSheets = {}

local function enterFrameLoading()
  local nextSheetToLoad = #preloadedSheets + 1
  if (nextSheetToLoad > #filenameArray) then
    Runtime:removeEventListener("enterFrame", enterFrameLoading)
    -- go to game scene if you are using scenes
    return
  end

  preloadedSheets[nextSheetToLoad] = 
        graphics.newImageSheet("spritesheets/" .. filenameArray[nextSheetToLoad] .. ".png", ??)

  updateProgress(nextSheetToLoad) -- this function will update UI, i.e. progress bar, text, etc
end

Runtime:addEventListener("enterFrame", enterFrameLoading)

预加载后,所有工作表都将存储在内存中,因此您应该不会遇到性能问题

  1. 使用多个按需创建的精灵对象

您可以在spriteListener内创建新对象-再次将所有子画面存储在表中,并使用.isVisible = false隐藏旧的子画面

  1. 合并解决方案1和2

您可以仅用3个序列创建精灵对象。然后像上面显示的那样在enterFrame侦听器中预加载其他工作表。

预加载完成后,您想要销毁旧的精灵并以相同的顺序和帧创建新的精灵

如果您需要更多信息,请告诉我