Search code examples
iosswifttexturesspritegame-physics

Change image when collision Detected in swift?


i am making a simple game as a project and need to change my 'bird image' when it collides with another 'image'

Now i have the collision detection all set up i just need to change the texture of my 'bird image' to my new image

any tips on how to do this? I'm new to programming thought it would be easy but evidently not...

i have tried changing

var birdTexture = SKTexture(imageNamed: "bird_img_1.png") // global variable

to

birdTexture = SKTexture(imageNamed: "bird_img_dead.png") // this is inside collision detection

GameScene Class:-

import SpriteKit
  class GameScene: SKScene, SKPhysicsContactDelegate {

    var bg = SKSpriteNode()             // Create Background
    var bird = SKSpriteNode()           // Create User Bird
    var scoreLabel = SKLabelNode()      // Create Score Label
    var score: Int = 0                  // Create Score Integer
    var enemyBird = SKSpriteNode()      // Create Enemy Bird

    var birdGroup:UInt32 = 1            // Bird Collision Group
    var objectGroup:UInt32 = 2          // Enemy Collision Group
    var scoreGroup:UInt32 = 3           // Score Collision Group
    var gameOver = 0                    // Game Over function
    var movingObjects = SKNode()        // ??
    var scoreTimer = NSTimer()          // Create Score Timer
    var gameOverLabel = SKLabelNode()   // Game over label
    var labelHolder = SKSpriteNode()    // Holds Label - Game Over
    var enemySpawnTimer = NSTimer()     // Starts Enemy Spawner
    var Menu = 0


    /* Put Bird in and animate */
    var birdTexture = SKTexture(imageNamed: "bird_img_1.png")
    var birdTexture2 = SKTexture(imageNamed: "bird_img_2.png")
    var birdTexture3 = SKTexture(imageNamed: "bird_img_3.png")
    var birdTexture4 = SKTexture(imageNamed: "bird_img_4.png")

    var birdDeadTexture = SKTexture(imageNamed: "bird_img_dead.png")



    /* ------------------------------------ Main Setup ------------------------------------------ */


    override func didMoveToView(view: SKView) {
        /* Setup your scene here */

        println("Moved to Game Scene")


        movingObjects.speed = 0




        /* Background Image setup */
        backgroundImage()




        /* Set up deletates and physics and timer */
        self.physicsWorld.contactDelegate = self
        self.physicsWorld.gravity = CGVectorMake(0, -5)
        self.addChild(movingObjects)
        self.addChild(labelHolder)


        /*  Load Score Text */

        scoreLabel.fontName = "Helvetica"
        scoreLabel.fontSize = 60
        scoreLabel.text = "0"
        scoreLabel.position = CGPoint(x: CGRectGetMidX(self.frame), y: CGRectGetMidY(self.frame)+self.frame.size.height*0.3)
        self.addChild(scoreLabel)

        bird = SKSpriteNode(texture: birdTexture)
        bird.position = CGPoint(x: CGRectGetMidX(self.frame), y: CGRectGetMidY(self.frame))
        // Make bird smaller
        bird.size.height = bird.size.width/12
        bird.size.width = bird.size.width/12
        // Animate Bird
        var animation = SKAction.animateWithTextures([birdTexture, birdTexture2, birdTexture3, birdTexture4], timePerFrame: 0.08)
        var makeBirdFlap = SKAction.repeatActionForever(animation)
        bird.runAction(makeBirdFlap)
        // Load Physics
        // birdPhysics()
        // Run bird animation
        bird.zPosition = 10
        self.addChild(bird)

        /* Introduce ground and top into the scene */
        // Create Ground
        var ground = SKSpriteNode()
        ground.position = CGPointMake(CGRectGetMidX(self.frame), self.frame.size.height/100 * 16)
        ground.physicsBody = SKPhysicsBody(rectangleOfSize: CGSizeMake(self.frame.size.width, 1))
        ground.physicsBody?.dynamic = false
        ground.physicsBody?.categoryBitMask = objectGroup
        // Add Ground to scene
        self.addChild(ground)

        // Create Top
        var top = SKSpriteNode()
        top.position = CGPointMake(0, self.frame.size.height)
        top.physicsBody = SKPhysicsBody(rectangleOfSize: CGSizeMake(self.frame.size.width, 1))
        top.physicsBody?.dynamic = false
        top.physicsBody?.categoryBitMask = objectGroup
        // Add Top to scene
        self.addChild(top)
    }

    /* ------------------------------------ Spawning Enemy Birds ------------------------------------------ */
    /* Create and Spawn enemy birds */
    func enemySpawn() {

        let height = self.frame.size.height                             // screen height as variable
        let width = self.frame.size.width                               // screen width as variable

        var bottomBarHeight = self.frame.size.height*0.16               // bottom bar height
        var spawningPoint = height - bottomBarHeight                    // screen height - 16%

        var randSpawn = arc4random_uniform(UInt32(spawningPoint))       // random number between 0 and 645
        var finalSpawn = CGFloat(randSpawn) + bottomBarHeight           // add 16% (bottombarheight to the random number

        /*
        CHECK VALUES OF SPAWN
        println("\(height) is the total screen height")
        println("\(bottomBarHeight) is the pixels below the ground")
        println("\(spawningPoint) is the random range")
        println("\(randSpawn) is a random number")
        println("\(finalSpawn)  - Spawn Location")
        println(enemyBird.position)
        */





        if (enemyBird.position.y > 730) {
            enemyBird.position.y = 720
        }

        if (enemyBird.position.y < 130) {
            enemyBird.position.y = 135
        }



        // println(Int(enemyBird.position.y))


        // Create enemy bird
        var enemyBirdTexture = SKTexture(imageNamed: "enemy_img_2.png")

        enemyBird = SKSpriteNode(texture: enemyBirdTexture)
        enemyBird.position = CGPoint(x: CGRectGetMidX(self.frame)*2.5, y: finalSpawn)
        enemyBird.size.height = enemyBird.size.height/12
        enemyBird.size.width = enemyBird.size.width/12
        enemyBird.physicsBody = SKPhysicsBody(rectangleOfSize: CGSizeMake(enemyBird.size.width, enemyBird.size.height))
        enemyBird.physicsBody?.dynamic = false
        enemyBird.physicsBody?.categoryBitMask = objectGroup


        // Move enemy birds
        var moveEnemyBird = SKAction.moveByX(-self.frame.size.width * 2, y: 0, duration: NSTimeInterval(self.frame.size.width / 100))     //4.14 seconds on screen
        var removeEnemyBird = SKAction.removeFromParent()
        var moveAndRemoveEnemyBird = SKAction.sequence([moveEnemyBird, removeEnemyBird])


        // Add enemy to scene and move enemy
        enemyBird.runAction(moveEnemyBird)
        movingObjects.addChild(enemyBird)
    }
    /* ------------------------------------ Other Parts ------------------------------------------ */
    func backgroundImage() {

        /* Put Background Image In */

        // Create Background Texture
        var bgTexture = SKTexture(imageNamed: "bg.png")
        // Link bg variable to texture
        bg = SKSpriteNode(texture: bgTexture)
        // Position thr bg image
        bg.position = CGPoint(x: CGRectGetMidX(self.frame), y: self.frame.height/2)
        bg.size.height = self.frame.height

        // Move background image left
        var moveBg = SKAction.moveByX(-bgTexture.size().width, y: 0, duration: 9)
        var replaceBg = SKAction.moveByX(bgTexture.size().width, y: 0, duration: 0)
        var moveBgForever = SKAction.repeatActionForever(SKAction.sequence([moveBg, replaceBg]))

        // Keep world never ending
        for var i:CGFloat = 0; i < 3; i++ {

            // Position Background
            bg = SKSpriteNode(texture: bgTexture)
            bg.position = CGPoint(x: bgTexture.size().width/2 + bgTexture.size().width * i, y: CGRectGetMidY(self.frame))

            // Stretch background full height of screen
            bg.size.height = self.frame.height

            // Run the action to move BG
            bg.runAction(moveBgForever)

            self.addChild(bg)
        }
    }
    func startTimers() {

        /* Create Score Timer */
        //scoreTimer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector:Selector("scoreCount"), userInfo: nil, repeats: true)

        enemySpawnTimer = NSTimer.scheduledTimerWithTimeInterval(0.75, target: self, selector: Selector("enemySpawn"), userInfo: nil, repeats: true)


    }

    func birdPhysics() {
        /* Give bird physics */
        // Give bird physics
        bird.physicsBody = SKPhysicsBody(circleOfRadius: bird.size.height/3)
        bird.physicsBody?.mass = 0.2
        bird.physicsBody?.dynamic = true
        bird.physicsBody?.allowsRotation = false
        bird.physicsBody?.categoryBitMask = birdGroup
        bird.physicsBody?.collisionBitMask = objectGroup
        bird.physicsBody?.contactTestBitMask = objectGroup

    }
    func didBeginContact(contact: SKPhysicsContact) {
        if contact.bodyA.categoryBitMask == objectGroup || contact.bodyB.categoryBitMask == objectGroup {
            scoreTimer.invalidate()
            enemySpawnTimer.invalidate()
            bird = SKSpriteNode(texture: birdDeadTexture)

            if gameOver == 0 {
                movingObjects.speed = 0
                gameOver = 1
                movingObjects.removeAllChildren()// Remove all enemies
                gameOverLabel.fontName = "Helvetica"
                gameOverLabel.fontSize = 25
                gameOverLabel.text = "Tap to retry!"
                gameOverLabel.position = CGPoint(x: CGRectGetMidX(self.frame), y: CGRectGetMidY(self.frame)*1.5)
                labelHolder.addChild(gameOverLabel)
                gameOverLabel.zPosition = 9



            }
        }
    }

    override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
        /* Called when a touch begins */



        if (Menu == 0) {
            movingObjects.speed = 1
            birdPhysics()
            startTimers()
        }

        if (gameOver == 0) {                                                                            // Runs if game is not over
            bird.physicsBody?.velocity = CGVectorMake(0, 0)
            bird.physicsBody?.applyImpulse(CGVectorMake(0, 80))
            Menu = 1    // Number on right is jump height

        } else {                                                                                        // Runs if game is over
            score = 0                                                                                   // Score int is 0
            scoreLabel.text = "0"                                                                       // Score Label is 0
            bird.position = CGPoint(x: CGRectGetMidX(self.frame), y: CGRectGetMidY(self.frame))         // Position Bird in center
            bird.physicsBody?.velocity = CGVectorMake(0,0)                                              // Cannot make bird jump
            labelHolder.removeAllChildren()                                                             // Removes all labels
            gameOver = 0                                                                                // Sets game over to 0 so game will run
            movingObjects.speed = 1
            startTimers()

        }
    }

    override func update(currentTime: CFTimeInterval) {
        /* Called before each frame is rendered */
    }

}

Solution

  • You can just change the texture of the SKSpriteNode like,

    sprite.texture = newTexture
    

    Load the textures before the start of the game.

    var birdAliveTexture = SKTexture(imageNamed: "bird_img_1.png")
    var birdDeadTexture = SKTexture(imageNamed: "bird_img_dead.png")
    var bird : SKSpriteNode!
    

    When the sprite is loaded, give a name to the birdSprite.

    bird = SKSpriteNode(texture: birdAliveTexture)
    bird.name = "bird" 
    

    In didBeginContact function

     func didBeginContact(contact: SKPhysicsContact) {
        if contact.bodyA.categoryBitMask == objectGroup || contact.bodyB.categoryBitMask == objectGroup {
            scoreTimer.invalidate()
            enemySpawnTimer.invalidate()
    
            bird.removeAllActions() //changed
            bird.texture = birdDeadTexture // changed
    
            if gameOver == 0 {
                movingObjects.speed = 0
                gameOver = 1
                movingObjects.removeAllChildren()// Remove all enemies
                gameOverLabel.fontName = "Helvetica"
                gameOverLabel.fontSize = 25
                gameOverLabel.text = "Tap to retry!"
                gameOverLabel.position = CGPoint(x: CGRectGetMidX(self.frame), y: CGRectGetMidY(self.frame)*1.5)
                labelHolder.addChild(gameOverLabel)
                gameOverLabel.zPosition = 9
             }
        }
    }