ecoguy
ecoguy

Reputation: 665

Creating rain animation with physics

I'm currently working on an iOS app written in Swift using the SpriteKit game technology. In this game raindrops fall from the top of the screen down to the bottom. When they hit the bottom, which is represented by a physicsBody they should return to their original position at the top of the screen allowing the animation to continue for the lifetime of the game.

Since I only need a few drops I create them like this:

let drop = SKSpriteNode(imageNamed: "drop")
drop.position = CGPointMake(x,y)
drop.physicsBody = SKPhysicsBody(rectangleOfSize: drop.size)
addChild(drop)

Then I create the bitmasks:

drop.physicsBody!.categoryBitmask = DropCategory
bottom.physicsBody!.categoryBitmask = BottomCategory
drop.physicsBody!.contactTestBitmask = BottomCategory    

I add the didBeginContact function and I do get notified when the drop hits the bottom. Then my console displays "hit ground".

func didBeginContact(contact: SKPhysicsContact) {

    var firstBody: SKPhysicsBody
    var secondBody: SKPhysicsBody

    if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask {
        firstBody = contact.bodyA
        secondBody = contact.bodyB
    } else {
        firstBody = contact.bodyB
        secondBody = contact.bodyA
    }

    if firstBody.categoryBitMask == BlockCategory && secondBody.categoryBitMask == GroundCategory {
        println("hit ground")

        firstBody.node?.removeFromParent()
        let drop = SKSpriteNode(imageNamed: "drop")
        drop.name = "testNode"
        drop.position = CGPointMake(self.frame.width - self.frame.width/3*2, self.frame.height) // At start Position
        drop.physicsBody = SKPhysicsBody(rectangleOfSize: drop.size)
        drop.physicsBody?.categoryBitMask = BlockCategory
        drop.physicsBody?.contactTestBitMask = GroundCategory
        addChild(drop)
    }
}

However, the position of the drop doesn't change. There is no syntax error, so what's my problem?

If I replace this:

firstBody.node!.position = CGPointMake(x, y)

with this:

firstBody.applyImpulse(CGVector)

it gives the drop the impulse. How can I make the first option work as well?

Upvotes: 4

Views: 1690

Answers (1)

rakeshbs
rakeshbs

Reputation: 24572

You can try removing the node when it touches the bottom, and adding new node at the top again. Load the texture for reuse in a seperate SKTexture variable. Like this

let dropTexture = SKTexture(imageNamed: "drop.png")

use it like this

let drop = SKSpriteNode(texture: dropTexture)

Then inside didBeginContact

func didBeginContact(contact: SKPhysicsContact) {
    println("collided")
    var bodyA : SKPhysicsBody!
    var bodyB : SKPhysicsBody!

    if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask
    {
        bodyA = contact.bodyA!
        bodyB = contact.bodyB!
    }
    else
    {
        bodyB = contact.bodyA!
        bodyA = contact.bodyB!
    }

    if bodyA.categoryBitMask == bottomCategoryBitMask && bodyB.categoryBitMask == raindropCategoryBitMask
    {
        if bodyB.node?.parent != nil // Added line
        {
            bodyB.node?.removeFromParent()
            let drop = SKSpriteNode(imageNamed: "1.png")
            drop.name = "testNode"
            drop.position = CGPointMake(self.frame.width - self.frame.width/3*2, self.frame.height) // At start Position
            drop.physicsBody = SKPhysicsBody(rectangleOfSize: drop.size)
            drop.physicsBody?.categoryBitMask = raindropCategoryBitMask
            drop.physicsBody?.contactTestBitMask = bottomCategoryBitMask
            addChild(drop)
        }
    }
}

Upvotes: 2

Related Questions