何时在xCode 6.4中使用带有SpriteKit的didMoveToView或initWithSize

时间:2015-07-31 12:24:57

标签: ios objective-c xcode xcode6 sprite-kit

由于xCode已更新至6.0版,因此“GameScene”(创建的默认场景)中SpriteKit的默认方法更改为:

underscore.string

与旧方法相反:

-(void) didMoveToView:(SKView *) view {
/* Scene set up in here */
}

我知道新方法(与视图控制器中的更改一样)用于帮助管理xCode 6中新增的.sks文件的导入。但是,如果我不想,我很好奇使用新的“storyboard”类型格式即.sks文件,我还应该使用新方法吗?或者我应该将方法更改回initWithSize方法并删除.sks文件?

3 个答案:

答案 0 :(得分:5)

应该使用Init方法进行初始化,但请记住,在init内部,视图始终是nil。因此,任何需要视图的代码都必须移动到didMoveToView方法(在视图呈现场景后立即调用它)。

关于Xcode 6中的initWithSize ...默认情况下,场景是从.sks文件加载的。因此,initWithSize实际上从未被调用过。而是调用initWithCoder

- (instancetype)initWithCoder:(NSCoder *)aDecoder
{

    if (self = [super initWithCoder:aDecoder]) {
        // do stuff 
    }
    return self;
}

因此,初始化initWithSize内的任何内容都不会产生任何影响。如果您决定删除.sks文件并在" old"中创建一个场景方式,你可以在视图控制器中做这样的事情:

- (void)viewDidLoad
{
    [super viewDidLoad];

    // Configure the view.
    SKView * skView = (SKView *)self.view;
    skView.showsFPS = YES;
    skView.showsNodeCount = YES;
    /* Sprite Kit applies additional optimizations to improve rendering performance */
    skView.ignoresSiblingOrder = YES;

    // Create and configure the scene.
    GameScene *scene = [GameScene sceneWithSize:self.view.bounds.size];
    scene.scaleMode = SKSceneScaleModeAspectFill;


    // Present the scene.
    [skView presentScene:scene];
}

之后,您可以使用initWithSize进行初始化。

请注意,在viewDidLoad中,视图的最终大小可能尚未知晓,而使用viewWillLayoutSubviews可能是正确的选择。阅读更多here

为场景初始化目的正确实现viewWillLayoutSubviews将是:

- (void)viewWillLayoutSubviews
{
    [super viewWillLayoutSubviews];

    // Configure the view.
    SKView * skView = (SKView *)self.view;
    skView.showsFPS = YES;
    skView.showsNodeCount = YES;
    /* Sprite Kit applies additional optimizations to improve rendering performance */
    skView.ignoresSiblingOrder = YES;

    //viewWillLayoutSubviews can be called multiple times (read about this in docs ) so we have to check if the scene is already created
    if(!skView.scene){
        // Create and configure the scene.
        GameScene *scene = [GameScene sceneWithSize:self.view.bounds.size];
        scene.scaleMode = SKSceneScaleModeAspectFill;

        // Present the scene.
        [skView presentScene:scene];
    }
}

Swift代码:

override func viewWillLayoutSubviews() {
    super.viewWillLayoutSubviews()

    if let scene = GameScene.unarchiveFromFile("GameScene") as? GameScene {
        // Configure the view.
        let skView = self.view as SKView
        skView.showsFPS = true
        skView.showsNodeCount = true
        skView.showsPhysics = true
        skView.showsDrawCount = true

        /* Sprite Kit applies additional optimizations to improve rendering performance */
        skView.ignoresSiblingOrder = true

        /* Set the scale mode to scale to fit the window */

        if(skView.scene == nil){

            scene.scaleMode = .AspectFill
            scene.size  = skView.bounds.size
            skView.presentScene(scene)
        }


    }
}

答案 1 :(得分:2)

我认为,就所有意图和目的而言,在实际设置场景和使用它时,两种方法之间没有太大区别。 (initWithSize在初始化场景时调用,而didMoveToView在场景由视图显示时始终调用。我想如果你真的更喜欢看初始化,那么你可以毫无困难地使用init方法。

关于.sks文件:

看看你的视图控制器实现文件。在v.controller的方法正上方,你会看到:

@implementation SKScene (Unarchive)

+ (instancetype)unarchiveFromFile:(NSString *)file {
    /* Retrieve scene file path from the application bundle */
    NSString *nodePath = [[NSBundle mainBundle] pathForResource:fileofType:@"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

这是处理sk的部分。使用该文件是完全可选的,您不会被迫这样做,它对您设置场景没有任何影响。但是,如果您确实希望使用它,那么您将发现您需要使用此代码段。

答案 2 :(得分:0)

两种选择都是正确的。说,init方法实际上与didMoveToView:方法不同,因为在SKScene中显示SKView后,将调用最后一个方法。