Corona SDK - 逐帧动画和加速度计问题

3
我们正在制作一个涉及移动对象和使用加速度计的游戏。
我们钩入了两个事件-关于绘制帧和加速度计。
问题是,在接收到加速度事件后,我们立即将x值放入变量中。
然后我们使用这个变量来在屏幕上移动一个对象,但是会有相当大的减速。(我转动手机,一秒钟后物体才能正确移动,但是一秒钟对于游戏来说太长了,我期望立即响应)。
我做错了什么?还有其他解决方法吗?或者我可以给加速度计提供一些参数吗?
不幸的是,这是一个严重的问题-真正的阻碍。如果这样行不通,我必须找到另一种解决方案(不是Corona)来实现游戏。
提前感谢!!! Danail
PS:这里是一些源代码:
local lastXGravity = 0

local function move(event) 
        eventTime=event.time
        elapsedTime = eventTime - lastDrawTime
        lastDrawTime = eventTime

        xSpeed = lastXGravity
        local xMoved = xSpeed * elapsedTime
        object.x= object.x + xMoved
end

function acc(event)   
        lastXGravity = event.xGravity
end

Runtime:addEventListener("accelerometer", acc)
Runtime:addEventListener( "enterFrame", move )

你需要展示你的事件处理程序和对象移动的代码。目前没有明显的原因可以解释你所遇到的延迟。只有代码才能告诉我们发生了什么事情... - JeffK
当然,非常抱歉!我添加了一个微小的片段,让你一睹为快。 - Danail
4个回答

1
Ansca论坛上的人刚发布了这个:
system.setAccelerometerInterval( 50 )

这个并没有完全解决问题,但是

system.setAccelerometerInterval( 100 ) -- 警告 - 会耗电!!

成功了 :)


1

我对Corona开发一无所知,但有一些通用问题。首先,重力包含什么?只有重力向量还是总加速度=重力+用户加速度?你需要获取userAcceleration = totalAcceleration - gravity或者从提供它的事件中直接获取某个成员,否则就没有机会。

如果你有用户加速度,你需要进行两次积分才能得到位置。参见运动方程。在你的情况下,代码将如下:

velocity = userAcceleration * elapsedTime

position = 0.5*userAcceleration * elapsedTime^2

一般来说,通过加速度计和陀螺仪进行精确位置检测仍然是一个未解决的问题,因此不要期望精确的结果。但如果你只是想评估一个方向上是否有冲量,这可能有效。例如,参见使用Core Motion从加速度计数据获取位移


我只需要完成以下任务:角度转动得越大,物体的速度就越快。不需要将加速度叠加到速度上,这是另一个任务。我不在尝试位置检测,那是一个高级问题。 - Danail

0

local isSimulator = "simulator" == system.getInfo("environment")

-- 模拟器不支持加速度计

if isSimulator then -- 请显示警告框 end

-- 文本参数 local labelx = 50 local x = 220 local y = 95 local fontSize = 24

local frameUpdate = false

local xglabel = display.newText("重力x = ", labelx, y, native.systemFont, fontSize) xglabel:setTextColor(255, 255, 255) local xg = display.newText("0.0", x, y, native.systemFont, fontSize) xg:setTextColor(255, 255, 255) y = y + 25 local yglabel = display.newText("重力y = ", labelx, y, native.systemFont, fontSize) local yg = display.newText("0.0", x, y, native.systemFont, fontSize) yglabel:setTextColor(255, 255, 255) yg:setTextColor(255, 255, 255) y = y + 25 local zglabel = display.newText("重力z = ", labelx, y, native.systemFont, fontSize) local zg = display.newText("0.0", x, y, native.systemFont, fontSize) zglabel:setTextColor(255, 255, 255) zg:setTextColor(255, 255, 255) y = y + 50 local xilabel = display.newText("瞬时x = ", labelx, y, native.systemFont, fontSize) local xi = display.newText("0.0", x, y, native.systemFont, fontSize) xilabel:setTextColor(255, 255, 255) xi:setTextColor(255, 255, 255) y = y + 25 local yilabel = display.newText("瞬时y = ", labelx, y, native.systemFont, fontSize) local yi = display.newText("0.0", x, y, native.systemFont, fontSize) yilabel:setTextColor(255, 255, 255) yi:setTextColor(255, 255, 255) y = y + 25 local zilabel = display.newText("瞬时z = ", labelx, y, native.systemFont, fontSize) local zi = display.newText("0.0", x, y, native.systemFont, fontSize) zilabel:setTextColor(255, 255, 255) zi:setTextColor(255, 255, 255)

-- 创建一个随加速器事件移动的圆形

local centerX = display.contentWidth / 2 local centerY = display.contentHeight / 2

Circle = display.newCircle(0, 0, 20) Circle.x = centerX Circle.y = centerY Circle:setFillColor( 0, 0, 255 ) -- 蓝色

local textMessage = function( str, location, scrTime, size, color, font )

local x, t

size = tonumber(size) or 24
color = color or {255, 255, 255}
font = font or "Helvetica"

if "string" == type(location) then
    if "Top" == location then
        x = display.contentHeight/4
    elseif "Bottom" == location then
        x = (display.contentHeight/4)*3
    else
        -- Assume middle location
        x = display.contentHeight/2
    end
else
    -- Assume it's a number -- default to Middle if not
    x = tonumber(location) or display.contentHeight/2
end

scrTime = (tonumber(scrTime) or 3) * 1000       -- default to 3 seconds (3000) if no time given

t = display.newText(str, 0, 0, font, size ) 
t.x = display.contentWidth/2
t.y = x
t:setTextColor( color[1], color[2], color[3] )

-- Time of 0 = keeps on screen forever (unless removed by calling routine)

if scrTime ~= 0 then

    -- Function called after screen delay to fade out and remove text message object
    local textMsgTimerEnd = function()
        transition.to( t, {time = 500, alpha = 0}, 
            function() t.removeSelf() end )
    end

    -- Keep the message on the screen for the specified time delay
    timer.performWithDelay( scrTime, textMsgTimerEnd )
end

return t        -- return our text object in case it's needed

end -- textMessage()

本地函数 xyzFormat( obj, value)

obj.text = string.format( "%1.3f", value )

-- Exit if not time to update text color
if not frameUpdate then return end

if value < 0.0 then
    -- Only update the text color if the value has changed
    if obj.positive ~= false then 
        obj:setTextColor( 255, 0, 0 )       -- red if negative
        obj.positive = false
        print("[---]")
    end
else
    if obj.positive ~= true then 
        obj:setTextColor( 255, 255, 255)        -- white if postive
        obj.positive = true
        print("+++")
    end
end

结束

本地函数 onAccelerate(事件)

xyzFormat( xg, event.xGravity)
xyzFormat( yg, event.yGravity)
xyzFormat( zg, event.zGravity)
xyzFormat( xi, event.xInstant)
xyzFormat( yi, event.yInstant)  
xyzFormat( zi, event.zInstant)  

frameUpdate = false     -- update done 

-- Move our object based on the accelerator values

Circle.x = centerX + (centerX * event.xGravity)
Circle.y = centerY + (centerY * event.yGravity * -1)

-- Display message and sound beep if Shake'n

if event.isShake == true then
    -- str, location, scrTime, size, color, font
    textMessage( "Shake!", 400, 3, 52, {255, 255, 0} )
end

结束

local function onFrame() frameUpdate = true end

-- 添加运行时监听器 Runtime:addEventListener ("accelerometer", onAccelerate); Runtime:addEventListener ("enterFrame", onFrame);

希望这段代码能够帮到你。


0

我开源了我的第一个使用Corona SDK制作的游戏(实际上做得非常好),它使用了你描述的倾斜方式(倾斜越多,移动速度越快,反之亦然)。

它叫做“Tilt Monster”,你可以在这里下载: http://developer.anscamobile.com/code/tilt-monster


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接