0

我读过的大多数教程只解释了 HelloWorld 类中的 Cocos2D 示例,但是当我开始构建一个简单的游戏时,我需要知道如何将事件发送到不同的类,并让它们在发生时做出响应.

我有 GameSceneLayer,一个 CCLayer 类,它加载到我不同的 Sprite 的 CCLayers 中:

@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 精灵被触摸时,我希望它从 Player CCLayer 的 PLAYER 精灵中生成。

我猜我需要一个 GlobalVariables.h 类似的东西:

 #define gameStart @"0"

因此,当按下 START 精灵时,它会将 gameStart 更改为 1,并且在 PLAYER 精灵中的某处有

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

但是我不确定如何设置代码,以便播放器精灵始终在寻找该信息。

4

2 回答 2

1

你有对象(类的实例)。您希望一个对象与另一个对象进行通信。在 Objective-C 中,这称为发送消息。在其他语言中,它只是调用一个方法。

您不需要全局变量。相反,接收对象 MainMenu 需要向 Player 对象发送消息(调用方法)。如何让两个对象相互认识?你可以把它们放在一个臭气熏天、吵吵闹闹、人满为患的迪斯科舞厅里,然后寄希望于最好的结果。

或者你可以简单地让他们互相交谈,但很可惜,他们不应该这样做。由于两者都是 GameSceneLayer 的兄弟姐妹,因此它们本身不应持有彼此的引用(除非您使用弱引用,否则会产生保留循环的危险)。

但两者都有相同的父母。那么当两个兄弟姐妹不互相交谈时,一个好父母会怎么做呢?它传递信息!

在 MainMenu 中,向父 GameSceneLayer 发送消息:

[(GameSceneLayer*)self.parent gameWillStart];

GameSceneLayer 实现了该选择器,并将消息转发给任何其他应该被告知开始游戏的对象:

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

并且 Player 还实现了上述选择器:

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

还有一件事:在 GameSceneLayer 中,使玩家和所有其他对象 ivars(实例变量),以便 GameSceneLayer 可以随时使用这些引用。另一种方法是标记(不太常用的)对象,然后使用 getChildByTag:

PS:在我看来,将 PLAYER 添加为孩子看起来很可疑。如果您已经创建了任何节点 PLAYER,您应该立即添加它,如有必要,将其设置为不可见和/或在游戏尚未开始时暂停。

于 2012-10-22T18:11:33.283 回答
0

您可以使用单例 GameState 管理器,它保存有关游戏状态的信息。

这是一个小片段:

+(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 属性,并创建你自己的 setter

//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 回答