0

I need help with coming up with ways to make to make the newly spawned enemy ships all shoot bullets. The problem is that I don't actually know how I am going to do that. I tried using a variable timer but, it only shoots one straight line and I can't really control the location it spawns at.

Game Picture: There are more enemies spawning What I Tried:

var EnemyTimer = Foundation.Timer.scheduledTimer(timeInterval: 0.3, target: self, selector: #selector(GameScene.spawnBullet3), userInfo: nil, repeats: true)

Also Tried:

 }
func spawnBullet3(){
    let Bullet = SKSpriteNode(imageNamed: "eBullet.png")
    Bullet.setScale(1)
    Bullet.zPosition = -1

    Bullet.position = CGPoint(x: enemy.position.x, y: enemy.position.y)

    let action = SKAction.moveTo(y: self.size.height + 100, duration: 0.5)
    let actionDone = SKAction.removeFromParent()
    Bullet.run(SKAction.sequence([action, actionDone]))

    Bullet.physicsBody = SKPhysicsBody(rectangleOf: Bullet.size)
    Bullet.physicsBody?.categoryBitMask = PhysicsCategories.Bullet
    Bullet.physicsBody!.collisionBitMask = PhysicsCategories.None
    Bullet.physicsBody?.contactTestBitMask = PhysicsCategories.Enemy
    Bullet.physicsBody?.affectedByGravity = true
    Bullet.physicsBody?.isDynamic = false
    self.addChild(Bullet)

}
kb920
  • 3,039
  • 2
  • 33
  • 44
Abee
  • 11
  • 4
  • 1
    Can you post piece of code with timer and bullet creation? There are a lot of ways how to do this, it would probably be best to start with what you already have and see what went wrong – Lope Nov 07 '16 at 05:20
  • 1
    Don't use timers - they are not Sprite-Kit compliant. Use SKActions instead. – Steve Ives Nov 07 '16 at 08:57
  • Your 'bullet.position...' code would be simpler as 'bullet.position = enemy.position'. What is this code doing that is incorrect? What problem are you actually having? Be more specific than 'not knowing how to spawn bullets'. – Steve Ives Nov 07 '16 at 09:00
  • this tutorial was very helpful to me for battle games, maybe it helps you too [Shooting Projectiles](https://www.raywenderlich.com/42699/spritekit-tutorial-for-beginners) – Mina Nov 07 '16 at 13:33
  • ughh i am still stuck. – Abee Nov 09 '16 at 03:52
  • I suggest you just use your update function instead of a timer or skaction – Jack Nov 13 '16 at 17:25

1 Answers1

0

Well, for starters, (as LearnCocos2D explained wonderfully here) never user a Timer, performSelector:afterDelay:, or Grand Central Dispatch (GCD, ie any dispatch_... method.

Before anything, you must set up a couple of things:

First, replace add an argument to your spawnBullet3 function (If you use a custom class replace enemy:SKSpriteNode with enemy:yourCustomClass).

func spawnBullet3(enemy:SKSpriteNode){
   let Bullet = SKSpriteNode(imageNamed: "eBullet.png")
   Bullet.setScale(1)
   Bullet.zPosition = -1

   Bullet.position = CGPoint(x: enemy.position.x, y: enemy.position.y)

   let action = SKAction.moveTo(y: self.size.height + 100, duration: 0.5)
   let actionDone = SKAction.removeFromParent()
   Bullet.run(SKAction.sequence([action, actionDone]))

   Bullet.physicsBody = SKPhysicsBody(rectangleOf: Bullet.size)
   Bullet.physicsBody?.categoryBitMask = PhysicsCategories.Bullet
   Bullet.physicsBody!.collisionBitMask = PhysicsCategories.None
   Bullet.physicsBody?.contactTestBitMask = PhysicsCategories.Enemy
   Bullet.physicsBody?.affectedByGravity = true
   Bullet.physicsBody?.isDynamic = false
   self.addChild(Bullet)
}

Second, create a public enemies array (Again, if you use a custom class replace SKSpriteNode with your custom class name).

var enemies:[SKSpriteNode] = []

Next, every time you create a new enemy, append the enemy to the array

enemies.append(newEnemy)

Now you have two options:

Option 1: Use a SKAction

Use a SKAction timer to automate every enemy shooting every couple of seconds (Replace SKAction.waitForDuration(2.5) with SKAction.waitForDuration(yourAmountOfSeconds)).

for e in enemies
{
   var wait = SKAction.waitForDuration(2.5)
   var run = SKAction.runBlock {
      spawnBullet3(e)
   }

   e.runAction(SKAction.repeatActionForever(SKAction.sequence([wait, run])))
}

Option 2: Use the update function

Use the currentTime from the update function (Replace currentTime.truncatingRemainder(dividingBy: 3) with currentTime.truncatingRemainder(dividingBy: yourAmountOfSeconds)).

override func update(_ currentTime: TimeInterval) {
   [...]

   if currentTime.truncatingRemainder(dividingBy: 3) == 0
   {
      for e in enemies
      {
         spawnBullet3(e)
      }
   }
}
Community
  • 1
  • 1
Jack
  • 955
  • 1
  • 9
  • 30