【问题标题】:Adding an enemy every 10 seconds which tracks your location每 10 秒添加一个敌人,跟踪您的位置
【发布时间】:2017-05-26 10:59:49
【问题描述】:

下面是我正在制作的一个简单游戏的部分代码。在游戏中,你的手指围绕着屏幕一个球在你的手指下方。然后每 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) {


    }
}

【问题讨论】:

  • your previous question 中尚未回答的问题?
  • 不,我已经使用了人们之前告诉我的所有信息来构建它,除了这个之外一切正常
  • 一般你不应该使用SKAction来实现类似homing missile的东西如果你需要每帧更新一些东西,你可以使用SKScene的update:方法。因此,如果配置正确,您正在做的事情可能会奏效,但仍然不是实现您想要的东西的高效方式。

标签: ios swift sprite-kit


【解决方案1】:
  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()
  }
}

【讨论】:

  • 嘿,非常感谢。我理解你在这里想要做什么,我认为它可以工作。我确实将其复制并粘贴到 Xcode 中并运行它。但可悲的是,它每 10 秒增加一个敌人,但敌人并没有跟着我。我会努力解决的。谢谢
  • 非常感谢 :) 我认为这与 movefollowertotarget 函数有关,因为其他一切似乎都可以正常工作。该功能已连接到添加敌人功能,所以我不确定它可能是什么。
  • 不,只是你回答了一般性问题,让我很好地了解了我需要做什么,目前球会生成,我可以撞到它们,因为我添加了物理实体,但是嘿不要不要跟着我,就像我说的那样,我认为它与 movefollowertotarget 函数有关,您应该尝试在 excise 中运行它,看看会发生什么
  • 那么我是不是把整个 movefollowertotarget 函数放到 touches 中了?
  • 哦,是的,我刚刚做到了,我明白你的意思了,这几乎就像它相反,当你拖动球时它们不会跟随你,但当你放手时它们会跟随
猜你喜欢
  • 1970-01-01
  • 2021-07-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多