How to rotate player with accelerometer input?

Hi guys, I’m learning about the accelerometer at the moment and I have noticed that in many accelerometer games (side scrollers shooter) when you tilt the device the “ship” tilts also so it looks like it’s flying up/or down.

How do I make that function for rotation when I tilt the device?

Here’s my code, I’ve tried to set player rotation in the movePlayer function but it doesn’t work, help please…

[code]
display.setStatusBar(display.HiddenStatusBar)
system.setAccelerometerInterval( 50 )

_W = display.contentWidth
_H = display.contentHeight

local bg = display.newImageRect(“images/bg.png”, 480, 320)
bg:setReferencePoint(display.CenterReferencePoint)
bg.x = _W/2
bg.y = _H/2

– My player is a fish.
local player = display.newImageRect(“images/doodle.png”, 128, 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)

local function screenBoundaries (event)

– Left side boundaries
if player.x < 0 + player.width/2 then
player.x = 0 + player.width/2
end

– Right side boundaries
if player.x > display.contentWidth - player.width/2 then
player.x = display.contentWidth - player.width/2
end

– Upper boundaries
if player.y < 0 + player.height/2 then
player.y = 0 + player.height/2
end

– Lower boundaries
if player.y > display.contentHeight - player.height/2 then
player.y = display.contentHeight - player.height/2
end
end

Runtime:addEventListener(“enterFrame”, screenBoundaries)

[/code] [import]uid: 65840 topic_id: 10727 reply_id: 310727[/import]

Hi, I asked this question on Stackoverflow to see if I could get some help there too, I updated my post with my attempt to make a player rotate upon accelerometer value changes.

Like if a fish was swimming up and down with a little angle (25 - 45degrees) or what seems realistic. If anyone feels like showing how it’s done please feel free to post it here or on Stackoverflow.

Thanks guys
Cindy [import]uid: 65840 topic_id: 10727 reply_id: 39233[/import]

I decided to drop my failed attempt here too. I have no errors in the simulator but the fish doesn’t rotate in any way? How do I make this work?

[code]
display.setStatusBar(display.HiddenStatusBar)
system.setAccelerometerInterval( 50 )

_W = display.contentWidth
_H = display.contentHeight

local ceil = math.ceil
local pi = math.pi
local atan2 = math.atan2
local playerRotation
– Put the doodle fish in the center if the screen.
local player = display.newImageRect(“images/doodle.png”, 128, 64)
player:setReferencePoint(display.CenterReferencePoint)
player.x = _W/2
player.y = _H/2

– My rotation function, not sure how to do it right.

local function getPlayerRotationAngle(xGravity, yGravity)
angle = math.atan2(xGravity, yGravity)

angle = angle*(180/pi)

playerRotate = ceil(360 - angle(xGravity, yGravity))

return playerRotate
end

– Set up the Accelerometer values in Landscape

local motionX = 0
local motionY = 0

local function onAccelerate( event )
motionX = 5 * event.yGravity;
motionY = 5 * event.xGravity;

– Should I put the rotation here or down in the movePlayer function?

player.rotation = playerRotate(event.yGravity, event.xGravity);
end

Runtime:addEventListener (“accelerometer”, onAccelerate);

– Make the player move on tilt.

function movePlayer (event)

player.x = player.x + motionX
player.y = player.y + motionY
end

Runtime:addEventListener(“enterFrame”, movePlayer)
[/code] [import]uid: 65840 topic_id: 10727 reply_id: 39234[/import]

the same question ,

I want to make it in my iPhone game (( Lucky_Shark )) , [import]uid: 13061 topic_id: 10727 reply_id: 42825[/import]

@eng.tareqali
How is it going with this, have you found a solution? [import]uid: 65840 topic_id: 10727 reply_id: 116110[/import]

I think I know what’s happening. In your code, here:

[lua] local function onAccelerate( event )
motionX = 5 * event.yGravity;
motionY = 5 * event.xGravity;
player.rotation = playerRotate(event.yGravity, event.xGravity);
end

Runtime:addEventListener (“accelerometer”, onAccelerate);[/lua]

I don’t know if your equation is right, but I think you should do something like this if you want to set the rotation to the equation you get at the end of the getPlayerRotationAngle:

[lua] local function onAccelerate( event )
motionX = 5 * event.yGravity;
motionY = 5 * event.xGravity;

local rotationForPlayer=getPlayerRotationAngle(event.yGravity, event.xGravity) – You have to call the function, and on behalf of the ‘return playerRotate’ line, it will put the rotationForPlayer as the playerRotate value

player.rotation = rotationForPlayer
end[/lua]

See if that works :slight_smile:

I also might venture not to declare ‘angle’ and ‘playerRotate’ as global variables. Use local ones.

binc
[import]uid: 147322 topic_id: 10727 reply_id: 116128[/import]

I haven’t played Lucky shark but I think we are looking for the same thing.

@Binc,

No, that does not rotate the player sprite on accel input.

I just want to enhance the visual aspect by adding a little rotation when the player goes up or down, it just looks a little better and realistic…

Thanks Binc
/Cin [import]uid: 65840 topic_id: 10727 reply_id: 116362[/import]

Hi,

I’ve been working on a piece of code for rotation with the accelerometer for sometime now. It is def possible but very fiddly and I decided it didn’t look good enough to warrant the feature.

Anyway here is my code. It works fine but is sensitive.

Below is a accelerometer runtime listener.

[lua]local function playerMovement(event)
if accelerometerReady and gameIsActive then
local player = player
local pBlock = player.contentWidth/2
local cameraBounds = cameraBounds
local _yG = _yG – A value that is taken from a calibration button at start of game
local _xG = _xG – A value that is taken from a calibration button at start of game
local floor = math.floor
local atan2 = math.atan2
local pi = math.pi
local abs = math.abs

– Set Calibrated X&Y Values (Reversed X&Y Sums due to device being in landscape mode)
local currentYValue = event.xGravity - _xG
local currentXValue = event.yGravity - _yG
currentYValue = (floor(currentYValue * 20))
currentXValue = (floor(currentXValue * 20))

print("X Value: " …currentXValue)
print("Y Value: " …currentYValue)

–Store Current X/Y Pos
local playerX = player.x
local playerY = player.y

–Store New Pos
local newXPos = playerX + currentXValue
local newYPos = playerY + currentYValue

–Calc Rotation
local currentRotation = (floor(atan2(currentYValue , currentXValue) * ( 180 / pi)))-- Take X&Y radian values and convert into degrees
if currentRotation < 0 then currentRotation = 360 + currentRotation end

print("R Value: " …currentRotation)

–Set Rotation
player.rotation = floor(currentRotation)

–Move Player To New Pos If In Bounds
if newXPos < (cameraBounds.xMin+pBlock) then
player.x = (cameraBounds.xMin+pBlock)
elseif newXPos > (cameraBounds.xMax-pBlock) then
player.x = (cameraBounds.xMax-pBlock)
else
player.x = newXPos
end
if newYPos < (cameraBounds.yMin+pBlock) then
player.y = (cameraBounds.yMin+pBlock)
elseif newYPos > (cameraBounds.yMax-pBlock) then
player.y = (cameraBounds.yMax-pBlock)
else
player.y = newYPos
end
end
end[/lua] [import]uid: 26289 topic_id: 10727 reply_id: 116374[/import]

@CELL
Thanks for posting, Are you implementing some sort of accel calibration in your code? I’ve never found anything on how to calibrate accelerometer depending on the angel you’re holding the device.

I haven’t tested the code you posted CELL, however I think it would be enough if the players rotation was limited to a 90° span (player normal position is totally horizontal = 0°) so he can only rotate 45°/-45° from normal position.

[import]uid: 65840 topic_id: 10727 reply_id: 116393[/import]

@cindy.h1986

No problem glad to share.

Yeah thats right. Its actually a really simple process.

  1. Create a calibration screen with a button. Telling the player to hold the device in their desired position then press the button

  2. Make two variables that store the current event.*gravity when button is pressed. Mine are _yG and _xG

So at the top of your file
[lua]local _xG
local _yG[/lua]

So the button code might be something like
[lua]if event.phase == “pressed” then
_xG = event.xGravity
_yG = event.yGravity
end[/lua]

  1. Then negate those values from your current event.*gravity’s in your accelerometer listener
    [lua]local currentYValue = event.xGravity - _xG
    local currentXValue = event.yGravity - _yG[/lua]

Beware! What I have posted is not finished code and my original code needs to be cleaned up as well. It’s late here so let me know if it doesn’t work but I assure you it can.

Tip: Try and avoid doing mathematical calculations in ‘listener functions’ or any function that gets called a lot. If its getting called every frame its having to do those calculations every frame, which is very CPU taxing.

Example
[lua] --Move Player To New Pos If In Bounds
if newXPos < (cameraBounds.xMin+pBlock) then
player.x = (cameraBounds.xMin+pBlock)
elseif newXPos > (cameraBounds.xMax-pBlock) then
player.x = (cameraBounds.xMax-pBlock)
else
player.x = newXPos
end
if newYPos < (cameraBounds.yMin+pBlock) then
player.y = (cameraBounds.yMin+pBlock)
elseif newYPos > (cameraBounds.yMax-pBlock) then
player.y = (cameraBounds.yMax-pBlock)
else
player.y = newYPos
end [/lua]

This is sloppy coding as a lot of these calculations could be done earlier on in the application and then stored in a variable.

So
lua[/lua]
I could take this and make a local variable called cameraMinBounds
[lua]local cameraXMinBounds = (cameraBounds.xMin+pBlock)[/lua]

Then use this in the function
[lua]if newXPos < cameraXMinBounds then[/lua]

It is much faster to grab a number than make a mathematical calculation. I mainly mention this because I see you have made the same mistake :wink:

Let me know if you get it working to a acceptable level

Cheers and good luck [import]uid: 26289 topic_id: 10727 reply_id: 116395[/import]