0

「LearningCocos2D」という本で説明されているSpaceVikingプロジェクトを構築しています。問題が発生し始めたとき、Box2Dの第10章にたどり着きました。次に、cocos2Dをバージョン1からバージョン2.0にアップグレードしようとしました。非推奨を修正するために必要な変更を加えた後、コードは機能しなくなります。具体的には、ゲームオブジェクトまたは敵オブジェクトが作成されると、それらのinitメソッドが呼び出されなくなることがわかりました。たとえば、次の行が実行された場合:

RadarDish *radarDish = [[RadarDish alloc] initWithSpriteFrameName:@"radar_1.png"];

RadarDishinitメソッドは呼び出されません。次に、バージョン1とバージョン2の両方でinitWithSpriteFrameNameの実行を調べたところ、CCSprite.mが変更され、initメソッドが呼び出されなくなったことがわかりました。バージョン2のソースコードでは、initWithSpriteFrameNameメソッドはinitWithSpriteFrameを呼び出し、これはinitWithTextureを呼び出します。

-(id) initWithTexture:(CCTexture2D*)texture rect:(CGRect)rect rotated:(BOOL)rotated
{
    if( (self = [super init]) ) {

したがって、RadarDishinitメソッドは呼び出されません。代わりに、CCNodeinitメソッドが呼び出されます。ただし、バージョン1では、initWithSpriteFrameNameは、次のコードを持つinitWithTextureを呼び出すinitWithSpriteFrameを呼び出します。

// IMPORTANT: [self init] and not [super init];
if( (self = [self init]) ){
    [self setTexture:texture];
    [self setTextureRect:rect];
}

これにより、RadarDishinitメソッドを呼び出すことができます。

これを解決するにはどうすればよいですか?cocos2d v2.0へのアップグレードをサポートするために本を変更する必要はないようですので、何か他のものが欠けているに違いないと思います。しかし、私が間違っている場合、このコードを変更してRadarDishinitメソッドを呼び出す方法は何でしょうか。

4

2 に答える 2

3

わかりました、私は間違っていました。「cocos2d2.xはv1.xとは多くの点で異なるため、v1.xコードが2.xでのみ機能することは期待できません。」「LearningCocos2D」という本をフォローする場合は、cocos2d-iphoneバージョン1.0.1をロードすることをお勧めします。そうしないと、多くの非互換性と修正すべき多くの非推奨に直面することになります。

しかし、本当に最新のcocos2dを使用したい場合は、いくつかのことを行う必要があります。1)このリンクの指示に従ってください。2)修正すべき多くの非推奨と変更があるため、このリンクを使用して、これらの非推奨と変更を修正する方法を理解してください。3)ジョイスティッククラスも更新する必要があるので、これらの変更を取得するにはこのリンクにアクセスしてください。4)解決策を見つけるために残りをグーグルで検索する必要があります。

ここで述べた問題の解決策については、複数の解決策がある可能性がありますが、以下に1つ提供します(上記のSylvanの回答に感謝します)。

GameObjects、EnemyObjects、およびPowerUpsのそれぞれに、initWithFrameNameをオーバーライドするメソッドを追加しました。これにより、objectsinitメソッドの使用が回避されます。たとえば、RadarDishの場合、次を追加しました。

-(id) initWithSpriteFrameName:(NSString*)frameName {
    if( (self=[super init]) ) {
        if ((self = [super initWithSpriteFrameName:frameName])) {

            CCLOG(@"### RadarDish initialized");
            [self initAnimations];                                   // 1
            characterHealth = 100.0f;                                // 2
            gameObjectType = kEnemyTypeRadarDish;                    // 3
            [self changeState:kStateSpawning];                       // 4

        }
    }
    return self;
}

これにより、CCSpriteのinitWithSpriteFrameNameメソッドを実行する前に、GameObjectメソッドとGameCharacterinitメソッドを実行できます。

Viking GameObjectは、initWithSpriteFrameNameではなくinitWithSpriteFrameで初期化されるため、わずかに異なるソリューションが必要でした。ただし、オーバーライドの実装は、基本的に上記のRadarDishの例と同じです。

(非推奨を克服するために必要なすべての変更を除いて)上記の変更により、「LearningCocos2D」の例の他のすべてがそのまま残ることができました。

幸運を。

于 2013-01-19T16:34:33.997 に答える
2

initメソッドを変更せずにそのままにしておくため、問題が発生していると思います。RadarDishクラスでメソッドinitWithSpriteFrameName:を呼び出していますが、そのクラスにはそのメソッド名がないため、そのスーパークラスを参照します。initメソッドの名前をinitWithSpriteFrameName:に変更するだけで、問題はなかったと思います。このような:

// RadarDish.m

-(id) initWithSpriteFrameName:(NSString*)frameName {
   if ((self = [super initWithSpriteFrameName:frameName])) {
      // init anything here
   }
   return self;
}

initという名前のメソッドも持たず、呼び出されることを期待してください。

于 2013-01-19T18:07:27.303 に答える