开发者

Corona SDK - frame-by-frame animation and accelerometer problem

we are doing a game with moving objects around frame-by-frame and also using accelerometer.

We have hooked on two events - about drawing the frame and for th开发者_StackOverflow中文版e acc.

The problem is, after we receive the acc event, we immediately put the x value in a variable.

Then we use this variable to move an object on the screen, but there is CONSIDERABLE slow down. ( I turn the phone, and after a second the object is moving properly, but a second is just way too much for a game, I expect immediate response).

What am I doing wrong? Is there another workaround to do this, or can I give some params to the accelerometer?

Unfortunately this is a serious problem - a real blocker. If this does not work, I have to find another solution (not Corona) for implementing the game.

Thanks in advance!!! Danail

PS: here's some source:

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 )


I don't know anything about Corona development, but there are some general issues. First what is gravity containing? Just the gravity vector or total acceleration = gravity + userAcceleration? You will need to get userAcceleration = totalAcceleration - gravity or some member from event providing it directly, otherwise there is no chance.

If you have user acceleration, you need to integrate twice to get the position. See Equations of motion. In your case the code will be like:

velocity = userAcceleration * elapsedTime

position = 0.5*userAcceleration * elapsedTime^2

In general precise position detection by accelerometer and gyroscope is still an unresolved problem, so don't expect precise results. But if you are interested in just evaluating that there is an impulse in one direction, it might work. See for example Getting displacement from accelerometer data with Core Motion


The guys at Ansca's forum just got this out:

system.setAccelerometerInterval( 50 )

This didn't quite actually did the trick, but

system.setAccelerometerInterval( 100 ) -- warning - battery drainer!!

did it :)


I open-sourced my first Corona SDK-made game (which actually did really well) which uses Tilting in the same manner you describe (the more the tilt, the faster the movement and vice-versa).

It's called 'Tilt Monster' and you can download it here: http://developer.anscamobile.com/code/tilt-monster


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

-- Accelerator is not supported on Simulator

if isSimulator then -- Please display an Alert Box end

-- Text parameters local labelx = 50 local x = 220 local y = 95 local fontSize = 24

local frameUpdate = false

local xglabel = display.newText( "gravity 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( "gravity 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( "gravity 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( "instant 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( "instant 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( "instant 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)

-- Create a circle that moves with Accelerator events

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 ) -- blue

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()

local function 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

end

local function onAccelerate( event )

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

end

local function onFrame() frameUpdate = true end

-- Add runtime listeners Runtime:addEventListener ("accelerometer", onAccelerate); Runtime:addEventListener ("enterFrame", onFrame);

I hope, this code will help you.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜