且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

何时在 xCode 6.4 中将 didMoveToView 或 initWithSize 与 SpriteKit 一起使用

更新时间: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)
        }


    }
}