I want to Create a endless scrolling background for my spritekit game, iT should consist of one or two images probably, which repeat themselves? I found these one and two exampl
I found a way to do this, somehow i managed to convert this obj. C to swift
You have to declare the two node's publicly
let background1 = SKSpriteNode(imageNamed: "bg1")
let background2 = SKSpriteNode(imageNamed: "bg2")
In the "didMoveToView" method
background1.anchorPoint = CGPointZero
background1.position = CGPointMake(0, 0)
background1.zPosition = -15
self.addChild(background1)
background2.anchorPoint = CGPointZero
background2.position = CGPointMake(0, background1.size.height - 1)
background2.zPosition = -15
self.addChild(background2)
And in the "override func update(currentTime: CFTimeInterval)" method you add
background1.position = CGPointMake(background1.position.x, background1.position.y - 2)
background2.position = CGPointMake(background2.position.x, background2.position.y - 2)
if(background1.position.y < -background1.size.height)
{
background1.position = CGPointMake(background2.position.x, background1.position.y + background2.size.height )
}
if(background2.position.y < -background2.size.height)
{
background2.position = CGPointMake(background1.position.x, background2.position.y + background1.size.height)
}
i don't know if it's the most efficient way of doing this. The other questions mentioned a For loop. But this is easier in my opinion.
You don´t need all that.
Just use this function with the vars that you declared and the attributes that you used in didMoveToView.
func backgroudScrollUpdate(){
background1.position = CGPointMake(background1.position.x, background1.position.y - 1)
background2.position = CGPointMake(background1.position.x, background2.position.y - 1)
if background1.position.y == -UIScreen.mainScreen().bounds.height{
background1.position = CGPointMake(0, 0)
background2.position = CGPointMake(0, 0 + UIScreen.mainScreen().bounds.height)
}
}
Then just call it in your update method.
Of course, it is not the best way since it is readable for two images, when you have more go for a loop.
I know this is late to the game, but I found how to do this horizontally as well!
Starting off with Egghead's code (Excellent work!) I modified some things:
let background1 = SKSpriteNode(imageNamed: "Street_Example")
let background2 = SKSpriteNode(imageNamed: "Street_Example")
Also:
background1.position = CGPoint(x: frame.size.width / 2, y:frame.size.height / 2)
background1.size = CGSize(width: frame.width, height: frame.height)
background1.anchorPoint = CGPointZero
background1.position = CGPointMake(0, 0)
background1.zPosition = -15
self.addChild(background1)
background2.size = CGSize(width: frame.width, height: frame.height)
background2.anchorPoint = CGPointZero
background2.position = CGPointMake(background1.size.width - 1,0)
background2.zPosition = -15
self.addChild(background2)
And to update the position of the background:
background1.position = CGPointMake(background1.position.x-2, background1.position.y)
background2.position = CGPointMake(background2.position.x-2, background2.position.y)
if(background1.position.x < -background1.size.width)
{
background1.position = CGPointMake(background1.position.x + background2.size.width , background2.position.y)
}
if(background2.position.x < -background2.size.width)
{
background2.position = CGPointMake(background2.position.x + background1.size.height, background1.position.y)
}
I've made a class for that. Currently it's written for Swift 5.0 or 4.2, and it supports top, bottom, left and right directions.
Check it out and see if it helps you, it's called InfiniteScrollingBackground: https://github.com/ThiagoAM/InfiniteScrollingBackground
Here what I came up with:
func terrain() -> SKNode {
let color = UIColor.init(red: randomColorChannel(), green: randomColorChannel(), blue: randomColorChannel(), alpha: 1.0)
let scale: CGFloat = 1.0// UIScreen.mainScreen().scale
let size = CGSizeMake(frame.size.width * scale, frame.size.height * scale)
let node = SKSpriteNode.init(color: color, size: size)
node.anchorPoint = CGPointZero
node.position = CGPointMake(0, UIScreen.mainScreen().bounds.size.height)
return node
}
And in update do this:
override func update(currentTime: NSTimeInterval) {
var newPosition1 = terrain1.position
var newPosition2 = terrain2.position
newPosition1.y -= terrainSpeed
if newPosition1.y < 0 {
newPosition2.y -= terrainSpeed
}
terrain1.position = newPosition1
terrain2.position = newPosition2
if terrain1.position.y <= -UIScreen.mainScreen().bounds.size.height {
removeChildrenInArray([terrain1])
terrain1 = terrain()
addChild(terrain1)
}
if terrain2.position.y <= -UIScreen.mainScreen().bounds.size.height {
removeChildrenInArray([terrain2])
terrain2 = terrain()
addChild(terrain2)
}
}
So basically, terrain is placed above the view, and then they start moving down, and replaced by new ones when needed, to repeat.
func backgroudScrollUpdate(){
BG .position = CGPoint(x: BG.position.x - 5, y: BG.position.y)
BG2.position = CGPoint(x: BG2.position.x - 5, y: BG2.position.y)
if BG2.position.x <= -self.frame.size.width {
BG.position = CGPoint(x: self.frame.size.width, y: 0)
}
if BG.position.x <= -self.frame.size.width {
BG2.position = CGPoint(x: self.frame.size.width, y: 0)
}
}
-UPDATED FOR SWIFT 3.1-
this is what I always use to make it work for the Y axis just switch all the extra stuff in the X positions to the Y positions