Swift - 多层无缝循环滚动背景(SpriteKit游戏开发)
在游戏开发中,比如跑酷游戏。我们需要实现背景的无限循环滚动,来营造运动的效果。除了单层的背景滚动,还有视差滚动。

主场景类 GameScene.swift
源码下载:
DynamicBg.zip
视差滚动是指让多层背景以不同的速度移动,形成立体的效果,从而带来非常出色的视觉体验。
样例说明:
1,本样例背景分为两层。第一层更靠近游戏窗口的色彩更鲜艳,移动速度也更快一些。第二层由于要模拟远处的场景,所以颜色也更淡一些,对比度更弱一些,移动速度也更慢一些。
2,要实现循环滚动。我们准备的背景图首尾是要可以无缝衔接的。
3,判断需要多少张无缝衔接图来组成背景?判断标准是:当第一张图移出屏幕外,剩下的图在x轴方向上还能够填满游戏屏幕就够了。(本例远景需要拼三种同样的无缝图,近景由两张同样的无缝图衔接成)
运行效果:

样例代码:
背景类 BackGround.swift
import SpriteKit
class BackGround :SKNode {
//近处背景数组
var arrBG = [SKSpriteNode]()
//远处背景数组
var arrFar = [SKSpriteNode]()
override init() {
super.init()
//获取远处背景的纹理
var farTexture = SKTexture(imageNamed: "background_f1")
//远处背景由3章无缝图衔接而成
var farBg0 = SKSpriteNode(texture: farTexture)
farBg0.anchorPoint = CGPointMake(0, 0)
farBg0.zPosition = 9
farBg0.position.y = 150
var farBg1 = SKSpriteNode(texture: farTexture)
farBg1.anchorPoint = CGPointMake(0, 0)
farBg1.zPosition = 9
farBg1.position.x = farBg0.frame.width
farBg1.position.y = farBg0.position.y
var farBg2 = SKSpriteNode(texture: farTexture)
farBg2.anchorPoint = CGPointMake(0, 0)
farBg2.zPosition = 9
farBg2.position.x = farBg0.frame.width * 2
farBg2.position.y = farBg0.position.y
self.addChild(farBg0)
self.addChild(farBg1)
self.addChild(farBg2)
arrFar.append(farBg0)
arrFar.append(farBg1)
arrFar.append(farBg2)
//近处背景纹理
var texture = SKTexture(imageNamed: "background_f0")
//近处背景由2章无缝衔接图组成
var bg0 = SKSpriteNode(texture: texture)
bg0.anchorPoint = CGPointMake(0, 0)
var bg1 = SKSpriteNode(texture: texture)
bg1.anchorPoint = CGPointMake(0, 0)
bg1.position.x = bg0.frame.width
bg0.zPosition = 10
bg1.zPosition = 10
bg0.position.y = 70
bg1.position.y = bg0.position.y
self.addChild(bg0)
self.addChild(bg1)
arrBG.append(bg0)
arrBG.append(bg1)
}
required init(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
//移动方法
func move(speed:CGFloat){
//通过遍历获取背景,然后做x方向的改变
for bg in arrBG {
bg.position.x -= speed
}
//循环滚动算法
if arrBG[0].position.x + arrBG[0].frame.width < speed {
arrBG[0].position.x = 0
arrBG[1].position.x = arrBG[0].frame.width
}
//远景同上
for far in arrFar {
far.position.x -= speed/4
}
if arrFar[0].position.x + arrFar[0].frame.width < speed/4 {
arrFar[0].position.x = 0
arrFar[1].position.x = arrFar[0].frame.width
arrFar[2].position.x = arrFar[0].frame.width * 2
}
}
}
主场景类 GameScene.swift
import SpriteKit
class GameScene: SKScene {
lazy var bg = BackGround()
//背景移动速度
var bgMoveSpeed:CGFloat = 3
override func didMoveToView(view: SKView) {
//场景的背景颜色
let skyColor = SKColor(red:113/255,green:197/255,blue:207/255,alpha:1)
self.backgroundColor = skyColor
//设置背景
self.addChild(bg)
}
override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
}
override func update(currentTime: CFTimeInterval) {
bg.move(bgMoveSpeed/5)
}
}
源码下载:
