1

In my code I am essentially trying to make a galaga. Although when I try to get the enemies to fall using moveToY they stay stationary. I tried switching where the enemy should move to but that did nothing. I am trying not use a physics body.

import SpriteKit

var guy = SKSpriteNode()
var bullet = SKSpriteNode()
var badGuy = SKSpriteNode()


class GameScene: SKScene {
override func didMoveToView(view: SKView) {

    self.backgroundColor = SKColor.blackColor()

    guy = SKSpriteNode(imageNamed: "guy")
    guy.position = CGPoint(x: self.frame.size.width/2, y: self.frame.size.height/6)
    guy.setScale(0.5)
    addChild(guy)

    var timer = NSTimer.scheduledTimerWithTimeInterval(0.2, target: self, selector: Selector("spawnBullets"), userInfo: nil, repeats: true)

    var enemyTimer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: Selector("spawnBadGuys"), userInfo: nil, repeats: true)
}

func spawnBullets(){

    bullet = SKSpriteNode(imageNamed: "bullet")
    bullet.setScale(0.5)
    bullet.zPosition = -5
    bullet.position = CGPointMake(guy.position.x, guy.position.y)
    let action = SKAction.moveToY(self.size.height + 30, duration: 1)
    bullet.runAction(SKAction.repeatActionForever(action))
    self.addChild(bullet)
}

func spawnBadGuys(){

    badGuy = SKSpriteNode(imageNamed: "badGuy")
    var minValue = self.size.width/8
    var maxValue = self.size.width - 20
    var spawnPoint = UInt32(maxValue - minValue)
    badGuy.position = CGPoint(x: CGFloat(arc4random_uniform(spawnPoint)), y: self.size.height)
    let action = SKAction.moveToY(-35, duration: 3.0)
    self.runAction(SKAction.repeatActionForever(action))
    self.addChild(badGuy)

}

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

    for touch in touches {
        let location = touch.locationInNode(self)
        guy.position.x = location.x
        if guy.position.y != self.frame.height/6{
            guy.position.y = self.frame.size.height/6

               }
    }

}

override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
    for touch in touches {
        let location = touch.locationInNode(self)
        guy.position.x = location.x
        if guy.position.y != self.frame.height/6{
            guy.position.y = self.frame.size.height/6
        }


    }

}


}
Hamish
  • 78,605
  • 19
  • 187
  • 280
  • Note that you don't really need a property called badGuy. It keeps a reference only to last spawned enemy...You should create a local variable in spawnBadGuys() method (`let badGuy = ...`), unless you really need the reference to the last spawned enemy. – Whirlwind Feb 14 '16 at 19:17

1 Answers1

1

You should run action on the badGuy (instead of on the scene):

func spawnBadGuys(){         
        //...
        badGuy.runAction(SKAction.repeatActionForever(action))     
}

Hints:

  • You should remove off-screen nodes because you can easily run into performance issues. Even bullets are not visible when go off-screen, they are still in the node graph and taking up memory.

  • Using SKAction for time related actions in SpriteKit is always a better idea than using NSTimer. NSTimer doesn't respect node's, view's or scene's paused state. So, if user receives a phone call (and there is no custom pause feature implemented for NSTimer) instead of having the spawning paused, it will continue. So when app returns from background to foreground, the user will have a full screen of enemies. And that is not what you want. Pausing/unpausing is done automatically if you use SKAction or update: method and its currentTime parameter. Read more here

Community
  • 1
  • 1
Whirlwind
  • 14,286
  • 11
  • 68
  • 157