Search code examples
objective-ccocos2d-iphoneaccelerometer

Objective-c + cocos2d + accelerometer not working


I'm looking for some help integrating UIAccelerometer into my cocos2d based application. My current design is roughly the following:

1 -- My HelloWorldLayer layer has a private variable -- a class called Manager -- that I will refer to as the data manager. It is the primary data management class that provides information to the UI.

2 -- The HelloWorldLayer's update method calls to the data manager's update method.

3 -- The data manger allocates a new object -- a class called accelerationMeter -- that provides accelerometer data and updates a custom data object that I'm using to track the devices current acceleration.

4 -- The accelerationMeter class sets up the accelerometer like so:

-(id) init
{
    if (self == [super init])
    {
    // the below call is only used if this object extends CCLayer. Right now it extends NSObject
        // self.isAccelerometerEnabled = YES;
        [[UIAccelerometer sharedAccelerometer] setUpdateInterval: 1/60];
        [[UIAccelerometer sharedAccelerometer] setDelegate: self];    

    // my data type to store acceleration information
        self.currVector = [[vector alloc] init];
    }
    return self;
}

// method called when the UIAccelerometer updates
- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration {
    [self currVector].x = acceleration.x;
    [self currVector].y = acceleration.y;
    NSLog([NSString stringWithFormat:@"accelerometer: x = %f, y = %f",self.currVector.x,self.currVector.y]);
}

5 -- After (seemingly exactly) 1 second of successful data collection from the UIAccelerometer, the NSLog line in the "accelerometer" method stoops logging. Therefore, the delegated method stops being called.

6 -- As per request, here is the code I use to integrate the accelerometer:

// source: HelloWorldLayer.mm
// purpose: update scene
-(void) update: (ccTime) dt
{
<snip>
    world->Step(dt, velocityIterations, positionIterations);
    [self updateData];
<snip>
}

// source: HelloWorldLayer.mm
// purpose: update data and use that for the accelerometer display
-(void) updateData
{
    if(dataManager)
    {
        [dataManager update]
        <snip>
        float accelX = [dataManager currentAcceleration].x;
        float accelY = [dataManager currentAcceleration].y;
        <snip>
    }
}


// source: Manager.m (the data manager class)
// called by updater method copied above this
-(void) update
{
    // replace outdated current accleration with the updated current accel
    // right now, the accelMonitor class just returns the value of the current acceleration so I will omit the monitor class
    currentAcceleration = [accelMonitor getCurrent];
    NSLog(@"Manger: Update called");
}

// source accelerationMeter.m
// called by (through an intermediate class) Manager
// I have verified that this method continues to be called after the accelerometer stops working
-(vector*) getCurrentAcceleration
{
    NSLog(@"accelerationMeter: getCurrentAcceleration called");
    return self.currVector;
}

Note I am not using the IOS simulator -- I am reading the logs from the console of my device.

My main questions are the following:
A -- Why could the accelerometer's delegated method stop being executed?
B -- How can I resolve this so that I can make use of the accelerometer data for > 1 second?


Solution

  • Solved!

    I ended up adding the accelerationMeter as a node to the HelloWorldLayer layer. I think that this had something to do with the runloop going out of scope or switching modes, which would therefore stop the accelerometer from collecting data, though I'm unsure.