【问题标题】:Cocos2d: Can't seem to create child sprites correctly using class or instance methodCocos2d:似乎无法使用类或实例方法正确创建子精灵
【发布时间】:2012-05-06 08:58:24
【问题描述】:

我昨天发了一个类似的帖子,但几乎没有收到任何回复,可能是因为缺乏细节。我会更彻底。

所以我一直在清理我的类 (JoinedMapsLayer),其中添加了我的 tmx 地图并运行更新、绘制等。我尝试将一些方法添加到其他类但没有完全成功。有些创建精灵并成功地将它们显示在屏幕上,但 JoinedMapsLayer 似乎无法再识别它们,即使它们来自它的头文件。因此,我不能使用 JoinedMapsLayer 或其他一些类来删除它。我尝试在添加断点后设置断点(无论添加到何处),然后在控制台中键入 po [spritename],结果为零。

也许我只是不明白这应该如何完全工作,我一定是采取了错误的方法。如果有人能帮助我一劳永逸地理解这一点,将不胜感激!

我遇到了一个很好的例子,但我又一次没有成功。这个根本没有出现。

在这里,我可以向您展示我曾经拥有的东西,效果很好:

(in .h) JoinedMapsLayer 的界面我有:

CCSprite *selectionScreenOverlaySprite;
CCSpriteBatchNode * selectionScreenOverlaySpriteSheet;

我的属性:

@property(nonatomic, retain) CCSprite *selectionScreenOverlaySprite;
@property(nonatomic, retain) CCSpriteBatchNode *selectionScreenOverlaySpriteSheet;

声明方法:

-(void) addSelectionScreenOverlay;

(在 .m 中)我综合了我的属性:

@synthesize selectionScreenOverlaySprite, selectionScreenOverlaySpriteSheet;

我的方法:

-(void) addSelectionScreenOverlay {

    // overlay

    [[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:@"selectionScreenOverlay.plist"];

    selectionScreenOverlaySpriteSheet = [CCSpriteBatchNode batchNodeWithFile:@"selectionScreenOverlay.png"];

    NSMutableArray *selectionScreenFrames = [NSMutableArray array];

    [selectionScreenFrames addObject:
     [[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:
      [NSString stringWithFormat:@"selectionScreenOverlay.png"]]];

    selectionScreenOverlaySprite = [CCSprite spriteWithSpriteFrameName:[NSString stringWithFormat:@"selectionScreenOverlay.png"]];  

    [selectionScreenOverlaySpriteSheet addChild:selectionScreenOverlaySprite];

    [self addChild:selectionScreenOverlaySpriteSheet z:13];

    selectionScreenOverlaySprite.position = [self convertToNodeSpace:CGPointMake(512, 384)];
    selectionScreenOverlaySprite.scale = 260;

    selectionScreenOverlaySprite.opacity = 0;

}

所以效果很好......


但是当我在头文件中导入一个名为 SpriteFX.h 的类并调用新方法时,什么都没有发生???

我这样调用类方法:

[SpriteFX addSelectionScreenOverlayOnLayer:self
                                withSprite:selectionScreenOverlaySprite
                           withSpriteSheet:selectionScreenOverlaySpriteSheet];

我在 SpriteFX.h 中声明了这样的方法:

+(void) addSelectionScreenOverlayOnLayer:(CCLayer*)layer
                              withSprite:(CCSprite*)sprite
                         withSpriteSheet:(CCSpriteBatchNode*)spriteSheet;

而我在 SpriteFX.m 中的方法如下所示:

+(void) addSelectionScreenOverlayOnLayer:(CCLayer*)layer
                              withSprite:(CCSprite*)sprite
                         withSpriteSheet:(CCSpriteBatchNode*)spriteSheet {

    [[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:@"selectionScreenOverlay.plist"];

    spriteSheet = [CCSpriteBatchNode batchNodeWithFile:@"selectionScreenOverlay.png"];

    NSMutableArray *selectionScreenFrames = [NSMutableArray array];

    [selectionScreenFrames addObject:
     [[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:
      [NSString stringWithFormat:@"selectionScreenOverlay.png"]]];

    sprite = [CCSprite spriteWithSpriteFrameName:[NSString stringWithFormat:@"selectionScreenOverlay.png"]];  

    [spriteSheet addChild:sprite];

    [layer addChild:spriteSheet z:13];

    sprite.position = [layer convertToNodeSpace:CGPointMake(512, 384)];
    sprite.scale = 260;

    sprite.opacity = 0;
}

没有豆子

如果我理解正确,因为我将 self 作为 CCLayer 传递,那么我的类方法中的层应该指向 JoinedMapsLayer 中的 CCLayer。此外,传递的精灵和精灵表应该指向 JoinedMapsLayer,所以它应该可以正常工作......但事实并非如此。

在 JoinedMapsLayer 中调用类方法后,我检查了 selectionScreenOverlaySprite 上的父对象。是零。

【问题讨论】:

    标签: ios methods cocos2d-iphone instance sprite


    【解决方案1】:

    在您的第一段代码中,您没有正确访问属性。您应该使用 self 指针来获取属性...在您的代码中,您只是直接访问 ivar。现在有了 ARC,理论上它应该在 ivar 上进行正确的保留/释放,但仍然如此。

    self.selectionScreenOverlaySpriteSheet = [CCSpriteBatchNode batchNodeWithFile:@"selectionScreenOverlay.png"];
    

    在您的第二个示例中, spriteSheet 是传递给方法的参数,您会在第二行立即用新值覆盖该方法,因此 spriteSheet 中的任何内容现在都丢失了。取决于代码的其余部分,这可能会或可能无关紧要,但是调用您的共享方法的人将无法引用精灵表。

    如果您在 ARC 上,那么运行时可能会在调用 addChild 之后立即释放 spriteSheet。我不熟悉这些引用是如何在 cocos2d 中设置的,但如果它们很弱或没有保留,那么这也可能是一个问题。

    【讨论】:

    • 感谢您的解释。有趣的是“调用我的共享方法的人将无法引用精灵表”;它会失去其父属性吗?我正在使用 Cocos2D 的 0.95 的编辑版本,没有 ARC。
    • 不,这是因为修改共享方法中的变量不会自动将值复制回调用该方法的人。您需要在方法签名中声明它的 **type 等 *var = blah;,然后将值复制回调用者。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多