0
votes

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)

}
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 wrongLope
Don't use timers - they are not Sprite-Kit compliant. Use SKActions instead.Steve Ives
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
this tutorial was very helpful to me for battle games, maybe it helps you too Shooting ProjectilesMina
ughh i am still stuck.Abee

1 Answers

0
votes

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)
      }
   }
}