2

In my game I want an enemy to spawn every 10 seconds. I attempt to accomplish this by, in the GameViewController, writing

var secondEnemyTimer = NSTimer.scheduledTimerWithTimeInterval(10.0, target: self, selector: "secondEnemyFunction", userInfo: nil, repeats: false)

in the viewWillLayoutSubviews method. Then in the secondEnemyFunction I write:

let skView = self.view as! SKView
    let gameScene = GameScene(size: skView.bounds.size)

    gameScene.enemy2Function()

Then in the enemy2Function in the GameScene class I write:

 println("Called!")

    enemy2.name = enemyCategoryName

    enemy2.size.width = 57
    enemy2.size.height = 57

    let randomX = randomInRange(Int(CGRectGetMinX(self.frame)), hi: Int(CGRectGetMaxX(self.frame)))
    let randomY = randomInRange(Int(CGRectGetMinY(self.frame)), hi: Int(CGRectGetMaxY(self.frame)))
    let randomPoint = CGPoint(x: randomX, y: randomY)
    enemy2.position = randomPoint

    self.addChild(enemy2)

    enemy2.physicsBody = SKPhysicsBody(circleOfRadius: enemy1.size.width / 2)
    enemy2.physicsBody?.friction = 0
    enemy2.physicsBody?.restitution = 1
    enemy2.physicsBody?.linearDamping = 0
    enemy2.physicsBody?.allowsRotation = false

    enemy2.physicsBody?.applyImpulse(CGVectorMake(50, -50))

    enemy2.physicsBody?.categoryBitMask = enemyCategory

In the log "Called!" appear yet the enemy is not spawned. Just so you know I did create the enemy at the top of the class by doing:

let enemy2 = SKSpriteNode(imageNamed: "enemy")

Does anyone know how I can spawn my second enemy? Thank you in advance!

-Vinny

Whirlwind
  • 14,286
  • 11
  • 68
  • 157
vinny_711
  • 51
  • 9
  • in the timer turn repeats to true and let the function try to keep spawning an enemy. tell me if you are able to get an enemy appear at least once – MaxKargin Aug 10 '15 at 00:39
  • @M321K Thank you for responding. I kept on getting the "Called!" in the log every ten seconds yet no enemies were spawned. Any ideas? – vinny_711 Aug 10 '15 at 01:09
  • 1
    If you don't use the random value generator and just specify the center of the screen for the enemy, does it appear? – MaxKargin Aug 10 '15 at 01:52
  • @M321K Thank you for responding again. Unfortunately no, the enemy doesn't appear :( – vinny_711 Aug 10 '15 at 03:03
  • 1
    Is there a background sprite node perhaps that could be hiding it? Are you setting the scene anchor point anywhere so that nodes are in wrong places maybe? – MaxKargin Aug 10 '15 at 03:09
  • @M321K Thank you for responding. No there are no background nodes to block it and no I am not setting the scene anchor point anywhere so that nodes are in wrong places. Thank you again. – vinny_711 Aug 10 '15 at 03:39

1 Answers1

2

You should keep things simple and just do everything inside GameScene. Another thing is to drop NSTimer and use SKAction to spawn enemies. NSTimer don't respect scene's paused state, so you can get into some trouble eventually. This is how you can spawn enemies using SKAction:

GameScene.swift:

import SpriteKit

class GameScene: SKScene {


    override func didMoveToView(view: SKView) {

        generateEnemies()
    }

    func stopGeneratingCoins(){


        if(self.actionForKey("spawning") != nil){removeActionForKey("spawning")}

    }

    func generateEnemies(){

        if(self.actionForKey("spawning") != nil){return}



        let timer = SKAction.waitForDuration(10)

        //let timer = SKAction.waitForDuration(10, withRange: 3)//you can use withRange to randomize duration


        let spawnNode = SKAction.runBlock {


            var enemy = SKSpriteNode(color: SKColor.greenColor(), size:CGSize(width: 40, height:40))
            enemy.name = "enemy" // name it, so you can access all enemies at once.

            //spawn enemies inside view's bounds
            let spawnLocation = CGPoint(x:Int(arc4random() % UInt32(self.frame.size.width - enemy.size.width/2) ),
                y:Int(arc4random() %  UInt32(self.frame.size.height - enemy.size.width/2)))

            enemy.position = spawnLocation


            self.addChild(enemy)

            println(spawnLocation)

        }

        let sequence = SKAction.sequence([timer, spawnNode])


        self.runAction(SKAction.repeatActionForever(sequence) , withKey: "spawning") // run action with key so you can remove it later


    }

}

When it comes to positioning, I assumed that your scene already has the correct size. If scene is not correctly initialized and has different size (or more precisely, different aspect ratio) than a view, it could happen that enemy get off-screen position when spawned. Read more here on how to initialize the scene size properly.

Community
  • 1
  • 1
Whirlwind
  • 14,286
  • 11
  • 68
  • 157
  • Thank you so much for responding! this code works perfectly, but is there anyway I can make a cap on how many enemies spawn? I know I'm asking for a lot but is there anyway I can apply an impulse to each enemy in a random direction? Thank you again so very much. – vinny_711 Aug 11 '15 at 22:49
  • @vinny_711 You can use some counter variable to count how much enemies were spawned, and remove action key when needed. Or you can repeat action for specified number of times : https://developer.apple.com/library/prerelease/ios/documentation/SpriteKit/Reference/SKAction_Ref/index.html#//apple_ref/occ/clm/SKAction/repeatAction:count: Search SO site about your second question, I am sure that something helpful can be found about that topic. Or ask a new question, because comments are not suitable for new questions/answers. – Whirlwind Aug 12 '15 at 01:16