soleil
soleil

Reputation: 13085

Objective C Polymorphism for a Game Class

My situation is that I have a few different mini-games in my app. The games are listed in a table view, and when one of them is selected I create the corresponding game object. I need the game objects to have a common parent class, so that I can do common things such as pausing and resuming.

I have a generic GameScene class which has a generic GameLayer property:

@interface GameScene : CCScene {

}

@property (nonatomic, strong) GameLayer* gameLayer;

However each child class of GameScene has it's own type of GameLayer. So for example the SuperMarioBros_GameScene has a SuperMarioBros_GameLayer. The problems arise when I initialize the 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;
}

In general each game will also have an input layer, which will send UI messages to the gameLayer. I get this error:

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

I understand this is happening because SuperMarioBros_GameLayer implements <SuperMarioBros_FireDelegate>, but GameLayer doesn't.

So my question is how do I make the GameScene class hold a polymorphic property that can be any subclass of GameLayer? Keeping in mind that each type of GameLayer may implement different protocols based on their corresponding input layers? Or maybe there's a better way to go about this?

Again, the end goal is to be able to make a call from the main game controller such as

[currentGameScene pause];

which will in turn do something like:

[self.gameLayer pauseGameLoop];

Upvotes: 1

Views: 252

Answers (1)

Martin R
Martin R

Reputation: 539795

In the implementation file of the SuperMarioBros_GameScene class, you can override the property declaration of the gameLayer property in a class extension:

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

Then you should not get a compiler error anymore.

This will not create new getter or setter functions (these are still called in the superclass), and does not introduce a new instance variable as backing store. It only tells the compiler that self.gameLayer is an instance of the subclass in this implementation file.

Upvotes: 2

Related Questions