【问题标题】:Change Node Positioning Depending on Screen Size Swift/Sprite Kit根据屏幕尺寸 Swift/Sprite Kit 更改节点位置
【发布时间】:2016-03-20 18:41:14
【问题描述】:

我想根据屏幕大小更改节点的位置。例如,当我在 iPhone 4s 上运行我的应用程序时,并不是所有的节点都适合屏幕,因为我在开发应用程序时考虑了 iPhone 6 的尺寸。我怎样才能使节点根据运行的设备重新定位自己?我知道我可以通过约束正常实现这一点,但我不知道如何在 Sprite Kit 中做到这一点。我在下面包含了一个屏幕截图。

    lblRocketCount.position = CGPoint(x: 100, y: 150)
    lblRocketCount.text = "Bullets: 30"
    self.addChild(lblRocketCount)

    lblMissileCount.position = CGPoint(x: -100, y: 150)
    lblMissileCount.text = "Missiles: 5"
    self.addChild(lblMissileCount)


    leftBorder.position = CGPoint(x: -333, y: 0)
    self.addChild(leftBorder)

    rightBorder.position = CGPoint(x: 333, y: 0)
    self.addChild(rightBorder)

    topBorder.position = CGPoint(x: 0, y: 187)
    self.addChild(topBorder)

    bottomBorder.position = CGPoint(x: 0, y: -187)
    self.addChild(bottomBorder)

    buttonDirUp.position = CGPoint(x: -200, y: -50)
    buttonDirUp.setScale(2.0)
    self.addChild(buttonDirUp)

    ship.setScale(0.33)
    shootButton.setScale(0.7)
    missileButton.setScale(0.5)


    buttonDirLeft.position = CGPoint(x: -250, y: -100)
    buttonDirLeft.setScale(2.0)
    self.addChild(buttonDirLeft)

    buttonDirDown.position = CGPoint(x: -200, y: -150)
    buttonDirDown.setScale(2.0)
    self.addChild(buttonDirDown)

    buttonDirRight.position = CGPoint(x: -150, y: -100)
    buttonDirRight.setScale(2.0)
    self.addChild(buttonDirRight)

    self.view?.multipleTouchEnabled = true

    self.backgroundColor = SKColor.blackColor()

    self.anchorPoint = CGPointMake(0.5, 0.5)

    self.addChild(base)
    base.position = CGPointMake(200, -100)

    self.addChild(ball)
    ball.position = base.position

    self.addChild(ship)
    ship.position = CGPoint(x: self.frame.midX, y: self.frame.midY)

    self.addChild(shootButton)
    shootButton.position = CGPoint(x: self.frame.midX, y: -100)

    self.addChild(missileButton)
    missileButton.position = CGPoint(x: -200, y: 50)

Screen Shot

【问题讨论】:

  • 只需将硬编码的绝对值更改为相对值,以屏幕宽度或高度的百分比表示。而且看起来你可以表达一些相对于其他人而不是屏幕的内容。
  • @AlfieHanssen 你能举个例子吗?
  • 我不确定我理解你的意思@AlfieHanssen
  • @AlfieHanssen 你能解释一下你的意思吗

标签: ios xcode swift sprite-kit swift2


【解决方案1】:

我发现这是一种对处理多种分辨率非常有效的技术。您需要在 GameViewController 中创建两个反映当前视图大小的全局变量:

import SpriteKit


// global variables
var SKViewSize: CGSize?
var SKViewSizeRect: CGRect?


class GameViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        let skView = self.view as! SKView
        SKViewSize = skView.bounds.size
        let scene = GameScene(size: SKViewSize!)

        scene.scaleMode = .AspectFill
        skView.presentScene(scene)
        SKViewSizeRect = getViewSizeRect()
    }

    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        SKViewSize = self.view.bounds.size
        SKViewSizeRect = getViewSizeRect()

        let skView = self.view as! SKView
        if let scene = skView.scene {
            if scene.size != self.view.bounds.size {
                scene.size = self.view.bounds.size
            }
        }
    }

    func getViewSizeRect() -> CGRect {
        return CGRect(x: ((SKViewSize!.width  * 0.5) * -1.0), y: ((SKViewSize!.height * 0.5) * -1.0), width: SKViewSize!.width, height: SKViewSize!.height)
    }
}

然后为所有SKNode 类型创建一个扩展,允许您使用当前屏幕尺寸的百分比来定位它们:

public extension SKNode {

    public func posByScreen(x: CGFloat, y: CGFloat) {
        self.position = CGPoint(x: CGFloat((SKViewSizeRect!.width * x) + SKViewSizeRect!.origin.x), y: CGFloat((SKViewSizeRect!.height * y) + SKViewSizeRect!.origin.y))
    }
}

例如,要创建一个 sprite 节点并将其置于任何屏幕尺寸的中心,您可以在 GameScene 中使用它:

let sprite = SKSpriteNode(color: SKColor.whiteColor(), size: CGSizeMake(32, 32))
addChild(sprite)
sprite.posByScreen(0.5, y: 0.5)

【讨论】:

  • 有趣。你能举个例子吗?
  • 这实际上改变了 4s 和 5 ~ 以上的游戏玩法,因为 Sprite 在 2 台设备之间的大小相同,由于 4s 上的空间较小,4s 上的碰撞会比 5s 上发生的更多
  • 我如何知道更改百分比?
【解决方案2】:

对于您要寻找的内容没有简单的答案,您首先需要确定您的游戏在不同的纵横比下应该是什么样子,并围绕它进行计划。在很多情况下,您只想为 16:9 手机提供更多 FOV(它们可以看到更多游戏世界)。为此,请使用 2 层设计您的游戏:游戏层和 hud 叠加层。

游戏层将利用 .AspectFill 使您的游戏在不同设备上保持相同的“大小”,iPhone 4s 用户将无法查看其上方和下方的某些屏幕(您可以调整他们失去某些屏幕的位置)画面通过移动游戏层节点位置)

HUD 覆盖层将处理需要在屏幕上保持固定位置的内容,例如按钮和生命条。现在您可以像某些人提到的那样使用基于 % 的坐标,或者您可以保留绝对坐标,如果您的游戏检测到 3:2(或 4:3,如果您愿意,只需添加/减去覆盖节点的像素差异) iPad) 比率

基本原则:(不要逐字逐句)

假设我们创建了一个 160x284 点的游戏场景

这意味着在 iphone 4s 上我们的分辨率是 320x480,纵横比填充将采用顶部/底部或左/右之间的最小距离并缩放到该距离。在我们的例子中,160 将缩放到 320,284 将缩放到 568。呃,哦,iphone 只有 480,所以你失去了 88 像素,这意味着在游戏世界中我们失去了 44 点。

//这意味着顶部和底部将分别损失22个点,所以让我们的iphone4s填充

class GameScene
{
  let gameNode = SKNode();
  let overlayNode = SKNode();
  let iPhone4sPadding = 22;
  func init()
  {
     //add all of the games nodes that you would add to the scene to gameNode instead
      self.addChild(gameNode);

     //add all of your overlay nodes (buttons, lifebars, etc) to the overlayNode

     //do a check on uiscreen to see if the height is 480, if it is
     //  all nodes on the bottom add iphone4spadding to the y
     //  all nodes on the top subtract iphone4spadding from the y
     self.addChild(overlayNode);

  }
}

【讨论】:

  • 我该怎么做呢?你能给我一些例子吗?我真正在寻找的是 Sprite Kit 的等效约束.....
  • 不幸的是,SpriteKit 中存在限制,据我了解,它主要用于将精灵保持在一定的范围或距离内,没有任何东西会限制在边框上。
  • 哦,不。你能给我一个使用你的策略的例子吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多