0

raywnderlichのサンプル プロジェクトに従って、最初の cocos2d アプリケーションに挑戦しました。

そのアプリケーションでは、移動ターゲットが以下のように追加されます

-(void)addMonster
{    
    __strong CCSprite * monster = [CCSprite spriteWithFile:@"monster.png"];
    CGSize winSize=[CCDirector sharedDirector].winSize;
    int minY=monster.contentSize.height/2;
    int maxY=winSize.height-minY;
    int rangY=maxY-minY;
    int actualY=(arc4random()%rangY)+minY;

    monster.position=ccp(winSize.width+monster.contentSize.width, actualY);
    [self addChild:monster];
    monster.tag=1;
    int minDuration=2.0;
    int maxDuration=4.0;
    int actualDuration=(arc4random()%(maxDuration-minDuration))+minDuration;

    CCMoveTo *actionMove=[CCMoveTo actionWithDuration:actualDuration
                                             position:ccp(-monster.contentSize.width/2, actualY)];
    CCCallBlock *actionDone=[CCCallBlock actionWithBlock:^(CCSprite *node){
        [node removeFromParentAndCleanup:YES];// crashed at this point
        [_monsters removeObject:node];

    }];
    [monster runAction:[CCSequence actions:actionMove,actionDone,nil]];
    [_monsters addObject:monster];
}

そして、以下のように CCLayerColor サブクラス(シーン)の -init メソッドから上記のメソッドをスケジュールします

-(id)init
{ 
    // player adding code
    [self schedule:@selector(gameLogic) interval:1.0];
}
-(void)gameLogic
{
    [self addMonster];
}

つまり、iPad 画面の左端から右端に移動する

私の問題は、ノード オブジェクトへのアクセス中に CCCallBlock でアプリケーションがクラッシュすることです。

ソースをダウンロードする代わりに、開始点から手順を複製することを計画しましたが、まだリリースされた場所を見つけることができません。仲間を助けて

更新:- クラッシュ時のスクリーンショットを投稿しました ここに画像の説明を入力 ここに画像の説明を入力

4

2 に答える 2

4

問題は、使用しているブロックが期待されるインターフェイスに準拠していないことです。アクションはパラメーターのCCCallBlockないブロックを想定していますが、ブロックをパラメーター (ノード) を受け取るものとして定義しました。これでもコンパイルできることに驚いています。もちろん、渡されたノードはガベージ ポインターになり、アクセスするとクラッシュします。

CCCallBlockNブロックがCCNode*パラメーターとしてポインターを取るこの使用を修正するには、次のようにします。

CCCallBlockN *actionDone = [CCCallBlockN actionWithBlock:^(CCNode *node){
    // ...
    }];
于 2014-01-20T17:43:18.133 に答える
0

問題は、実行中のクリーニングが多すぎるようです。

You add monster to self (+1), 
add to array _monsters (+1), 
then remove [node removeFromParentAndCleanup:YES]; (-1), 
[_monsters removeObject:node]; (-1), 
[self removeChild:node]; (-1)
+2, -3 —> bad access

また (この特定のケースでは) ノードを 2 回削除しようとします。最初に removeFromParentAndCleanup: によって、次に親 removeChild: から何か 1 つを選択します。何かを 2 回削除することはできません。

于 2014-01-20T15:19:11.130 に答える