Twitter

Simple accelerometer movement with Cocos2d and Chipmunk

Posted: June 15th, 2010 | Author: | Filed under: iPhone Dev | Tags: , , , , | 4 Comments »

We all need a quick and easy way to move a body based on accelerometer movement. This method allows quick execution and testing. In this post I’ll be detailing how to move a cpBody on screen using the accelerometer.

I’m assuming you’ll make all the connections between your sprite and the cpBody and understand how to set up a cocos2D and Chipmunk project. If you need help with this check out Alexandre Gomes’ excellent tutorial “An introduction to game physics with Chipmunk“. Much of the code below is not directly related to the acceleration, while I am not including all the methods required for the class, I like to provide complete methods, so you can see how things will interact.

In this case we’ll just move a body based on the x (left and right) movement.

1) enable accelerometer in the init method and initialize the acceleration at 0.

-(id) init
{
    if( (self=[super init]) ) {
        self.isAccelerometerEnabled = YES;
        accellX = 0; // float defined in header
 
        // setup chipmunk
        [self setupChipmunk];
 
        // setup your cpShapes, cpBodies and CCSprites here
        // I'll be using spriteBody to these
    }
}

2) Setup Chipmunk

- (void) setupChipmunk
{
    // start chipmunk
    cpInitChipmunk();
 
    // create space object
    space = cpSpaceNew();
 
    // define gravity vector - zero gravity here - change the vector to apply gravity
    space->gravity = cpv(0, -0);
 
    // Add some elastic effects to the simulation
    space->elasticIterations = 20;
 
    // Create an update schedule
    [self schedule:@selector(step:)];
}

3) Update the current acceleration when an update is received

- (void) accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration
{
    // set current acceleration to 10x the current acceleration of the device.
    // change 10 to any number that works for your implementation speed.
    accellX = acceleration.x * 10;
}

4) The step function we referred to in #2. This move the cpBody based on the current acceleration as defined in #3. Remember, right now this is x only, I’ll let you make the connections to get y working.

-(void) step: (ccTime) dt
{
    cpSpaceStep(space, dt);
 
    // get new x position based on acceleration
    // spriteBody is a cpBody defined in the header file and setup with a shape and sprite in the init
    float newX = spriteBody->p.x + accellX;
 
    // move the sprite body to the new x position
    spriteBody->p = cpv(newX, spriteBody->p.y);
 
    // call our function for each shape
    cpSpaceHashEach(space->activeShapes, &updateShape, nil);
}

5) Just for completion’s sake, I’ll include the method to update the shapes called in the last line of the previous code. None of this effects the acceleration at all… simply moves the sprite to the position of the shape.

void updateShape(void *ptr, void* unused)
{
    cpShape *shape = (cpShape *)ptr; // the shape
    CCSprite *sprite = shape->data; // the sprite
 
    // set the sprite position to the shapes body position
    [sprite setPosition: shape->body->p];
}

And that’s it, your body should be moving based on the accelerometer input.


  • http://my-addr.com/ CeafWouff

    Many thanks.

  • Dontinahome

    get error on p? class b2Body has no member named p error
    plz help and ty for ur tutorial

  • http://www.lapegna.com Joey Lapegna

    Hi Dontinahome.

    Did you setup your shapes and bodies in the init method?

    If your body is named b2Body, you should have something like this:

    cpBody *b2Body = cpBodyNew(100.0, INFINITY);
    b2Body -> p = cpv(x, y);
    cpSpaceAddBody(space, b2Body);

    Hope this helps. If not feel free to contact me with your full source code, and I can take a look at it for you. My email address is jlapegna at gmail dot com

  • Nani Monish

    What is  & at this line.
    cpSpaceHashEach(space->activeShapes, &updateShape, nil);