Cocos2d iphone InitWithPriteFrameName在升级到cocos2d v2.0后未初始化类
我一直在构建《学习Cocos2D》一书中描述的太空海盗项目。当我开始遇到问题时,我已经读到了关于Box2D的第10章。然后我尝试将cocos2D从版本1升级到版本2.0。在进行必要的更改以修复弃用之后,代码不再工作。具体来说,我发现当创建游戏对象或敌人对象时,它们的init方法不再被调用。例如,当执行以下行时:Cocos2d iphone InitWithPriteFrameName在升级到cocos2d v2.0后未初始化类,cocos2d-iphone,xcode4.5,Cocos2d Iphone,Xcode4.5,我一直在构建《学习Cocos2D》一书中描述的太空海盗项目。当我开始遇到问题时,我已经读到了关于Box2D的第10章。然后我尝试将cocos2D从版本1升级到版本2.0。在进行必要的更改以修复弃用之后,代码不再工作。具体来说,我发现当创建游戏对象或敌人对象时,它们的init方法不再被调用。例如,当执行以下行时: RadarDish *radarDish = [[RadarDish alloc] initWithSpriteFrameName:@"radar_1.png"]; 未调用RadarD
RadarDish *radarDish = [[RadarDish alloc] initWithSpriteFrameName:@"radar_1.png"];
未调用RadarDish init方法。然后,我研究了版本1和版本2中initWithPriteFrameName的执行情况,发现CCSprite.m已发生更改,因此不再调用init方法。在版本2源代码中,initWithPriteFrameName方法调用initWithPriteFrame,后者调用initWithTexture,后者调用:
-(id) initWithTexture:(CCTexture2D*)texture rect:(CGRect)rect rotated:(BOOL)rotated
{
if( (self = [super init]) ) {
因此,不调用RadarDish init方法。而是调用CCNode init方法。但是,在版本1中,InitWithPriteFrameName调用InitWithPriteFrame,后者调用initWithTexture,后者具有以下代码:
// IMPORTANT: [self init] and not [super init];
if( (self = [self init]) ){
[self setTexture:texture];
[self setTextureRect:rect];
}
这允许调用RadarDish init方法
我能做些什么来解决这个问题?这本书似乎不太可能需要修改以支持升级到cocos2dv2.0,所以我怀疑我肯定错过了其他东西。但是如果我错了,那么如何更改此代码以调用RadarDish init方法呢?好的,我错了。“CoCoS2D2.x在许多细节上与v1.x不同,所以不能期望v1.x代码只在2.x下工作”。如果您要学习“Learning Cocos2D”一书,我建议您加载Cocos2D iphone 1.0.1版。否则,您将面临许多不兼容以及许多需要修复的不推荐 但是如果你真的想使用最新的cocos2d,那么你应该做一些事情。1) 按照中的说明操作。2) 您将要修复大量的弃用和更改,因此请使用了解如何修复这些弃用和更改。3) 你还需要更新操纵杆类,所以要获得这些更改,你必须用谷歌搜索其余部分以找到解决方案 现在,关于我在这里提到的问题的解决方案,可能有多种解决方案,但我将在下面提供一种(感谢Sylvan在上面的回答): 在每个GameObjects、EneMyObject和PowerUps中,我都添加了一个方法来覆盖initWithFrameName。这将避免使用objects init方法。例如,对于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;
}
这允许GameObject和GameCharacter init方法在CCSprite的initWithPriteFrameName方法运行之前运行
Viking游戏对象必须有一个稍微不同的解决方案,因为它是用initWithPriteFrame而不是initWithPriteFrameName初始化的。但是覆盖实现与上面的RadarDish示例基本相同
(除了克服反对意见所需的所有更改之外)上述更改允许“Learning CoCoCos2D”示例中的所有其他内容保持不变
祝你好运。好吧,我错了。“CoCoS2D2.x在许多细节上与v1.x不同,所以不能期望v1.x代码只在2.x下工作”。如果您要学习“Learning Cocos2D”一书,我建议您加载Cocos2D iphone 1.0.1版。否则,您将面临许多不兼容以及许多需要修复的不推荐 但是如果你真的想使用最新的cocos2d,那么你应该做一些事情。1) 按照中的说明操作。2) 您将要修复大量的弃用和更改,因此请使用了解如何修复这些弃用和更改。3) 你还需要更新操纵杆类,所以要获得这些更改,你必须用谷歌搜索其余部分以找到解决方案 现在,关于我在这里提到的问题的解决方案,可能有多种解决方案,但我将在下面提供一种(感谢Sylvan在上面的回答): 在每个GameObjects、EneMyObject和PowerUps中,我都添加了一个方法来覆盖initWithFrameName。这将避免使用objects init方法。例如,对于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;
}
这允许GameObject和GameCharacter init方法在CCSprite的initWithPriteFrameName方法运行之前运行
Viking游戏对象必须有一个稍微不同的解决方案,因为它是用initWithPriteFrame而不是initWithPriteFrameName初始化的。但是覆盖实现与上面的RadarDish示例基本相同
(除了克服反对意见所需的所有更改之外)上述更改允许“Learning CoCoCos2D”示例中的所有其他内容保持不变
祝你好运。我认为你遇到了麻烦,因为你保持了init方法的原样,而没有修改它。您正在RadarDish类上调用一个initWithPriteFrameName:方法,但该类没有该方法名,因此它看起来是它的超类。我认为您可以简单地将init方法重命名为initWithPriteFrameName:这样您就可以了。像这样:
// RadarDish.m
-(id) initWithSpriteFrameName:(NSString*)frameName {
if ((self = [super initWithSpriteFrameName:frameName])) {
// init anything here
}
return self;
}
只是不要让一个名为init的方法被调用。我认为您遇到了问题,因为您保持了init方法的原样,而没有修改它。您正在RadarDish类上调用一个initWithPriteFrameName:方法,但该类没有该方法名,因此它看起来是它的超类。我认为您可以简单地将init方法重命名为initWithPriteFrameName:这样您就可以了。像这样:
// RadarDish.m
-(id) initWithSpriteFrameName:(NSString*)frameName {
if ((self = [super initWithSpriteFrameName:frameName])) {
// init anything here
}
return self;
}
只是不要让一个名为init的方法被调用。initWithPriteFrameName应该可以工作。您的init方法是什么样子的?cocos2d 2.x在许多细节上与v1.x不同,因此不能期望v1.x代码仅在2.xinitWithPriteFrame下工作