开发者

How to calibrate the accelerometer angle based on how the users is holding the device with Corona SDK?

开发者 https://www.devze.com 2023-03-09 20:56 出处:网络
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.

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

0

精彩评论

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