Moving physics objects with the accelerometer

Jul 18, 2011 at 5:08 PM
Edited Jul 18, 2011 at 5:51 PM

Hey guys, first off Andy great work here. I just started with the physics helper and it's been really fun.

I was wondering if anyone knew a good way to move physics objects with the acceleration. For my test app I simply have a ragdoll user control and a static floor on the main screen. I know I could change the gravity around to move my ragdoll but is there a way to do this without changing the worlds gravity? I've been looking at the threads and so far I came up with this.

So far I have tried the following:

 

void ThreadSageAccelerometerChanged(AccelerometerReadingEventArgs e)
        {
            PhysicsSprite temp = physicsController.PhysicsObjects["ragdoll"] as PhysicsSprite;

            //temp.BodyObject.ApplyForce(new Vector2((temp.Position.X + (float)(e.X * 10)), (temp.Position.Y + (float)(e.Y * 10))));
            temp.BodyObject.ApplyForce(new Vector2((temp.BodyObject.Position.X + (float)(e.X * 1000))), new Vector2((float)(480), (float)(temp.BodyObject.Position.Y)));
        }

 

I got kind of confused with the whole world coordinates and screen coordinates. But basically what I tried to do was apply a force in the x direction to a point on the side but my object does not move at all when I tilt my device.

Thanks,

Mike

Jul 18, 2011 at 11:56 PM

I'm still having trouble moving my object too with left and right buttons.

Jul 19, 2011 at 2:58 AM

Yea I was looking at your thread when I got started but not sure what exactly to do. I'm reading up on the Farseer though and seeing if I can figure it out. It would be helpful though if someone already knows how to do this.

Coordinator
Jul 19, 2011 at 1:50 PM

I've always just changed gravity for the simulation for this effect. But I understand you want to only affect the ragdoll in this case.

A couple of ideas:

- maybe create a separate Island (part of Farseer) and put the ragdoll in it so the gravity affects only the ragdoll.

- maybe create a distance joint to each side of the doll and change the length to pull it either way

 

Jul 19, 2011 at 4:17 PM

Thanks for the reply! I'm having some trouble referencing the distance joint I added in blend though. I'm really confused on what is the correct way to reference a physics object you made in blend and manipulate it in the code behind.

I tried grabbing the joint from my _physicsController by referencing the name I gave it in blend. 

var temp = _physicsController.PhysicsObjects["distance_Right"];

But it didn't have the length property even though I checked it off as a distance joint on blend.

I also tried.

var disRight = _physicsJointMain.JointObjects[0] as DistanceJoint;
disRight.Length = (float)(disRight.Length - e.X * 100);

But as I debugged my _physicsJointMain did not have any objects in it and I couldn't find a way to add a joint to it. I wouldn't have been successfull though as I do not know how to reference the joint I made in blend to put into my _physicsJointMain.

How do I reference the joint I made in blend and access the Length property in the code behind?

Thanks,

Mike

Coordinator
Jul 19, 2011 at 5:51 PM
Edited Jul 19, 2011 at 5:52 PM

Here is a method to find all of the joints between two bodies in the simulation... (note that it is looking for RevoluteJoint's, you may need to tweak as needed)

 

public static List<RevoluteJoint> FindJoint(PhysicsControllerMain physicsController, string body1, string body2)

{

    List<RevoluteJoint> joint = new List<RevoluteJoint>();

 

    foreach (Joint x in physicsController.Simulator.JointList)

    {

        if (x is RevoluteJoint)

        {

            RevoluteJoint rj = x as RevoluteJoint;

            if ((rj.BodyA == physicsController.PhysicsObjects[body1].BodyObject && rj.BodyB == physicsController.PhysicsObjects[body2].BodyObject)

            || (rj.BodyB == physicsController.PhysicsObjects[body1].BodyObject && rj.BodyA == physicsController.PhysicsObjects[body2].BodyObject))

            {

                joint.Add(rj);

 

            }

 

        }

    }

 

 

    return joint;

}

 


Jul 19, 2011 at 9:23 PM

Thanks for the method it was very helpful. I was able to find the joints and alter their lengths. My ragdoll still did not move though. As I debugged I checked that the length value was indeed changing as I moved the accelerometer but the ragdoll stayed still.

My setup:

- A static rectangle at the top of the screen (RecTop)

- An ellipse (the direction joint) positioned on the top of the head of my ragdoll (bodyA - RecTop, bodyB - ragdoll)

Is this setup wrong? I tried moving the joint in different places still no success though.

I need a write a tutorial after I'm able to achieve this...

Jul 24, 2011 at 5:39 AM

I'm trying the island setup now that I have some time. How do I manipulate the islands gravity though?

I understand I can add the object to the island by simply calling

physicsController.Simulator.Island.Add(physicsController.PhysicsObjects["ragdoll"].BodyObject);
But there is no property to manipulate the gravity of that island.

Coordinator
Jul 25, 2011 at 11:41 AM

Hmmm... I thought Islands had gravity exposed, but apparently I was wrong :(

There is an article here: http://www.emanueleferonato.com/2009/07/17/managing-multiple-gravities-with-box2d/

... that explains multiple gravities for Box2D (note that Farseer 3 is based on Box2D so there should be minor differences). Maybe that can be of some help?