How to calibrate the accelerometer angle based on how the users is holding the device with Corona SDK?
Hey guys, I just finished my app with Corona SDK and thought I'd try to make my first game.
As my first app was learning about the accelerometer I thought my game should be with that too.
So I placed a little doodle on the screen and got him controlled by the accelerometer in both X and Y direction, the game is in landscape but if I have the device on an angle towards me the doodle slides off the screen in Y direction.
If开发者_如何转开发 I would be laying in bed or slouching on the couch then the game won't be playable.
How do I write a function that compensate this angle?
Here is the code I have for the accelerometer at the moment;
display.setStatusBar(display.HiddenStatusBar)
system.setAccelerometerInterval( 50 )
_W = display.contentWidth
_H = display.contentHeight
local player = display.newImageRect("doodle.png", 64, 64)
player:setReferencePoint(display.CenterReferencePoint)
player.x = _W/2
player.y = _H/2
-- Set up the Accelerometer values in Landscape
local motionX = 0
local motionY = 0
local function onAccelerate( event )
motionX = 10 * event.yGravity;
motionY = 10 * event.xGravity;
end
Runtime:addEventListener ("accelerometer", onAccelerate);
-- Make the player move on tilt.
local function movePlayer (event)
player.x = player.x + motionX;
player.y = player.y - motionY;
end
Runtime:addEventListener("enterFrame", movePlayer))
We faced a similar challenge for ArdentHD.
Basically what you need to do is calibrate for the "still" X, Y and Z values. Once you launch your game, keep reading the accelerometer for a few seconds. During that time you can display a count down or something else to comfort the user.
Calculate the average value for X, Y and Z respectively. These are the values that represent a "still" device.
So when the user holds the device upright, you'll have X = 0, Y = -1 and Z = 0. (With the device on it's back, it would be X = 0, Y = 0, Z = -1) Save those somewhere. e.g:
xOffset = event.xGravity
yOffset = event.yGravity
zOffset = event.zGravity
Now, instead of executing
motionX = 10 * event.yGravity;
motionY = 10 * event.xGravity;
in your movement calculation function, instead execute
motionX = 10 * (event.yGravity - xOffset);
motionY = 10 * (event.xGravity - yOffset);
This cleans out the original position.
Also, be aware that of you want to really turn the device 360°, you will to calculate both your motionX and motionY as a cotangent of xGravity and zGravity as well as yGravity and zGravity. Otherwise the movement will only feel "real" when the device is horizontal (zGravity constant at -1).
精彩评论