【问题标题】:SpriteKit .sks files and subclassingSpriteKit .sks 文件和子类化
【发布时间】:2015-04-10 00:14:49
【问题描述】:

Apple 在其关于 SpriteKit 最佳实践的 WWDC 2014 Session 608 视频中演示了此代码。

AppDelegate.m

+ (instancetype)unarchiveFromFile:(NSString *)file {
    /* Retrieve scene file path from the application bundle */
    NSString *nodePath = [[NSBundle mainBundle] pathForResource:file ofType:@"sks"];
    /* Unarchive the file to an SKScene object */
    NSData *data = [NSData dataWithContentsOfFile:nodePath
                                      options:NSDataReadingMappedIfSafe
                                        error:nil];
    NSKeyedUnarchiver *arch = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
    [arch setClass:self forClassName:@"SKScene"];
    SKScene *scene = [arch decodeObjectForKey:NSKeyedArchiveRootObjectKey];
    [arch finishDecoding];

    return scene;
}

我了解它在做什么的要点,但我感到困惑的是如何将此代码用于任何其他 .sks 文件。我尝试从我的 GameScene.m 类中调用 unarchiveFromFile 方法,但无济于事。我阅读了关于这个主题的帖子here,但它没有澄清事情。

编辑 根据 Okapi 的建议,我在 GameScene.m 类的新 OS X SceneKit 项目中尝试了以下操作:

#import "GameScene.h"

@implementation GameScene

-(void)didMoveToView:(SKView *)view {
    SKNode *nodeInScene2 = [self childNodeWithName:@"object1"];
    for (SKNode *blah in [SKScene unarchiveFromFile:@"Scene2"].children) {
        [nodeInScene2 addChild:blah];
    }
}

-(void)update:(CFTimeInterval)currentTime {
    /* Called before each frame is rendered */
}

@end

我有 2 个 .sks 文件。第一个称为 GameScene.sks,其中有一个名为“object1”的精灵。我想添加存储在“Scene2.sks”中的孩子。 didMoveToView 方法中的循环给了我一个错误。我究竟做错了什么?这是 Apple 在他们的 WWDC 608 视频中所做的,但也许我错过了一些东西,因为我在网上找不到他们的项目。

【问题讨论】:

  • 像视图控制器中的 init 方法一样使用它let scene = [GameScene unarchiveFromFile: "your sks filename here"]
  • 我试过了,它甚至没有显示该方法的选项。顺便说一句,我使用的是目标 C 而不是 Swift。我在我的 GameScene 课程中尝试过。我尝试包含 AppDelegate.h 标头,但似乎没有任何效果。
  • 这个方法应该在你的 GameScene 类文件中
  • 那么,您是说我应该从 AppDelegate 中获取 unarchiveFromFile 方法并将其粘贴到 GameScene.m 中?我刚试过,但我一定是做错了什么:/这是你的意思吗?

标签: objective-c sprite-kit


【解决方案1】:

+unarchiveFromFile: 在 GameViewController.m 中定义为 SKScene 上的一个类别。如果您想在其他地方使用它,则需要复制该代码。

@implementation SKScene (Unarchive)

+ (instancetype)unarchiveFromFile:(NSString *)file {
    /* Retrieve scene file path from the application bundle */
    NSString *nodePath = [[NSBundle mainBundle] pathForResource:file ofType:@"sks"];
    /* Unarchive the file to an SKScene object */
    NSData *data = [NSData dataWithContentsOfFile:nodePath
                                          options:NSDataReadingMappedIfSafe
                                            error:nil];
    NSKeyedUnarchiver *arch = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
    [arch setClass:self forClassName:@"SKScene"];
    SKScene *scene = [arch decodeObjectForKey:NSKeyedArchiveRootObjectKey];
    [arch finishDecoding];

    return scene;
}

@end

【讨论】:

    【解决方案2】:

    这个也让我挂了一段时间。我最终在每个需要它的子类中声明了 unarchiveFromFile,然后在我想要转换场景时调用它。像这样的...

    if (contactQuery == (playerCategory | proceedCategory)) {
        SKScene *levelTwo = [LevelTwo unarchiveFromFile:@"LevelTwo"];
        [self.view presentScene:levelTwo transition:[SKTransition doorsCloseHorizontalWithDuration:0.5]];
    }
    

    完整示例代码可在here下载。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-04
      • 1970-01-01
      相关资源
      最近更新 更多