0

CoreMotion を使用して加速度計のデータを収集し、スプライトの位置を変更しています。これを行うには、ブロックを使用してキューを更新する必要があります。ただし、これを行うと、cocos2d の scheduleUpdate と競合します。Core self.motionManager = のコードは次のとおりです。

[[CMMotionManager alloc] init];
        if (motionManager.isAccelerometerAvailable) {
            NSOperationQueue *queue = [[NSOperationQueue alloc] init];
            [self.motionManager
             startAccelerometerUpdatesToQueue:queue
             withHandler:^(CMAccelerometerData *accelerometerData, NSError *error) {
                 // Deceleration
                 float deceleration = 0.4f;                         // Controls how fast velocity deceerates/low = quck to change dir
                 // sensitivity
                 float sensitivity=0.6f;
                 //how fast the velocity can be at most
                 float maxVelocity=100;

                 // adjust the velocity basedo n current accelerometer acceleration
                 playerVelocity.x = playerVelocity.x*deceleration+accelerometerData.acceleration.x*sensitivity;

                 // we must limit the maximum velocity of the players sprite, in both directions
                 if (playerVelocity.x>maxVelocity) {
                     playerVelocity.x=maxVelocity;
                 }else if (playerVelocity.x < -maxVelocity) {
                     playerVelocity.x = -maxVelocity;
                 }

                 // schedule the -(void)update:(ccTime)delta method to be called every frame

                 [self scheduleUpdateWithPriority:0];
             }];

        }

これは私のスケジュール更新のコードです:

/*************************************************************************/
//////////////////////////Listen for Accelerometer/////////////////////////
/*************************************************************************/
-(void) update:(ccTime)delta
{
    // Keep adding up the playerVelocity to the player's position
    CGPoint pos = player.position;
    pos.x += playerVelocity.x;

    // The player should also be stopped form going outside the screen
    CGSize screenSize = [CCDirector sharedDirector].winSize;
    float imageWidthHalved = player.texture.contentSize.width * 0.5f;
    float leftBorderLimit = imageWidthHalved;
    float rightBorderLimit = screenSize.width - imageWidthHalved;

    // preventing the player sprite from moving outside of the screen
    if (pos.x < leftBorderLimit) {
        pos.x=leftBorderLimit;
        playerVelocity=CGPointZero;
    } else if (pos.x>rightBorderLimit)
    {
        pos.x=rightBorderLimit;
        playerVelocity = CGPointZero;
    }

    // assigning the modified position back
    player.position = pos;
}

scheduleUpdate を使用してバイパスし、更新コードを最初のブロック内に配置できることはわかっていますが、それでも scheduleUpdates を使用できるようにしたいと考えています。どうすればこれを回避できますか?

ご助力ありがとうございます。

PSこれは私のエラーです

    *** Terminating app due to uncaught exception
 'NSInternalInconsistencyException', reason: 
'CCScheduler: You can't re-schedule an 'update' selector'. 
Unschedule it first'
4

1 に答える 1

0

問題は、加速度計ブロックがフレームごとに呼び出されるため、そこで更新をスケジュールできないことです。

初期化で一度更新をスケジュールするだけです。次に、BOOl iVar/property を使用して、更新メソッドが実行中のものを処理する必要があるかどうかを追跡します。

または、すべての更新コードをブロック内に移動します。結局のところ、加速度計の値はフレームごとに更新されるため、実際に「更新」を見逃すことはありません。

于 2012-12-11T11:15:11.510 に答える