Swift - 在View Controller中添加Sprite Kit场景后面的背景图像

时间:2015-06-20 19:14:46

标签: ios swift uiviewcontroller sprite-kit

我正在尝试在视图控制器中添加背景图像,以便我的精灵工具包游戏场景可以在前台。当我的背景图像在游戏场景相互转换时保持在屏幕上对我来说很重要。我遇到的问题是如何将我为背景创建的子视图放在我的skscene后面,此时我的背景图像位于我的游戏场景前面,你只能看到图像sendSubviewToBack没有'似乎工作。以下是我的viewDidLoad谢谢

import UIKit
import SpriteKit

class GameViewController: UIViewController {

    override func viewDidLoad() {

        super.viewDidLoad()
        let scene = MainMenuScene(size: CGSize(width: 1536, height: 2048))
        let skView = self.view as! SKView

        scene.scaleMode = .AspectFill
        skView.presentScene(scene)

        let backgroundImageView = UIImageView(image: UIImage(named: "bg.jpg"))
        backgroundImageView.frame = view.frame
        backgroundImageView.contentMode = .ScaleAspectFill
        view.addSubview(backgroundImageView)
        view.sendSubviewToBack(backgroundImageView)

    }
}

5 个答案:

答案 0 :(得分:1)

您所描述的内容无法通过UIKit完成,因为您的视图无法在SKView后面显示,从而呈现您的场景。

在iOS 8+中,您可以使用SKView的allowsTransparency属性。文档说明:

  

此属性告诉绘图系统应如何处理   视图。如果设置为NO,则绘图系统将视图视为完全视图   不透明,允许绘图系统优化一些绘图   运营并提高绩效。如果设置为YES,则绘图系统   通常将视图与其他内容合成。默认值为   这个属性是NO。

但在我看来,这不是最好的解决方案。最好的解决方案是使用Sprite Kit,但问题是你无法跨场景保存节点。您必须在每个场景转换期间再次添加节点。这就是我不按照文档描述的方式使用Apple的场景转换的原因。相反,我使用自己的自定义SKNodes并使用这些节点进行自己的自定义转换,我强烈建议您这样做。我给出了关于here

的详细答案

答案 1 :(得分:1)

制作带有背景纹理的SKSpriteNode!

background.size = self.frame.size //Make the background as big as the screen

答案 2 :(得分:1)

我处理了同样的问题,以下是如何修复它:

  1. 将代码放在viewWillLayoutSubviews()中,而不是放在viewDidLoad()中 - 这样可以确保您可以访问所有视图的属性。
  2. 不要将self.view转换为SKView,将其保留为UIView,而是创建两个子视图:一个用于背景图像,一个用于SKScene
  3. 以下是更正后的代码:

    var skView : SKView? = nil
    
    override func viewWillLayoutSubviews() {
        super.viewWillLayoutSubviews()
    
        if (skView == nil) {
            let backgroundImageView = UIImageView(image: UIImage(named: "bg.jpg"))
            view.addSubview(backgroundImageView)
    
            skView = SKView(frame: CGRect(origin: CGPointZero, size: CGSize(width: 1536, height: 2048)))
            skView!.ignoreSiblingOrder = true
            let scene = MainMenuScene(size: CGSize(width: 1536, height: 2048))
            scene.scaleMode = .AspectFill
    
            view.addSubView(skView!)
            skView!.presentScene(scene)
        }
    }
    

    我这样做的特别原因是我可以在没有宽高比失真的情况下在iPhone和iPad上播放游戏。可玩区域'总是16:9,当在iPad上看到时,你会看到一个延伸到可播放区域两侧的背景图像。

    我所做的是加载适用于iPad的背景图像(纵横比为4:3),将skView定义为宽高比为16:9(因此我使用的是1536/2048而不是例如,750/1334)并将场景的scaleMode设置为.AspectFit。在iPhone上看时,场景完全覆盖了背景。在iPad上看到时,您可以看到背景图像与可播放区域的两侧相互补充。

    希望这有帮助!

答案 3 :(得分:0)

通常,UI元素会根据添加到视图中的顺序放在彼此之上。

如果您想自定义,可以使用属性.layer.zPosition,这是您选择的任何值。最低值在最后面,而最高值在最顶层。

希望有所帮助:)

答案 4 :(得分:0)

您可以使用insertSubView:而不是addSubView并指定索引,该索引确定视图的z顺序。索引较高的视图位于指数较低的视图之上。