Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Basic swift/spritekit game - trouble redrawing

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!

like image 767
James Avatar asked Oct 19 '22 15:10

James


1 Answers

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.

like image 94
Chris Slowik Avatar answered Oct 29 '22 22:10

Chris Slowik