0

私が読んだチュートリアルのほとんどは、HelloWorldクラスのCocos2Dの例のみを説明していますが、簡単なゲームの作成を開始したので、さまざまなクラスにイベントを送信する方法と、イベントが発生するたびに応答する方法を知る必要があります。 。

スプライトのさまざまなCCLayerをロードするCCLayerクラスであるGameSceneLayerがあります。

@implementation GameSceneLayer
+ (CCScene *)scene {
    CCScene *scene = [CCScene node]; // Create a container scene instance
    GameSceneLayer *gameLayer = [GameSceneLayer node]; // Create an instance of the current layer class
    [scene addChild:gameLayer]; // Add new layer to container scene
    return scene; // Return ready-made scene and layer in one
}
-(id)init
{
self = [super init];
if (self != nil)
{
    Background *background = [Background node];
    [self addChild:background z:0];
    Player *player = [player node];
    [self addChild:player z:1];
    MainMenu *mainMenu = [MainMenu node];
    [self addChild:mainMenu z:2];

}
return self;
}
@end

ただし、MainMenu CCLayerのSTARTスプライトに触れると、PlayerCCLayerからPLAYERスプライトにスポライトするようにしたいと思います。

次のようなGlobalVariables.hが必要だと思います。

 #define gameStart @"0"

したがって、STARTスプライトを押すと、gameStartが1に変更され、PLAYERスプライトのどこかにあります。

 if (gameStart == 1)
{
    [self addChild:PLAYER];
}

ただし、PLAYERスプライトが常にその情報を検索するようにコードを設定する方法がわかりません。

4

2 に答える 2

1

オブジェクト(クラスのインスタンス)があります。あるオブジェクトが別のオブジェクトと通信する必要があります。Objective-Cでは、これはメッセージの送信と呼ばれます。他の言語では、単にメソッドを呼び出すだけです。

グローバル変数は必要ありません。代わりに、受信オブジェクトMainMenuは、Playerオブジェクトにメッセージを送信する(メソッドを呼び出す)必要があります。2つのオブジェクトをどのようにしてお互いを知るようにしますか?あなたはそれらを臭くて騒々しい、過密なディスコに入れて、最高のものを期待することができます。

または、単にお互いに話をさせることもできますが、残念ながら、そうすべきではありません。どちらもGameSceneLayerの兄弟であるため、相互に参照を保持するべきではありません(弱参照を使用しない限り、保持サイクルを作成する危険性があります)。

しかし、両方とも同じ親を持っています。では、2人の兄弟が互いに話し合わない場合、良い親は何をしますか?メッセージを中継します!

MainMenuで、親GameSceneLayerにメッセージを送信します。

[(GameSceneLayer*)self.parent gameWillStart];

GameSceneLayerはそのセレクターを実装し、ゲームの開始について通知する必要がある他のオブジェクトにメッセージを転送します。

-(void) gameWillStart
{
    [player gameWillStart];
    [ingameUI gameWillStart];
    // etc.
}

また、Playerは上記のセレクターも実装しています。

-(void) gameWillStart
{
    [self addChild:PLAYER];
}

もう1つ、GameSceneLayerで、プレーヤーと他のすべてのオブジェクトをivar(インスタンス変数)にして、GameSceneLayerがこれらの参照をすぐに利用できるようにします。別の方法は、(あまり使用されない)オブジェクトにタグを付けてから、getChildByTagを使用することです。

PS:子供としてPLAYERを追加することは、私には疑わしいように見えます。PLAYERのノードをすでに作成している場合は、すぐに追加し、必要に応じて、ゲームがまだ開始されていない間は非表示にするか一時停止するように設定する必要があります。

于 2012-10-22T18:11:33.283 に答える
0

ゲームの状態に関する情報を保持するシングルトンGameStateManagerを使用できます。

ここに小さなスニペットがあります:

+(GameManager*) sharedGameManager {
if (!_sharedGameManager) {
    _sharedGameManager = [[self alloc] init];
}
return _sharedGameManager;
}

+(id) alloc {
    NSAssert(_sharedGameManager == nil, @"Cannot create second instance of singleton Game Manager");
    return [super alloc];
}

- (id)init
{
    self = [super init];
    if (self) {

    }
    return self;
}

そのゲームマネージャーでは、ゲームの状態を列挙して、そのプロパティを設定できます。

//Header

typedef enum {
     kGameStarted,
     kGameEnded
 }GameState

@interface GameManager : CCNode {

}
@property (nonatomic) GameSate gameState;

次に、実装ファイルに戻って、そのGameStateプロパティを合成し、独自のセッターを作成します

//Implementation
@synthesize gameState = _gameState;

//Create your own setter, so you can notify all listeners
    -(void) setGameState:(GameState) newGameState {
    if (newGameState != _gameState) {
        _gameState = newGameState;

        //Notify listeners via NSNotification
        [[NSNotificationCenter defaultCenter] postNotificationName:@"gameState" object:nil];
    }
}

メッセージを取得したいクラスでは、次のように「gameState」通知をサブスクライブする必要があります。

[[NSNotificationCenter defaultCenter] addObserver:self
        selector:@selector(onGameStateChange:) 
        name:@"gameState"
        object:nil];



  -(void) onGameStateChange{
          if ([GameManager sharedManager].gameState == kGameStarted){
          //start game
          }
   }
于 2012-10-22T18:55:36.653 に答える