1

私の状況では、アプリにいくつかの異なるミニゲームがあります。ゲームはテーブルビューに一覧表示され、そのうちの1つを選択すると、対応するゲームオブジェクトが作成されます。一時停止や再開などの一般的なことを実行できるように、ゲームオブジェクトに共通の親クラスが必要です。

ジェネリック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];
4

1 に答える 1

2

クラスの実装ファイルでは、クラス拡張SuperMarioBros_GameSceneのプロパティのプロパティ宣言をオーバーライドできます。gameLayer

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

そうすれば、コンパイラエラーは発生しなくなります。

これは、新しいゲッターまたはセッター関数を作成せず(これらは引き続きスーパークラスで呼び出されます)、バッキングストアとして新しいインスタンス変数を導入しません。self.gameLayerこれは、この実装ファイルのサブクラスのインスタンスであるコンパイラーにのみ通知します。

于 2013-03-15T18:31:37.853 に答える