更新时间:2023-02-02 13:50:57
Init 方法应该用于初始化,但请记住,在 init 内部,视图总是 nil
.因此,任何需要视图的代码都必须移动到 didMoveToView 方法(在视图呈现场景后立即调用).
Init methods should be used for initializing but keep in mind that inside init, view is always nil
. So any code that needs the view has to be moved to didMoveToView method (it's called immediately after a scene is presented by a view).
关于 Xcode 6 中的 initWithSize
... 默认情况下,场景是从 .sks 文件加载的.正因为如此, initWithSize
实际上从未被调用过.initWithCoder
被调用:
About initWithSize
in Xcode 6... By default, scene is loaded from .sks file. Because of this, initWithSize
is never called actually. initWithCoder
is called instead:
- (instancetype)initWithCoder:(NSCoder *)aDecoder
{
if (self = [super initWithCoder:aDecoder]) {
// do stuff
}
return self;
}
所以在 initWithSize
中初始化任何东西都不会产生任何影响.如果您决定删除 .sks 文件并以旧"方式创建场景,您可以在视图控制器中执行以下操作:
So initializing anything inside initWithSize
won't have any effect. If you decide to delete .sks file and create a scene in "old" way, you can do something like this in view controller:
- (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
进行初始化了.
After that, you can use initWithSize
for initialization.
请注意,在 viewDidLoad 中,视图的最终大小可能尚不清楚,而使用 viewWillLayoutSubviews
可能是正确的选择.阅读更多这里.
Note that in viewDidLoad the final size of a view may not be known yet, and using viewWillLayoutSubviews
instead could be a right choice. Read more here.
并正确实施 viewWillLayoutSubviews 用于场景初始化的目的是:
And proper implementation of viewWillLayoutSubviews for scene initialization purpose would be:
- (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)
}
}
}