13
votes

In my cocos2d game, I have my player sprite and I want to have him move in the direction I tilt my iPhone. I can deal with that, the hardest bit which I can't work out is:

How do I make my sprite rotate to point in the direction I am tilting? This is represented very well in the 'Tilt to Live' game on the app store. I want controls just like that.

My sprite(for those unfamiliar with cocos2d) does have a rotation value if that helps.

Thanks.

1

1 Answers

12
votes

If you don't like the above, here's a simpler way to get a reasonable result!

Hold the iPad in front of you, let LR be the left / right tilt, TA the towards you / away from you tilt. So LR runs from -90 to 90, TA from -90 to 90. (TA negative is leaning towards your belly.)

Display both those numbers on your screen, and move the device around, so you are certain you have that right to begin with. You won't be able to do anything until that is working.

The solutionAngle will be like a clock hand, clockwise, with 12 distant from you.

Go through this decision chain:

If both LR and TA is zero, the machine is flat. Act appropriately.

If LR is flat (0), the answer is either 0 or 180, depending on the sign of TA.

If TA is flat (0), the answer is either 90 or 270, depending on the sign of LR.

Otherwise:

adjustmentAngle = arctan( sin(TA) / sin(LR) )

// (NB, that should run from -90 to +90)

if ( LR > 0 ) finalResult = 90 - adjustmentAngle

if ( LR < 0 ), finalResult = 270 + adjustmentAngle

I think that will do it! Hope it helps!

IMO...... be sure to smooth the result over time, for a good feel.

.

setting the angle...

"the only thing I am unsure of currently (concerning your own idea) is how do I apply it to my player? Do I merely make the player rotation value equal to the adjustmentAngle?" .. hi Josh, yes simply set the rotation to the final angle you calculate using the above! Fortunately it's that simple.

If you ever have to convert back/fore between degrees and radians, just paste in these lines of code that everyone uses:

#include <math.h>
static inline float degreestoradians (double degrees) {return degrees * M_PI/180;}
static inline float radianstodegrees (double degrees) {return degrees * 180/M_PI;}

.

where are the axes?...

PS, here's the incredibly handy diagram you may want to bookmark:

http://developer.apple.com/library/ios/#documentation/uikit/reference/UIAcceleration_Class/Reference/UIAcceleration.html

.

converting from accelerometer to angles...

"the accelerometer doesn't provide the raw data in angles. How do get from the raw data"

Quite right, I forgot to mention it sorry. This is an everyday problem...

distanceFactor = square root of (x^2 + y^2 + z^2)
angle X axis = acos ( x / distanceFactor )
angle y axis = acos ( y / distanceFactor )
angle z axis = acos ( z / distanceFactor) )

You must TEST this by writing the three angles on the screen and then moving it around, in other words "physically unit test" that section you write, before you proceed!

here is one of many answers from SO: UIAccelerationValue angle

BTW as you can probably see, you can get a rough result by taking the ratio of simply the raw x by raw y value, rather than the ratio of the two sines, in the 'adjustmentAngle' expression ... but anyway don't worry about that for now.

And finally!

IMPORTANT Readers should note that the amazing new Core Motion system, handles a lot of this for you, depending on your needs. Check it out!!!!!

Hope it helps!