0

次のことを行う必要があります: スプライトがある位置に移動し、スプライトがこの位置に移動したら、逆のアクションを実行する必要があります。
この例のテストでは、その位置に到達したときに「ok」と出力するだけで、アクションを過度に解放して何らかの例外のリスクを冒すことを回避しています。

-(id) init
{
    if( (self=[super init]))
    {
        soldier=[CCSprite spriteWithFile: @"soldier.gif"];
        soldier.position= CGPointMake(250, 250);
        [self addChild: soldier];
        CGPoint position=[soldier convertToNodeSpace: CGPointZero];
        CCMoveTo* move=[CCMoveBy actionWithDuration: 2 position: position];
        [move retain];
        [soldier addObserver: self forKeyPath: @"position" options: NSKeyValueObservingOptionNew context: (void*)move];
        [soldier runAction: move];
    }
    return self;
}

- (void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    CGPoint position= [self convertToNodeSpace: soldier.position];
    if(CGPointEqualToPoint(position, CGPointZero));
    {
        NSLog(@"ok");
    }
}

問題は、「ok」を何度も出力することです。一度だけ出力する必要があります。なぜですか?

編集

余分な「;」を削除しました :

- (void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    CGPoint position= [self convertToNodeSpace: soldier.position]; // breakpoint here
    if(CGPointEqualToPoint(position, CGPointZero))
    {
        NSLog(@"ok");
    }
}

これで、「ok」は出力されません。ブレークポイントでは、位置を出力し、最後の値は (47,47) で、(0,0) には到達しません。

4

2 に答える 2

2

メソッド内のifステートメントの最初の行に続くセミコロンを削除します-observeValueForKeyPath:ofObject:change:context:。そのため、NSLog関数は無条件に呼び出されています。

于 2012-12-10T18:34:58.143 に答える
1

cocos2d は KVC/KVO に準拠していないという単純な理由から、私は cocos2d で KVO/KVC を使用しません。Cocos2D クラスのプロパティは、通知を受け取ることなく変更される場合があります。

これが問題かどうかはわかりませんが、KVC/KVO を使い続けると、最終的に問題が発生する可能性が高くなります。

于 2012-12-11T11:18:56.430 に答える