2013-03-15 65 views
1

我的情况是,我的应用程序中有几个不同的迷你游戏。游戏以表格视图列出,当选择其中一个游戏时,我创建相应的游戏对象。我需要游戏对象具有共同的父类,以便我可以执行常见的事情,例如暂停和恢复。目标C游戏类多态性

我有有一个通用的GameLayer财产通用GameScene类:

@interface GameScene : CCScene { 

} 

@property (nonatomic, strong) GameLayer* gameLayer; 

但是每个子类GameScene有它自己的类型GameLayer的。所以例如SuperMarioBros_GameScene有一个SuperMarioBros_GameLayer。当我初始化SuperMarioBros_GameScene出现的问题:

-(id) init 
{ 
    if((self = [super init])) { 
     self.gameLayer = (SuperMarioBros_GameLayer*)[SuperMarioBros_GameLayer node]; 
     [self addChild: self.gameLayer]; 

     SuperMarioBros_InputLayer *inputLayer = [SuperMarioBros_InputLayer node]; 
     inputLayer.delegate = self.gameLayer; //ERROR (see below) 
     [self addChild:inputLayer z:1 tag:2]; 
    } 
    return self; 
} 

通常,每个游戏中还将有一个输入层,其将发送UI消息到gameLayer。我得到这个错误:

Assigning to 'id <SuperMarioBros_FireDelegate> from incompatible type GameLayer* 

我明白这是发生,因为SuperMarioBros_GameLayer实现<SuperMarioBros_FireDelegate>,但GameLayer没有。

所以我的问题是如何让GameScene类拥有一个可以是GameLayer的任何子类的多态属性?请记住,每种类型的GameLayer都可以根据其相应的输入层实现不同的协议?或者也许有更好的方法去解决这个问题?

同样,最终目标是能够从主游戏控制拨打电话如

[currentGameScene pause]; 

这将反过来做这样的事情:

[self.gameLayer pauseGameLoop]; 

回答

2

在实现文件SuperMarioBros_GameScene类,您可以覆盖类扩展中gameLayer属性的属性声明:

@interface SuperMarioBros_GameScene() 
@property (nonatomic, strong) SuperMarioBros_GameLayer *gameLayer; 
@end 

然后你不应该得到一个编译器错误了。

这不会创建新的getter或setter函数(这些函数仍然在超类中调用),并且不会引入新的实例变量作为后备存储。它只告诉编译器self.gameLayer是这个实现文件中的子类的一个实例。

+0

我大概有75%清楚为什么这项工作,但它确实,而且很容易。 – soleil 2013-03-15 20:28:43