因此,在使用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)
如果有人执行此操作,那么我会看到我的意思,那么您认为为什么会这样?我很感激每一个答案!
问候,Nils
编辑:
这也会产生同样的问题:
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)
RE-编辑:
此代码也会产生相同的问题,尽管使用帧率独立动画。在增加循环速度时会强调这个问题,如下面的代码所示:
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
)
答案 0 :(得分: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?
答案 1 :(得分:0)
这是转换的一个非常常见的问题,[对我来说]是Corona SDK中的一个错误。
需要注意的重要事项是过渡如何运作。
转换只不过是一个表,它引用了对象和每个帧应该对它们做什么的信息。
检索每个帧这样的对象,并使用当前时间来计算应该应用于对象值的差异,如转换本身中所指定的。
这基本上意味着,如果您要求Corona将对象从x = 0
移动到x = 100
中的time = 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
阶段调用的函数的顺序。