user5278889
user5278889

Reputation:

Can’t run SKAction.runBlock in a Subclass

I am new to Swift but I am having trouble with classes and inheritance. I have a class called Bunny which holds some code including an SKAction. When I place the code found in Bunny into my GameScene class, it works fine, however, when I try running it, while it is in the Bunny class, from my GameScene class it does not work.

Here is the Bunny class:

import SpriteKit

class Bunny : SKSpriteNode {
    var bunny = SKSpriteNode()
    var moveAndRemove = SKAction()
    var textureAtlas = SKTextureAtlas()
    var textureArray = [SKTexture]()

    func spawnBunnies() {
        let spawn = SKAction.runBlock({
            () in
                self.spawnBunny()
                print("CALLEDBunniesSpawned") // THIS PART IS NOT GETTING CALLED
            })
        let delay = SKAction.waitForDuration(3)
        let spawnDelay = SKAction.sequence([spawn, delay])
        let spawnDelayForever = SKAction.repeatActionForever(spawnDelay)
        self.runAction(spawnDelayForever)
        let distance = CGFloat(self.frame.width + bunny.frame.width)
        let movePipes = SKAction.moveByX(-distance - 200, y: 0, duration: NSTimeInterval(0.009 * distance)) // Speed up pipes
        let removePipes = SKAction.removeFromParent()
        moveAndRemove = SKAction.sequence([movePipes, removePipes])
        print("BunniesSpawned") // THIS PART HERE RUNS
    }

    func spawnBunny() { // I NEED TO TRIGGER THIS PART VIA THE SPAWN = SKAction.runBlock
        print("BunniesSpawned2")
        let randomYGen = CGFloat(arc4random_uniform(UInt32(self.frame.height - 80)))
        textureAtlas = SKTextureAtlas(named: "Bunnies")
        for i in 1...textureAtlas.textureNames.count {
            var name = "Bunny\(i).png"
            textureArray.append(SKTexture(imageNamed: name))
        }
        bunny = SKSpriteNode(imageNamed: textureAtlas.textureNames[5] as! String)
        bunny.position = CGPoint(x: self.frame.width + bunny.frame.width / 2, y: randomYGen)
        bunny.setScale(0.5)
        bunny.runAction(moveAndRemove)
        self.addChild(bunny)
        bunny.runAction(SKAction.repeatActionForever(SKAction.animateWithTextures(textureArray, timePerFrame: 0.1)))
    }
}

Here is my GameScene class where I am trying to call the function from Bunny:

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
   /* Called when a touch begins */
    if gameStarted == false {
        gameStarted = true

        var bun = Bunny()
        bun.spawnBunnies()

    } else {

    }

Upvotes: 1

Views: 128

Answers (2)

Dion Larson
Dion Larson

Reputation: 868

As crashoverride777 said, the original Bunny you created in your touchesBegan is never added to the scene. If it is not part of a scene, it will never run any of the actions you are setting up.

var bun = Bunny()
self.addChild(bun)
bun.spawnBunnies()

Additionally, in spawnBunnies you are adding the newly spawned Bunny as a child of the Bunny that is spawning it. This bunny gets removed from the scene so the newly spawned bunny (which is it's child) also get's removed.

self.addChild(bunny) should be parent?.addChild(bunny). It might also need to be moved above the line bunny.runAction(moveAndRemove).

Upvotes: 1

crashoverride777
crashoverride777

Reputation: 10664

Unless I am missing something you are not adding the Bunny subclass to the scene.

Try this

 var bun = Bunny()
 addChild(bun)
 bun.spawnBunnies()

Upvotes: 0

Related Questions