簡體   English   中英

SpriteKit支持多種設備方向

[英]SpriteKit support multiple device orientations

我有一個SpriteKit游戲,我想支持所有方向。 現在當我改變方向時,節點不會保持其位置。 我使用SKSceneScaleModeResizeFill進行縮放,因為它將保持正確的精靈大小。

當我開始游戲時,游戲玩家就像這樣定位在中間屏幕:

在此輸入圖像描述

然后當我旋轉設備時,位置變為如下:

在此輸入圖像描述

這是我的視圖控制器代碼:

- (void)viewDidLayoutSubviews
{
    [super viewDidLayoutSubviews];
    // Configure the view.
    SKView * skView = (SKView *)self.view;
    if (!skView.scene) {

        // Create and configure the scene.
        SKScene * scene = [MyScene sceneWithSize:skView.bounds.size];
        scene.scaleMode = SKSceneScaleModeResizeFill;

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

我的場景代碼:

-(id)initWithSize:(CGSize)size {    
    if (self = [super initWithSize:size]) {

        self.backgroundColor = [SKColor colorWithRed:0.15 green:0.15 blue:0.3 alpha:1.0];

        //Add spaceship in the center of the view
        SKSpriteNode *spaceship = [SKSpriteNode spriteNodeWithImageNamed:@"Spaceship.png"];
        spaceship.position = CGPointMake(size.width/2, size.height/2);
        [spaceship setScale:.3];
        [self addChild:spaceship];

    }
    return self;
}

在場景調整大小后,您的精靈保持其位置 - 您可以從屏幕截圖中看到它與場景左下角保持相同的水平和垂直距離。 問題是,在場景調整大小后,該絕對偏移表示場景中的不同相對位置。

Sprite Kit可以自動調整場景大小,但是場景調整大小后節點的相對位置不是它可以為你做的事情。 對於如何以不同大小重新排列場景內容沒有“正確答案”,因為場景內容的排列是您的應用定義的內容。

在你的SKScene子類中實現didChangeSize:並在SKScene放置你想要的任何邏輯來移動你的節點。

例如,您可以使用它來使節點將其位置保持為場景大小的相對比例,使用如下所示:

- (void)didChangeSize:(CGSize)oldSize {
    for (SKNode *node in self.children) {
        CGPoint newPosition;
        newPosition.x = node.position.x / oldSize.width * self.frame.size.width;
        newPosition.y = node.position.y / oldSize.height * self.frame.size.height;
        node.position = newPosition;
    }
}

根據您場景中的內容以及您的安排,您可能不希望這樣。 例如,如果您在游戲場景的每個角落都有HUD元素,則可能需要它們與角落的固定偏移量,而不是場景大小的一部分。

我添加了類似的問題並發現了這個問題。 我解決的方式不同,使用viewWillTransitionToSize:withTransitionCoordinator:由@GOR說這里

我在視圖控制器中添加了以下代碼(管理SKView及其SKScene)

- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
{
    //skView is my SKView object, with scaleMode SKSceneScaleModeResizeFill
    skView.frame = CGRectMake(0, 0, size.width, size.height);

    //currentScene is my SKScene object
    currentScene.size = skView.frame.size;

    //Then, as all the objects in my scene are children of a unique SKNode* background, I only relocate it 
    currentScene.background.position = CGPointMake(CGRectGetMidX(currentScene.frame), CGRectGetMidY(currentScene.frame));
}

它就像一個魅力!

對於Swift 3,

override func didChangeSize(_ oldSize: CGSize) {
    for node in self.children{
        let newPosition = CGPoint(x:node.position.x / oldSize.width * self.frame.size.width,y:node.position.y / oldSize.height * self.frame.size.height)
        node.position = newPosition
    }
}

因此,我們可以使用常量並在一行中初始化它。 然后在node.position = newPosition我們可以設置新位置。
此外,我們還可以使用增強的for循環,從而實現更優雅的解決方案。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM