1

ObjectiveCで問題が発生しています。スプライトを移動した後にブロックを呼び出そうとしています

私が達成しようとしていることの短いバージョンは、すべての敵を配列で動かしたいということです。そして、それぞれが動き終わったら、それが衝突したかどうかを確認したいと思います。

以下の簡略化されたコードは、私がやろうとしていることを示しています。

私のActorクラスは次のように定義されています

// -----------------------------
// Actor.h

#import <Foundation/Foundation.h>
#import "cocos2d.h"
#import "ScreenObject.h"

typedef void (^actorMoveComplete)(void);

@interface Actor : ScreenObject
{
   // actorMoveComplete onMoveComplete;
}

@property (nonatomic) BOOL isMoving;
@property (readwrite, copy) actorMoveComplete onMoveComplete;
@property (nonatomic, retain) CCSprite* sprite;

-(void) moveTo:(CGPoint)targetPosition Speed:(float) speed withCallback:(actorMoveComplete)moveComplete;

@end

// -----------------------------
//  Actor.m
#import "Actor.h"

@implementation Actor

@synthesize onMoveComplete;
@synthesize sprite;

-(void) moveTo:(CGPoint)targetPosition Speed:(float) speed withCallback:(actorMoveComplete)moveComplete;
{
    onMoveComplete = moveComplete;

    id actionMove = [CCMoveTo actionWithDuration:speed position:targetPosition];
    id actionMoveDone = [CCCallFuncN actionWithTarget:self selector:@selector(spriteMoveFinished:)];
    [super.sprite runAction:[CCSequence actions:actionMove, actionMoveDone, nil]];
}

-(void) spriteMoveFinished:(id) sender
{
    isMoving = NO;
    if (onMoveComplete != nil)
        onMoveComplete();
}
@end

ご覧のとおり、ブロックをonMoveCompleteパラメーターに格納しようとしています(プライベート変数にも格納しようとしています)。スプライトの移動が完了したら、ブロックを呼び出します。

私の呼び出しクラスでは、多数のアクター(敵)を反復処理しており、移動が完了したら、各アクターに対してこの匿名コードブロックを呼び出したいと思います。

{
   [self checkForCollision:enemy];
}

私の呼び出しクラスは次のようになります。

//------------------------------
//
//  GameLayer.h

#import "cocos2d.h"
#import "Actor.h"

@interface GameLayer : CCLayerColor
{
}

@property (nonatomic, copy) NSMutableArray *enemies;

- (void) updateEnemies;
- (void) checkForCollision:(Actor*)actor;
- (BOOL) isMapGridClear:(CGPoint)mapGrid excludeActor:(Actor*)actor;

@end


//------------------------------
//  GameLayer.m

#import "GameLayer.h"


@implementation GameLayer

@synthesize enemies;

- (void) updateEnemies
{

    for (Actor *enemy in enemies)
    {
        //  
        CGPoint newPosition = [self getNewPosition:enemy]; /* method to figure out new position */

        [enemy moveDelta:ccp(dX, dY) Speed:enemySpeed withCallback:^{
            [self checkForCollision:enemy];
        }];
    }
}


- (void) checkForCollision:(Actor*)actor
{
    if (![self isMapGridClear:actor.gridPosition excludeActor:actor])
    {
        actor.isCrashed=YES;
        [actor loadSprite:self spriteImage:@"crashed.png"];
    }
}


- (BOOL) isMapGridClear:(CGPoint)mapGrid excludeActor:(Actor*)actor
{
    /* Actual method figures out if there was a collision    */
    return YES;
}

@end

残念ながら、onMoveCompleteブロックを呼び出すと、EXC_BAD_ACCESSエラーが発生し続けます。興味深いことに、moveToメソッド内でブロックを呼び出そうとすると、機能します(ただし、もちろん、移動が完了した後にこれをトリガーする必要があります)。

誰かが私が間違っていることで私を助けることができますか?私も正しいメカニズムを使用していますか?

(フォーマットが不十分で不完全なコードセグメントについてお詫びします)

4

1 に答える 1

2

プロパティをコピーとして正しく宣言しましたが、生成されたアクセサーを使用せずに、インスタンス変数をブロックのアドレスに直接設定しています。つまり、ブロックはコピーされず、呼び出される前に破棄されます。

を使用してブロックを割り当てれself.onMoveCompleted = moveCompletedば、問題はありません。

于 2012-05-19T08:04:03.543 に答える