Original: Swift language Combat Promotion-9th chapter game-Parkour Panda-9-10 remove platform with parallax scrolling
9.9 removing platforms outside the scene
Use as a platform is a steady stream of production, if you do not pay attention to destruction, the platform will accumulate more, although in the game scene can not see. Dozens of can not see the problem, the tens of thousands of of them? Millions of of them?
So let's see how to remove the platform, what kind of platform needs to be removed? And how to remove it? As we have said before, when the platform completely removes the game scene, it can be removed. You need to do two operations, 1 are removed from the Platform factory class, and 2 are removed from the platform array.
And, because the platform is one after the other, we don't need to traverse the platform array every time to make a judgment on each platform. You just need to do this test on the leftmost and first platform. This test is best suited for the Move method.
func move (speed: CGFloat) {
// traverse all
for p in platforms {
// Animation of x coordinate change
p.position.x-= speed
}
// Remove platform
if platforms [0] .position.x <-platforms [0] .width {
platforms [0] .removeFromParent ()
platforms.removeAtIndex (0)
}
}
9.10 Parallax Scrolling Background
What is parallax scrolling? It refers to allowing multi-layered backgrounds to move at different speeds, creating a three-dimensional movement that results in a very good visual experience.
And our game is also used in this technology. Such as:
In the game of Parkour Panda, our background is divided into two layers. The first layer is closer to the game window and the colors are more vivid and move faster. The second layer is to simulate a distant scene, so the color is lighter, the contrast is weaker, and the movement speed is slower.
So, in our code, we can use the moving speed movespeed defined in the Gamescene to give the value of the movespeed of the first layer background 1/5 to the Moveseed value of the second layer background 1/20. This creates a rolling inspection.
After the parallax scrolling, we also need to understand a cyclic scrolling algorithm. Because we can't create a new background like a platform. We're going to do this with a loop-rolling algorithm.
First of all, our background images can be seamlessly bridged. So how many seamless graphs do you need to make up the background? The criterion is: When the first picture is removed from the screen, the rest of the graph can fill the game screen in the x-axis direction. See:
In a situation like this, only two background images are required. So we're going to use two seamless background graphs to illustrate what a circular scroll is. Is the initial situation:
When moving to the position of figure 9-17, jump directly to the position of Figure 9-18, and then continue to move to the left to form a circular scroll. As we can see, when we jump back, in the game scene, the background is visually unchanged, but it has actually started a new scroll.
The principle is complete, let's look at the specific code. We create a new background class with the class name background, inherited from Sknode.
In the background class we define two arrays, one to store the close-up, and the other to store the vision:
// Close background array
ar arrBG = [SKSpriteNode] ()
// Distant background array
var arrFar = [SKSpriteNode] ()
We are building the code in the method init to generate the background. Because the vision picture is relatively small, you need to complete the circular scrolling to 3 images.
The algorithm for cyclic scrolling is unloaded in the Move method, and the Move method, like the Move method of the Platform factory class, receives a parameter that represents speed, which is 1/5 of movespeed in Gamescene. Because the vision speed moves more slowly, its x-coordinate change value is One-fourth of the close-up.
Look at the full code:
import SpriteKit
class BackGround: SKNode {
// Close background array
var arrBG = [SKSpriteNode] ()
// distant background array
var arrFar = [SKSpriteNode] ()
override init () {
super.init ()
// Get the texture of the distant background
var farTexture = SKTexture (imageNamed: "background_f1")
// The distant background is made up of 3 chapters seamless map
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)
// Close background texture
var texture = SKTexture (imageNamed: "background_f0")
// The background is composed of 2 seamless chapters
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")
}
// moving method
func move (speed: CGFloat) {
// Get the background by traversing, and then change the x direction
for bg in arrBG {
bg.position.x-= speed
}
// Circular scrolling algorithm
if arrBG [0] .position.x + arrBG [0] .frame.width <speed {
arrBG [0] .position.x = 0
arrBG [1] .position.x = arrBG [0] .frame.width
}
// Vision is the same as above
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
}
}
}
Ping Tai Factory class like the Panda class, we need to declare a BG variable in Gamescene.
lazy var bg = BackGround ()
Then load it in the Didmovetoview method, which is a little earlier than the panda Panda.
Self.addchild (BG)
Background scrolling also needs to be implemented in the Gamescene update
Bg.move (MOVESPEED/5)
Now that the gamescene has changed a lot, let's take a look at the complete code:
import SpriteKit
class GameScene: SKScene, ProtocolMainScene {
lazy var panda = Panda ()
lazy var platformFactory = PlatformFactory ()
lazy var bg = BackGround ()
//Moving speed
var moveSpeed: CGFloat = 15
// Judge how far away the last platform is to fully enter the game scene
var lastDis: CGFloat = 0.0
override func didMoveToView (view: SKView) {
// The background color of the scene
let skyColor = SKColor (red: 113/255, green: 197/255, blue: 207/255, alpha: 1)
self.backgroundColor = skyColor
// Set the background
self.addChild (bg)
// Give panda an initial position
panda.position = CGPointMake (200, 400)
// Show the panda in the scene
self.addChild (panda)
// Add the platform factory to the view
self.addChild (platformFactory)
// Pass the width of the screen to the platform factory class
platformFactory.sceneWidth = self.frame.width
// Set proxy
platformFactory.delegate = self
}
override func touchesBegan (touches: NSSet, withEvent event: UIEvent) {
// Play the jump action when the panda status is running
if panda.status == Status.run {
panda.jump ()
} else if panda.status == Status.jump {
// When the status is jump, perform scrolling drawing
panda.roll ()
}
}
override func update (currentTime: CFTimeInterval) {
lastDis-= moveSpeed
if lastDis <= 0 {
println ("Generating a New Platform")
platformFactory.createPlatformRandom ()
}
platformFactory.move (self.moveSpeed)
bg.move (moveSpeed / 5)
}
func onGetData (dist: CGFloat) {
self.lastDis = dist
}
}
Finally, let's run it and see how it works. Well, everything is perfect. Wait, there seems to be something wrong with the platform, running behind the background.
Well, by examining the code we found that the background is set to Zposition, the value is 9, 10. This property determines the rendering order. The smaller the first render, the smaller the more in the back. Then the solution to this bug is simple. As long as the platform in the position set a larger, such as 20, can be solved.
So we switch to the platform class and add a sentence to the last line of the OnCreate method:
Self.zposition = 20
Run again, this time normal.
My public number.
I wrote a book: "Swift language Combat Promotion" http://item.jd.com/11641501.html
Swift language Combat Promotion-9th chapter game-Parkour panda-9-10 removal platform with parallax scrolling