xCode 6.4 中何时将 didMoveToView 或 initWithSize 与 SpriteKit 一起使用
When to use didMoveToView or initWithSize with SpriteKit in xCode 6.4
由于xCode更新到6.0版本,"GameScene"中SpriteKit的默认方法(创建的默认场景)更改为:
-(void) didMoveToView:(SKView *) view {
/* Scene set up in here */
}
与旧方法相反:
-(id) initWithSize:(CGSize) size {
if (self = [super initWithSize:size]{
/* Scene set up in here */
}
}
我知道新方法(与视图控制器中的更改一样)用于帮助管理从 xCode6 中新增的 .sks 文件的导入。但是,我很好奇是否我不想使用新的 "storyboard" 类型格式即 .sks 文件,我是否仍应使用新方法?或者我应该将方法改回 initWithSize 方法并只删除 .sks 文件吗?
两个选项都正确。也就是说,init
方法实际上与 didMoveToView:
方法不同,因为一旦 SKScene
出现在 SKView
中,最后一个方法就会被调用。
我认为,就所有意图和目的而言,就实际设置和使用场景而言,这两种方法之间没有太大区别。 (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 方法应该用于初始化,但请记住在 init 内部,视图始终是 nil
。因此,任何需要视图的代码都必须移至 didMoveToView 方法(在视图呈现场景后立即调用)。
关于initWithSize
in Xcode 6...默认情况下,场景是从.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)
}
}
}
由于xCode更新到6.0版本,"GameScene"中SpriteKit的默认方法(创建的默认场景)更改为:
-(void) didMoveToView:(SKView *) view {
/* Scene set up in here */
}
与旧方法相反:
-(id) initWithSize:(CGSize) size {
if (self = [super initWithSize:size]{
/* Scene set up in here */
}
}
我知道新方法(与视图控制器中的更改一样)用于帮助管理从 xCode6 中新增的 .sks 文件的导入。但是,我很好奇是否我不想使用新的 "storyboard" 类型格式即 .sks 文件,我是否仍应使用新方法?或者我应该将方法改回 initWithSize 方法并只删除 .sks 文件吗?
两个选项都正确。也就是说,init
方法实际上与 didMoveToView:
方法不同,因为一旦 SKScene
出现在 SKView
中,最后一个方法就会被调用。
我认为,就所有意图和目的而言,就实际设置和使用场景而言,这两种方法之间没有太大区别。 (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 方法应该用于初始化,但请记住在 init 内部,视图始终是 nil
。因此,任何需要视图的代码都必须移至 didMoveToView 方法(在视图呈现场景后立即调用)。
关于initWithSize
in Xcode 6...默认情况下,场景是从.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)
}
}
}