I've been playing around with swift and have been trying to make a tile based game with a scrolling view so the player is central. I've manager to get it to kind of work, but I seem to be redrawing all the nodes on top of what is currently there, so after a few moves I have 1000+ nodes and the game grinds to a halt. I'm guessing I need to remove all the old nodes before drawing the new ones? I've had a look at ways to do this, like removing children, but then I end up with nothing drawn after moving.
I've included the parts that are connected to the sprite drawing below.
func placeTile2D(tile:Tile, direction:Direction, position:CGPoint) {
let tileSprite = SKSpriteNode(imageNamed: textureImage(tile, direction: direction, action: Action.Idle))
if (tile == hero.tile) {
hero.tileSprite2D = tileSprite
hero.tileSprite2D.zPosition = 1
}
tileSprite.position = position
tileSprite.anchorPoint = CGPoint(x:0,y:0)
view2D.addChild(tileSprite)
}
func placeAllTiles2D() {
let playerPosCur = playerPosition
let playerPCX: Int = (Int(playerPosCur.x))
let playerPCY: Int = (-Int(playerPosCur.y))
var w = 1
var h = 1
for i in (playerPCY - 4) ..< (playerPCY + 4){
let row = tiles[i];
w = 1
for j in playerPCX - 4 ..< playerPCX + 4 {
let tile = Tile(rawValue: row[j].0)!
let direction = Direction(rawValue: row[j].1)!
let point = CGPoint(x: (w*tileSize.width), y: -(h*tileSize.height))
if w == 5 {
if h == 5 {
self.placeTile2D(Tile.Player, direction: .n, position: point)
}
}
w = w + 1
placeTile2D(tile, direction : direction, position : point)
}
h = h + 1
}
}
is what I'm using to draw the tiles around the player, and then below if what I'm using to change the player position and then call the placeAllTiles2D() function to redraw based on the new position.
override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
if let touch = touches.first {
let location = touch.locationInNode(view2D)
let touchPos2D = location
let moveXR = CGPoint(x:1,y:0)
let moveXL = CGPoint(x:-1,y:0)
let moveYU = CGPoint(x:0,y:1)
let moveYD = CGPoint(x:0,y:-1)
let beforeMove = playerPosition
var afterMove = CGPoint(x:0,y:0)
if touchPos2D.x > self.size.width*3/4 {
//Move player to right
afterMove = beforeMove + moveXR
}
if touchPos2D.x < self.size.width*1/4 {
//Move Player to left
afterMove = beforeMove + moveXL
}
if touchPos2D.y > -self.size.height/2 {
if touchPos2D.x < self.size.width*3/4 && touchPos2D.x > self.size.width*1/4 {
//Move PLayer Up
afterMove = beforeMove + moveYU
}
}
if touchPos2D.y < -self.size.height/2 {
if touchPos2D.x < self.size.width*3/4 && touchPos2D.x > self.size.width*1/4 {
//Move Player Down
afterMove = beforeMove + moveYD
}
}
playerPosition = afterMove
placeAllTiles2D()
}
}
Any help would be really greatly appreciated. Please be gentle, its my first go at anything swift!
You need to be using SKCameraNode
and think about it as moving the viewport around instead of spawning tiles and redrawing them every frame. Here's a good example
Basically it works like this:
var sceneCam: SKCameraNode! //declare your camera variable in your scene class
Then, in your didMoveToView
function:
sceneCam = SKCameraNode() //initialize your camera
//scaleAsPoint lets you zoom the camera in and out
sceneCam.scaleAsPoint = CGPoint(x: 0.25, y: 0.25)
camera = sceneCam //set the scene's camera
addChild(sceneCam) //add camera to scene
//position the camera on the gamescene.
sceneCam.position = CGPoint(x: frame.center.x, y: frame.center.y)
Now, when you move your player around, just set the camera to the same position as the player, and you'll have your scrolling scene. I agree with the comments. You're going to have a much better time at this if you review some of the fundamentals of sprite kit - learn about all the stuff it comes with, and you can avoid overlooking things like SKCameraNode
. There are a lot of things SpriteKit does for you, like this camera concept, to help make games quickly and easily.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With