【问题标题】:how to make infinite background in spriteKit swift 4如何在 spriteKit swift 4 中制作无限背景
【发布时间】:2018-03-26 20:50:44
【问题描述】:

我尝试通过节点制作一个无限的背景,但是背景没有变成无限并且被打断,第三个背景还没有显示出来。第一次演出后,场景中的节点数越来越多,如何解决?

import SpriteKit
import GameplayKit

class GameScene: SKScene {


   var bgNode: SKNode!
   var overlay: SKNode!
   var overlayWidth: CGFloat!
   //var viewSize: CGSize!
   var levelPositionX: CGFloat = 0.0
   //var speed: CGFloat = 5.5


   override func didMove(to view: SKView) {
    setupNode()
    //viewSize = CGSize(width: frame.size.width, height: 
                                                     
                                              frame.size.height )
    
  }

  func setupNode() {
    let worldNode = childNode(withName: "World")!
    bgNode = worldNode.childNode(withName: "Background")!
    overlay = bgNode.childNode(withName: "Overlay")!.copy() as! 
  SKNode
    overlayWidth = overlay.calculateAccumulatedFrame().width
  }

   func createBackgroundOverlay() {
    let backgroundOverlay = overlay.copy() as! SKNode
    backgroundOverlay.position = CGPoint(x: 0.0, y: 0.0)
    
    bgNode.addChild(backgroundOverlay)
    levelPositionX += overlayWidth
}

func update() {
    bgNode.position.x -= 5
    if bgNode.position.x <= -self.frame.size.width {
         bgNode.position.x = self.frame.size.width * 2
        createBackgroundOverlay()
        
      }
  }

  override func update(_ currentTime: TimeInterval) {
      update()
  }    

【问题讨论】:

    标签: swift3 sprite-kit skspritenode


    【解决方案1】:

    在我的无尽奔跑游戏中,我实现了与您的应用非常相似的无尽背景和地面(或地板)。下面我将讨论我在游戏中使用的步骤。

    第 1 步:在您的 GameScene.swift 文件中添加这些变量。

    var backgroundSpeed: CGFloat = 80.0 // speed may vary as you like
    var deltaTime: TimeInterval = 0
    var lastUpdateTimeInterval: TimeInterval = 0
    

    第二步:在GameScene文件中,制作setUpBackgrouds方法如下

    func setUpBackgrounds() {
        //add background
    
        for i in 0..<3 {
            // add backgrounds, my images were namely, bg-0.png, bg-1.png, bg-2.png
    
            let background = SKSpriteNode(imageNamed: "bg-\(i).png")
            background.anchorPoint = CGPoint.zero
            background.position = CGPoint(x: CGFloat(i) * size.width, y: 0.0)
            background.size = self.size
            background.zPosition = -5
            background.name = "Background"
            self.addChild(background)
    
        }
    
        for i in 0..<3 {
            // I have used one ground image, you can use 3
            let ground = SKSpriteNode(imageNamed: "Screen.png")
            ground.anchorPoint = CGPoint(x: 0, y: 0)
            ground.size = CGSize(width: self.size.width, height: ground.size.height)
            ground.position = CGPoint(x: CGFloat(i) * size.width, y: 0)
            ground.zPosition = 1
            ground.name = "ground"
            self.addChild(ground)
    
        }
    }
    

    第 3 步:现在我们必须从更新方法中捕获 timeIntervals

    override func update(_ currentTime: TimeInterval) {
        if lastUpdateTimeInterval == 0 {
            lastUpdateTimeInterval = currentTime
        }
    
        deltaTime = currentTime - lastUpdateTimeInterval
        lastUpdateTimeInterval = currentTime
    }
    

    第 4 步:这是最重要的部分,通过枚举子节点来移动我们的背景和 groungFloor。在 GameScene.swift 文件中添加这两个方法。

    func updateBackground() {
        self.enumerateChildNodes(withName: "Background") { (node, stop) in
    
            if let back = node as? SKSpriteNode {
                let move = CGPoint(x: -self.backgroundSpeed * CGFloat(self.deltaTime), y: 0)
                back.position += move
    
                if back.position.x < -back.size.width {
                    back.position += CGPoint(x: back.size.width * CGFloat(3), y: 0)
                }
            }
    
        }
    }
    
    func updateGroundMovement() {
        self.enumerateChildNodes(withName: "ground") { (node, stop) in
    
            if let back = node as? SKSpriteNode {
                let move = CGPoint(x: -self.backgroundSpeed * CGFloat(self.deltaTime), y: 0)
                back.position += move
    
                if back.position.x < -back.size.width {
                    back.position += CGPoint(x: back.size.width * CGFloat(3), y: 0)
                }
            }
    
        }
    }
    

    第 5 步: 此时您应该会在 updateBackground 和 updateGroundMovement 方法中收到此错误:“Binary operator '+=' cannot be applied to two 'CGPoint'operands”。

    现在我们需要实现运算符重载来解决这个问题。创建一个新的 Swift 文件并将其命名为 Extensions.swift ,然后实现如下:

    //  Extensions.swift
    
    import CoreGraphics
    import SpriteKit
    
    public func + (left: CGPoint, right: CGPoint) -> CGPoint {
       return CGPoint(x: left.x + right.x, y: left.y + right.y)
    }
    
    public func += (left: inout CGPoint, right: CGPoint) {
       left = left + right
    }
    

    第 6 步: 在 didMove(toView:) 中调用 setUpBackgrounds 方法

    override func didMove(to view: SKView) {
    
        setUpBackgrounds()
    
    }
    

    第 7 步: 最后调用 update(_ currentTime) 方法中的 updateBackgroundupdateGroundMovement 方法。更新代码如下:

    override func update(_ currentTime: TimeInterval) {
        if lastUpdateTimeInterval == 0 {
            lastUpdateTimeInterval = currentTime
        }
    
        deltaTime = currentTime - lastUpdateTimeInterval
        lastUpdateTimeInterval = currentTime
    
        //MARK:- Last step:- add these methods here
        updateBackground()
        updateGroundMovement()
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-07
      • 1970-01-01
      • 2014-12-08
      相关资源
      最近更新 更多