我读过的大部分教程只解释了HelloWorld类中的Cocos2D示例,但是当我开始构建一个简单的游戏时,我需要知道如何将事件发送到不同的类,并让他们响应无论何时发生。
我有GameSceneLayer,一个CCLayer类,它加载在我不同的精灵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精灵时,我希望它从玩家CCLayer中的PLAYER精灵中产生。
我猜我需要一个类似于:
的GlobalVariables.h #define gameStart @"0"
因此,当按下START精灵时,它会将gameStart更改为1,并且PLAYER精灵中的某个地方有
if (gameStart == 1)
{
[self addChild:PLAYER];
}
但是我不确定如何设置代码,以便PLAYER精灵始终在寻找这些信息。
答案 0 :(得分:1)
你有对象(类的实例)。您希望一个对象与另一个对象进行通信。在Objective-C中,这称为发送消息。在其他语言中,它只是调用方法。
您不需要全局变量。相反,接收对象MainMenu需要向Player对象发送消息(调用方法)。你如何让两个物体相互认识?你可以把它们放在一个臭,声,过度拥挤的迪斯科舞厅里,并希望最好。
或者你可以简单地让他们互相交谈,但唉,他们不应该。由于两者都是GameSceneLayer的兄弟,因此他们不应该自己保持对彼此的引用(除非你使用弱引用,否则创建保留周期的危险)。
但两者都有同一个父母。那么,当两个兄弟姐妹不会互相交谈时,一个好父母会怎么做?它传达了这个信息!
在MainMenu中,向父GameSceneLayer发送消息:
[(GameSceneLayer*)self.parent gameWillStart];
GameSceneLayer实现了该选择器,并将消息转发给任何其他应该被告知开始游戏的对象:
-(void) gameWillStart
{
[player gameWillStart];
[ingameUI gameWillStart];
// etc.
}
播放器还实现了所述选择器:
-(void) gameWillStart
{
[self addChild:PLAYER];
}
另外一件事:在GameSceneLayer中,制作播放器和所有其他对象ivars(实例变量),以便GameSceneLayer可以随时使用这些引用。另一种方法是标记(不太常用)对象,然后使用getChildByTag:
PS:加入PLAYER,因为孩子看起来很可疑。如果你已经创建了任何PLAYER节点,你应该立即添加它,如果有必要,在游戏尚未开始时将其设置为不可见和/或暂停。答案 1 :(得分:0)
您可以使用单身GameState Manager,它可以保存有关游戏状态的信息。
这是一个小片段:
+(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
}
}