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

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

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

与以前的方法相反:

 -(id) initWithSize:(CGSize) size { if (self = [super initWithSize:size]{ /* Scene set up in here */ } } 

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

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

关于Xcode 6中的initWithSize …默认情况下,场景是从.sks文件加载的。 正因为如此, initWithSize实际上永远不会被调用。 initWithCoder被调用:

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

所以初始化initWithSize里面的东西不会有任何效果。 如果您决定删除.sks文件并以“旧”的方式创build一个场景,您可以在视图控制器中做这样的事情:

 - (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可能是一个正确的select。 在这里阅读更多。

为了场景初始化,适当的实现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) } } } 

我认为,就所有的意图和目的而言,在实际设置场景和使用场景方面,两种方法之间没有什么区别。 ( 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 

这是处理sks的部分。 使用这个文件是完全可选的,你不需要这样做,它确实不会影响你设置你的场景。 但是,如果你想使用它,那么你会发现你需要使用这个代码片段。

两个选项都是正确的。 说, init方法实际上与didMoveToView:方法不一样,因为一旦SKScene被呈现在SKView ,这个最后一个方法将被调用。