How to create an explosion effect using a set of image sprite frames

So, I created this game where you have to shoot objects. I now have a set of images that replicates the explosion of an object. I would like these images to be displayed in sequence, so it looks like an explosion after the projectile hits the object. Obviously, the images should be called at the exact location where the projectile hits the object. Does anyone know how to do this? Here's the code.

func projectileDidCollideWithMonster(projectile:SKSpriteNode, monster:SKSpriteNode) {
    projectile.removeFromParent()
    monster.removeFromParent()

    playerScore = playerScore + 1
    playerScoreUpdate()

    if (playerScore > 100) {
        let reveal = SKTransition.crossFadeWithDuration(0.3)
        let gameOverScene = GameOverScene(size: self.size, won: true)
        self.view?.presentScene(gameOverScene, transition: reveal)
    }

}

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 & UInt32(laserCategory)) != 0 && (secondBody.categoryBitMask & UInt32(monsterCategory)) != 0 {
        projectileDidCollideWithMonster(firstBody.node as SKSpriteNode, monster: secondBody.node as SKSpriteNode)
    }
    if playerScore > highScore() {
        saveHighScore(playerScore)
        println("New Highscore = " + highScore().description)
        highScoreLabel.text = "Best score: \(highScore().description)"
    } else {
        println("HighScore = " + highScore().description )  // "HighScore = 100"
    }
}


override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
    for touch: AnyObject in touches {
        let location = touch.locationInNode(self)
        let node = self.nodeAtPoint(location)

        if node.name == "muteSound" {
            if musicIsPlaying == true {
                backgroundMusicPlayer.stop()
                musicIsPlaying = false
            } else if musicIsPlaying == false {
                backgroundMusicPlayer.play()
                musicIsPlaying = true
            }
        } else {
            let touch = touches.anyObject() as UITouch
            let touchLocation = touch.locationInNode(self)

            let projectile = SKSpriteNode(imageNamed: "boom")
            projectile.setScale(0.6)
            projectile.position = player.position
            projectile.physicsBody = SKPhysicsBody(circleOfRadius: projectile.size.width/2)
            projectile.physicsBody?.dynamic = true
            projectile.physicsBody?.categoryBitMask = UInt32(laserCategory)
            projectile.physicsBody?.contactTestBitMask = UInt32(monsterCategory)
            projectile.physicsBody?.collisionBitMask = 0
            projectile.physicsBody?.usesPreciseCollisionDetection = true
            // 3 - Determine offset of location to projectile
            let offset = touchLocation - projectile.position
            // 4 - Bail out if you are shooting down or backwards
            if (offset.y < 0) { return }
            // 5 - OK to add now - you've double checked position
            addChild(projectile)
            // 6 - Get the direction of where to shoot
            let direction = offset.normalized()
            // 7 - Make it shoot far enough to be guaranteed off screen
            let shootAmount = direction * 1000
            // 8 - Add the shoot amount to the current position
            let realDest = shootAmount + projectile.position
            // 9 - Create the actions
            let actionMove = SKAction.moveTo(realDest, duration: 2.0)
            let actionMoveDone = SKAction.removeFromParent()

            if !isStarted {
                start()
            }else{
                projectile.runAction(SKAction.sequence([actionMove, actionMoveDone]))

            }
        }
    }
}

func addMonster() {
    let monster = SKSpriteNode(imageNamed: "box")
    monster.setScale(0.6)
    monster.physicsBody = SKPhysicsBody(rectangleOfSize: monster.size)
    monster.physicsBody?.dynamic = true
    monster.physicsBody?.categoryBitMask = UInt32(monsterCategory)
    monster.physicsBody?.contactTestBitMask = UInt32(laserCategory)
    monster.physicsBody?.collisionBitMask = 0
    monster.name = "box"

    var random : CGFloat = CGFloat(arc4random_uniform(320))
    monster.position = CGPointMake(random, self.frame.size.height + 10)
    self.addChild(monster)
}

      

+3


source to share


1 answer


For an explosion, you can create SKSpriteNode

one that plays back the frames you specified:

1. You need images as an array SKTexture

s. You said that you have images in a set of images, so the easiest way is to create an array using a loop for

like:

// I don't know how many images you've got, so I'll use 10.
var textures: [SKTexture] = []
for i in 0..<10 {
    let imageName = "explosion\(i)"
    textures.append(SKTexture(imageNamed: imageName))
}

      

Alternatively, what I would recommend is to create a Texture Atlas of your images. (For more information on texture atlases, see here ). To create an atlas, create a folder with an extension .atlas

and add all your explosion images to it. (Then add this to your project). Here's an extension I wrote to get sprites from the texture atlas ready to animate:

extension SKTextureAtlas {
    func textureArray() -> [SKTexture] {
        var textureNames = self.textureNames as! [String]

        // They need to be sorted because there not guarantee the
        // textures will be in the correct order.
        textureNames.sort { $0 < $1 }
        return textureNames.map { SKTexture(imageNamed: $0) }
    }
}

      

And here's how to use it:



let atlas = SKTextureAtlas(named: "MyAtlas")
let textures = atlas.textureArray()

      

2. Now you have your textures to create SKSpriteNode

and animate it:

let explosion = SKSpriteNode(texture: textures[0])

let timePerFrame = // this is specific to your animation.
let animationAction = SKAction.animateWithTextures(textures, timePerFrame: timePerFrame)
explosion.runAction(animationAction)

      

3. Add the sprite to your scene and place it correctly. To add it to the desired location, you can use the variable contactPoint

on SKPhysicsContact

, after checking that the projectile hit the object.

func didBeginContact(contact: SKPhysicsContact) {
    // Other stuff...

    explosion.position = contact.contactPoint
    self.addChild(explosion)
}

      

Hope it helps!

+2


source







All Articles