Камера SpriteKit заикается при следовании за игроком

Я испытываю это отставание или заикание в своей игре, и я думаю, что это может быть связано с тем, как камера следует за моим игроком.

Вот код:

func update(_ hp: CGPoint) {
    let camMove = SKAction.move(to: CGPoint(x: hp.x, y: hp.y), duration: 0.2)
    self.run(camMove)
}

Вышеупомянутая функция находится в расширении для SKCameraNode, и я вызываю ее в основном из функции обновления сцен.

Он работает довольно хорошо, хотя кто-то упомянул, что заикание может быть связано с перекрывающимися действиями, поскольку оно вызывается каждый кадр. Я использую этот метод, потому что продолжительность позволяет камере двигаться более естественно, чем жестко.

Я ищу альтернативы этому, чтобы устранить это дублирование SKAction.

Я попытался добавить вызов removeallActions() перед запуском нового действия, но это должно произойти быстро, потому что камера вообще не двигается. Кроме того, я попытался добавить ключ к действию и удалить по ключу до запуска следующего, но так же, как и removeallActions(), камера не двигается.

Я также пробовал следующее:

func moveCam(_ point: CGPoint) {
    let camMove = SKAction.move(to: CGPoint(x: point.x, y: point.y), duration: 0.2)
    self.run(camMove) {
        self.moveCam(player.position)
    }
}

Это останавливает наложение, но между окончанием одного действия и другим окончанием есть небольшая задержка, которая постоянно вызывает уродливое заикание.

У меня есть идея попытаться использовать SKAgents с последующим поведением, но я не совсем уверен, как это будет сделано и будет ли это хорошо. Любые предложения или решения будут весьма признательны.


person Discoveringmypath    schedule 25.10.2017    source источник
comment
Вы создаете бесконечный цикл   -  person Knight0fDragon    schedule 25.10.2017
comment
да, я знаю... блок завершения должен запускаться в другом потоке, поэтому там нет проблем, за исключением задержки между ними, которую я объяснил...   -  person Discoveringmypath    schedule 25.10.2017
comment
Кроме того, я не уверен, что это исправит отставание. при тестировании некоторых других решений, которые вообще не двигали камеру. Я все еще мог играть с игроками, и у меня было такое же отставание / заикание ... В любом случае, я хотел бы оптимизировать это, если это возможно.   -  person Discoveringmypath    schedule 25.10.2017


Ответы (1)


Вы хотите сделать это, когда положение спрайта изменится, поэтому я бы рекомендовал использовать KVO, чтобы отслеживать это и соответствующим образом обновлять ваше действие:

override func didMove(to view:SKView) {
  super.didMove(to:view)
  sprite.addObserver(self, forKeyPath: #keyPath(SKNode.position),
              options: [.old, .new, .initial],
              context: nil)
}

override func observeValue(forKeyPath keyPath: String?,
                           of object: Any?, change: [NSKeyValueChangeKey : Any]?,
                           context: UnsafeMutableRawPointer?) {

  if keyPath == #keyPath(SKNode.position) {

    guard let camera = self.camera, let sprite = object as? SKNode else { fatalError() }

    let wait = SKAction.wait(forDuration: 0.2)
    let loop = SKAction.customAction(withDuration: TimeInterval(CGFloat.infinity)) {_,_ in
      let move = SKAction.move(to: CGPoint(x: self.sprite.position.x, y: self.sprite.position.y), duration: 0.2)
      camera.run(SKAction.sequence([move,SKAction.run({
        camera.removeAction(forKey:"cameraWaitKey")})]), withKey:"cameraMoveKey")
    }

    if camera.action(forKey:"cameraWaitKey") == nil {
      camera.run(SKAction.sequence([wait,loop]), withKey:"cameraWaitKey")
    }
  }
}


deinit { sprite.removeObserver(self, forKeyPath: #keyPath(SKNode.position)) }

Что это сделает, так это применит небольшое ожидание, а затем начнет перемещать камеру каждый раз, когда положение меняется. Как только камера достигает игрока, она перезагружается, и когда вы снова перемещаетесь, происходит задержка.

Вы можете добавить timeMode к своим действиям, чтобы создавать эффекты easyIn и easyOut при движении камеры.

person Knight0fDragon    schedule 25.10.2017
comment
Давайте продолжим это обсуждение в чате. - person Knight0fDragon; 25.10.2017