Cocos2D:如何在不同类之间发送事件
Posted
技术标签:
【中文标题】Cocos2D:如何在不同类之间发送事件【英文标题】:Cocos2D: How to send events between different classes 【发布时间】:2012-10-22 17:42:54 【问题描述】:我读过的大多数教程只解释了 HelloWorld 类中的 Cocos2D 示例,但是当我开始构建一个简单的游戏时,我需要知道如何将事件发送到不同的类,并让它们响应每当它发生。
我有 GameSceneLayer,一个 CCLayer 类,它加载到我的不同 CCLayer 的 Sprites 中:
@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];
但是我不确定如何设置代码,以便播放器精灵始终在寻找该信息。
【问题讨论】:
看看 NSNotifications。他们可能会在您的情况下为您提供帮助。 除了你的单身教条工具包......继续寻找:) 【参考方案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,则应立即添加它,如有必要,将其设置为不可见和/或在游戏尚未开始时暂停。
【讨论】:
成功了!尽管 ios 6/iPhone5 已经发布,您的书是否仍然具有相关性,还是即将更新?我会买的。【参考方案2】:您可以使用单例 GameState 管理器,它保存有关游戏状态的信息。
这是一个小sn-p:
+(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
【讨论】:
以上是关于Cocos2D:如何在不同类之间发送事件的主要内容,如果未能解决你的问题,请参考以下文章