每 10 秒添加一个敌人来跟踪您的位置



下面我有我正在制作的简单游戏的部分代码。 在游戏中,你的手指在屏幕上,一个球在你的手指下面。然后每 10 秒添加一个球,跟随你的球。我有一个SKAaction,它每10秒调用一次我的添加敌人函数,从而生成敌人。问题是我无法让添加敌人功能每帧更新一次,因为如果 SKAction 每帧更新一次,它就不会让我调用它,所以我不确定该怎么做才能让球每 10 秒添加一次并让该球跟踪您的位置。因为目前它只跟踪球被添加时的初始位置。任何帮助不胜感激,谢谢。

import SpriteKit
import GameplayKit
class GameScene: SKScene {
    var me = SKSpriteNode()
    override func didMove(to view: SKView) {
        me = self.childNode(withName: "me") as! SKSpriteNode
        let border = SKPhysicsBody (edgeLoopFrom: self.frame)
        border.friction = 0
        self.physicsBody = border
        run(SKAction.repeatForever(SKAction.sequence([SKAction.run(createEnemy), SKAction.wait(forDuration: 10.0)])))
    }
    func createEnemy () {
        let enemy = SKSpriteNode(imageNamed: "ball 1")
        enemy.name = "enemy"
        enemy.position = CGPoint(x:667, y: -200)
        enemy.run(SKAction.moveTo(x: me.position.x, duration: 2))
        enemy.run(SKAction.moveTo(y: me.position.y, duration: 2))
        enemy.zPosition = +1
        addChild(enemy)
    }
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        for touch in touches{
            let location = touch.location(in: self)
            me.run(SKAction.moveTo(x: location.x, duration: 0))
            me.run(SKAction.moveTo(y: location.y, duration: 0))
        }
    }
    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        for touch in touches{
            let location = touch.location(in: self)
            me.run(SKAction.moveTo(x: location.x, duration: 0))
            me.run(SKAction.moveTo(y: location.y, duration: 0))
        }
    }
    override func update(_ currentTime: TimeInterval) {

    }
}
  1. 通过字典中的 .name 属性在字典中保留所有当前活着的敌人的列表。此字典中的值是一个元组。此元组跟踪敌人的实例及其目标的实例。

我通过makeEnemyNameaddEnemyToDict在您的createEnemy中执行此操作

  1. update给每个敌人一个新的行动来跟踪它的目标。这是通过遍历字典,然后使用每个键的值来moveFollowerToTarget来完成的。此信息存储在我们创建的元组类型中。

import SpriteKit
class GameScene22: SKScene {
  // MARK: - My code:
  // Tuple to keep track of enemy objects:
  typealias FollowerAndTarget = (follower: SKSpriteNode, target: SKSpriteNode)
  // [followerName: (followerSprite, targetSprite):
  var spriteDictionary: [String: FollowerAndTarget] = [:]
  // Give each enemy a unique name for the dictionary:
  var enemyCounter = 0
  // Assign to each enemy a unique name for the dictionary:
  private func makeEnemyName() -> String {
    enemyCounter += 1
    return "enemy(enemyCounter)"
  }
  private func addEnemyToDict(enemy: SKSpriteNode, target: SKSpriteNode) {
    if let name = enemy.name { spriteDictionary[name] = (enemy, target) }
    else { print("enemy not found") } // error!
  }
  private func removeEnemyFromDict(enemy: SKSpriteNode) {
    if let name = enemy.name { spriteDictionary[name] = nil }
    else { print("enemy not removed from dictionary!") } // error!
  }
  // Note, you did not set the enemy to have a constant speed, so the enemy will move at random speeds
  // based on how far they are away from the target.
  private func moveFollowerToTarget(_ sprites: FollowerAndTarget) {
    let action = SKAction.move(to: sprites.target.position, duration: 2)
    sprites.follower.run(action)
  }
  private func allEnemiesMoveToTarget() {
    for sprites in spriteDictionary.values {
      moveFollowerToTarget(sprites)
    }
  }
  // Use this carefully if you are using phsyics later on:
  func killEnemy(_ enemy: SKSpriteNode) {
    // Remove this enemy from the update loop:
    removeEnemyFromDict(enemy: enemy)
    enemy.removeAllActions()
    enemy.removeFromParent()
    enemy.physicsBody = nil
  }
  // MARK: - Your code (mostly):
  var me = SKSpriteNode()
  override func didMove(to view: SKView) {
    me = SKSpriteNode(color: .blue, size: CGSize(width: 50, height: 50))
    me.name = "me"
    addChild(me)
    self.anchorPoint = CGPoint(x: 0.5, y: 0.5)
    let border = SKPhysicsBody (edgeLoopFrom: self.frame)
    border.friction = 0
    self.physicsBody = border
    run(SKAction.repeatForever(SKAction.sequence([SKAction.run(createEnemy), SKAction.wait(forDuration: 10.0)])))
  }
  func createEnemy () {
    let enemy = SKSpriteNode(color: .purple, size: CGSize(width: 30, height: 30))
    enemy.name = makeEnemyName()
    addEnemyToDict(enemy: enemy, target: me)
    moveFollowerToTarget((follower: enemy, target: me))
    enemy.zPosition = +1
    addChild(enemy)
  }
  override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    for touch in touches{
      let location = touch.location(in: self)
      me.run(SKAction.moveTo(x: location.x, duration: 0))
      me.run(SKAction.moveTo(y: location.y, duration: 0))
    }
  }
  override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
    for touch in touches{
      let location = touch.location(in: self)
      me.run(SKAction.moveTo(x: location.x, duration: 0))
      me.run(SKAction.moveTo(y: location.y, duration: 0))
      allEnemiesMoveToTarget()
    }
  }
  override func update(_ currentTime: TimeInterval) {
    // Will iterate through dictonary and then call moveFollowerToTarget()
    // thus giving each enemy a new movement action to follow.
    allEnemiesMoveToTarget()
  }
}

最新更新