簡體   English   中英

Lua / Corona SDK:循環中顯示對象的位置差異

[英]Lua / Corona SDK : Positional difference of display objects in loop

因此,在使用Corona SDK構建移動游戲時,我偶爾會遇到一些問題。 其中一個我似乎沒解決:

當在循環中產生顯示對象時,似乎在一行中的兩個對象之間隨機出現位置差異。

起初,我認為這是由於在實際產生和轉換開始之間執行的大量代碼,但后來我設法在幾行中重現了同樣的問題:

local rectangleLoopTimer;
local counter = 0;
local rectangleArray = {}

local function rectangleLoop()

    counter = counter + 1

    local thisRectangle = display.newRect(1, 1, 216, 400)
    thisRectangle.anchorX = 0

    table.insert(rectangleArray, thisRectangle)

    transition.to(

        thisRectangle,

        {

            time = 5000,
            x = thisRectangle.x + 1080,

            onComplete = function()

                display.remove(thisRectangle)
                table.remove(rectangleArray, counter)

            end

        }

    )

end

rectangleLoopTimer = timer.performWithDelay(985, rectangleLoop, 0)

如果一個人執行此操作,那么我會看到我的意思,那你覺得為什么會這樣呢? 我感謝每一個答案!

問候,尼爾斯

編輯:

這也會產生同樣的問題:

local rectangleLoopTimer;
local counter = 0
local rectangleArray = {}
local thisRectangle

local function rectangleLoop()

    counter = counter + 1

    thisRectangle = display.newRect(1, 1, 216, 400)
    thisRectangle.anchorX = 0
    thisRectangle.lastTime = 0
    thisRectangle.rate = 216
    table.insert(rectangleArray, thisRectangle)
    thisRectangle.lastTime = system.getTimer()

    thisRectangle.enterFrame = function(self, event)

        local curTime = system.getTimer()
        local dt = curTime - self.lastTime
        self.lastTime = curTime
        local dx = self.rate * dt / 1000
        self.x = self.x + dx

    end

    Runtime:addEventListener("enterFrame", thisRectangle)

end

rectangleLoopTimer = timer.performWithDelay(1000, rectangleLoop, 0)

重新編輯:

此代碼也會產生相同的問題,盡管使用幀率獨立動畫。 在增加循環速度時會強調這個問題,如下面的代碼所示:

local loopSpeed =  306
local loopTimerSpeed = 1000
local gapTable = {}
local gapLoopTimer
local frameTime
local gap

--enterFrame for time only

    local function frameTime(event)

        frameTime = system.getTimer()

    end

--enterFrame

    local function enterFrame(self, event)

        local deltaTime = frameTime - self.time
        print(deltaTime/1000)
        self.time = frameTime
        local speed = self.rate * deltaTime / 1000
        self:translate(speed, 0)

    end

--loop speed function

local function setLoopSpeed(factor)

    loopSpeed = loopSpeed * factor
    loopTimerSpeed = loopTimerSpeed / factor

end

--set the loop speed

    setLoopSpeed(3)

--loop to create gaps

local function createGap()

    gap = display.newRect(1, 1, 308, 442)
    gap.time = system.getTimer()
    gap.anchorX = 1
    gap.anchorY = 0

    --animation

        gap.rate = loopSpeed
        gap.enterFrame = enterFrame
        Runtime:addEventListener("enterFrame", gap)

    --fill table for cleaning up

        table.insert(gapTable, gap)

    --cleaning up

        for i = #gapTable, 1, -1 do

            local thisGap = gapTable[i]

            if thisGap.x > display.contentWidth + 500 then

                display.remove(thisGap)
                table.remove(gapTable, i)
                Runtime:removeEventListener("enterFrame", thisGap)

            end

            thisGap = nil

        end

end

Runtime:addEventListener("enterFrame", frameTime)

gapLoopTimer = timer.performWithDelay(

    loopTimerSpeed,
    createGap,
    0

)

如果您不需要進一步參考rects使用下面的代碼

local rand = math.random

local function rectangleLoop() 
    local thisRectangle = display.newRect(1, 1, 216, 400)
    thisRectangle.anchorX = 0
    thisRectangle:setFillColor(rand(), rand(), rand())

    transition.to(thisRectangle, {time=5000,x=thisRectangle.x + 1080, onComplete=display.remove})
end

rectangleLoopTimer = timer.performWithDelay(985, rectangleLoop, 0)

你需要使用表來存儲rects嗎?

轉換是一個非常常見的問題,[對我來說]是Corona SDK中的一個錯誤。 需要注意的重要事項是過渡如何運作。 轉換只不過是一個表,它引用了對象和每個幀應該對它們做什么的信息。 檢索每個幀這樣的對象,並使用當前時間來計算應該應用於對象值的差異,如轉換本身中所指定的。 這基本上意味着如果你要求Corona將一個物體從x = 0移動到x = 100time = 100 每一幀,Corona都會獲取該信息,占用當前時間,並計算對象的x值。

這里的問題是,當前所花費的時間是計算時的當前時間,而不是幀的時間。 這意味着,如果你有很多轉換,那么在一幀內的第一個和最后一個轉換之間可能會有幾毫秒。 這將導致同一幀內的不同位置。

如果Corona需要幀時間[在幀的開頭那么時間]它將使用相同的值來計算所有內容,無論你將從A轉換到B有多少個對象,它們都會出現在同一個地方在所有的框架中。

解決此問題的最簡單方法是在enterFrame手動處理轉換或使用為您執行轉換的庫,例如: AKTween

希望這可以幫助。

編輯:根據您的其他代碼和評論,我認為這應該按照您的意願。 請原諒我的代碼質量,我是從內存中寫的,並沒有在Corona中測試它。

local rectangleLoopTimer;

local allRectangles = display.newGroup()


local lastTime = system.getTimer()

local function enterFrame()

    local curTime = system.getTimer()
    local dt = curTime - lastTime
    lastTime = curTime

    for i = allRectangles.numChildren, 1 do
        local rect = allRectangles[i]
        local dx = rect.rate * dt / 1000
        rect.x = rect.x + dx
    end
end

Runtime:addEventListener("enterFrame", enterFrame)


local function createRectangle()

    local thisRectangle = display.newRect(1, 1, 216, 400)
    thisRectangle.anchorX = 0
    thisRectangle.lastTime = 0
    thisRectangle.rate = 216
    allRectangles:insert(thisRectangle)
end

timer.performWithDelay(1000, createRectangle, 0)

編輯重新編輯后:

你有時間在enterFrame監聽器中設置,但你實際上並不知道什么時候會被調用。 我不會指望在enterFrame階段調用的函數的順序。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM