在 Swift 中的 spawn 函数 returns SIGABRT 之外声明 SKSpriteNode

Declaring SKSpriteNode outside spawn function returns SIGABRT in Swift

我正在制作一款游戏,其中有一名玩家和无限数量的敌人,这些敌人会在特定时间内在给定位置生成。这些敌人向玩家发射子弹。我需要能够访问 SpawnEnemies() 函数外部的 Enemy 变量,以便我可以在我的 SpawnBullets() 函数中使用它。我尝试在 SpawnEnemies() 函数外声明 Enemy 变量,但它返回了 Sigabrt,我不知道如何在函数外访问 Enemy 变量而不会出现此错误。

敌人声明:

var Enemy = SKSpriteNode(imageNamed: "Enemy.png")

SpawnEnemies 函数:

func SpawnEnemies() {
     let MinValue = self.size.width/8
     let MaxValue = self.size.width-20
     let SpawnPoint =  UInt32(MaxValue-MinValue)
     self.Enemy.position = CGPoint(x: CGFloat(arc4random_uniform(SpawnPoint)), y: self.size.height)
     let action = SKAction.moveToY(-70, duration: 3.0)
     self.Enemy.runAction(SKAction.repeatActionForever(action))
     self.addChild(Enemy)

}

SpawnBullets 函数:

func SpawnBullets(){
     let Bullet = SKSpriteNode(imageNamed: "bullet.png")
     Bullet.zPosition = -5
     Bullet.position = CGPointMake(Enemy.position.x, Enemy.position.y)
     let action = SKAction.moveToY(self.size.height + 30, duration: 1.0)
     Bullet.runAction(SKAction.repeatActionForever(action))
     self.addChild(Bullet)
}

在 didMoveToView() 中调用 SpawnEnemies 函数:

var EnemyTimer = NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: Selector("SpawnEnemies"),userInfo: nil, repeats: true)

在 didMoveToView() 中调用 SpawnBullets 函数:

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

我收到此错误,这是一个 sigabrt,但我使用断点来确定错误的确切位置和内容:

Attemped to add a SKNode which already has a parent: <SKSpriteNode> name:'(null)' texture:[<SKTexture> 'Enemy.png' (60 x 80)] position:{132, 1024} scale:{1.00, 1.00} size:{60, 80} anchor:{0.5, 0.5} rotation:0.00

将children添加到场景中已经是"infinite",您只需要将其用于您的优势即可。

首先像这样修改你的子弹函数,这样你就可以传递一个敌人。

func SpawnBullets(enemy : SKSpriteNode){
     let Bullet = SKSpriteNode(imageNamed: "bullet.png")
     Bullet.zPosition = -5
     Bullet.position = CGPointMake(enemy.position.x, enemy.position.y)
     let action = SKAction.moveToY(-self.size.height - 70, duration: 1.0)
     Bullet.runAction(SKAction.repeatActionForever(action))
     self.addChild(Bullet) 
}

然后修改你的敌人函数,这样随着时间的推移你会产生一个新的敌人。

func SpawnEnemies() {
     var Enemy = SKSpriteNode(imageNamed: "Enemy.png")
     Enemy.name =  "enemy";
     let MinValue = self.size.width/8
     let MaxValue = self.size.width-20
     let SpawnPoint =  UInt32(MaxValue-MinValue)
     Enemy.position = CGPoint(x: CGFloat(arc4random_uniform(SpawnPoint)), y: self.size.height)
     let action = SKAction.moveToY(-70, duration: 3.0)
     Enemy.runAction(SKAction.repeatActionForever(action))
     self.addChild(Enemy)

}

在 didMoveToView 函数中,让我们向场景添加动作来处理我们的计时,这样我们就不会使用 NSTimer

{
...
  let spawnEnemy = SKAction.sequence([SKAction.runBlock(
  {
    [unowned self] in 
    self.SpawnEnemies();
  }),SKAction.waitForDuration(1)]);

  let spawnBullet = SKAction.sequence([SKAction.runBlock(
  {
    [unowned self] in
      self.enumerateChildNodesWithName("enemy", usingBlock: 
      {
        (enemy : SKNode,stop: UnsafeMutablePointer <ObjCBool>) in
                   self.SpawnBullets(enemy as! SKSpriteNode);  
      });        
  }),SKAction.waitForDuration(0.2)]);

  let group = SKAction.group([spawnEnemy, spawnBullet])
  self.runAction(SKAction.repeatActionForever(group))


}

此代码未经测试,如果我需要更新任何内容,请告诉我。