2017-02-14 17 views
0

Я пытался переместить плеер по оси x с помощью встроенного акселерометра, но что-то не так. Когда я имитирую приложение на своем iPhone, узел продолжает двигаться во всех направлениях и только через 2-3 раза, когда я закрываю приложение и запускаю его снова, узел перемещается слева направо, что я и хотел. Так оно работает, но только после закрытия и открытия приложения снова.Странное поведение акселерометра (CoreMotion)

Часть кода:

import Foundation 
import SpriteKit 
import CoreMotion 

class Gameplay : SKScene{ 

    private var player : Player? 

    var motionManager = CMMotionManager() 

    override func update(_ currentTime: TimeInterval) { 
     self.player?.move() 
    } 

    func initializeGame(){ 
     player = childNode(withName: "player") as? Player! 
     player?.initPlayer() 
    } 

    override func didMove(to view: SKView) { 

     initializeGame() 

     motionManager.startAccelerometerUpdates() 
     motionManager.accelerometerUpdateInterval = 0.1 
     motionManager.startAccelerometerUpdates(to: OperationQueue.current!) { (data , _) in 
      if let accelerometerData = data{ 
       print("x: \(accelerometerData.acceleration.x)") 
       print("y: \(accelerometerData.acceleration.y)") 
       self.physicsWorld.gravity = CGVector(dx: accelerometerData.acceleration.x*10, dy: 0) //only x axis? 
      } else { 
       print("NOPE") 
      } 

     } 
    } 

Player.swift:

import Foundation 
import SpriteKit 

class Player : SKSpriteNode{ 

    func initPlayer(){ 
     name = "Player" 

     physicsBody?.affectedByGravity = true 
     physicsBody?.isDynamic = true 

    } 

    func move(){ //boundaries 
     if position.x >= 315{ 
      position.x = 315 
     } else if position.x <= -315{ 
      position.x = -315 
     } 
    } 

    func shoot(){ 
     //... 
    } 

} 

ответ

1

Вместо изменения силы тяжести вашей сцены попытаться переместить игрока напрямую. Если вы приспособите гравитацию, это испортит все ваши физические тела. Поэтому либо переместите игрока с помощью SKAction, либо лучше, применив к нему Силу.

player?.physicsBody?.applyForce(CGVector(dx: 30 * CGFloat(accelerometerData.acceleration.x), dy: 0)) 

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

Так удалить Этот блок кода

motionManager.startAccelerometerUpdates(to: OperationQueue.current!) { (data , _) in 
     if let accelerometerData = data{ 
      print("x: \(accelerometerData.acceleration.x)") 
      print("y: \(accelerometerData.acceleration.y)") 
      self.physicsWorld.gravity = CGVector(dx: accelerometerData.acceleration.x*10, dy: 0) //only x axis? 
     } else { 
      print("NOPE") 
     } 

    } 

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

override func update(_ currentTime: TimeInterval) { 

    if let accelerometerData = motionManager.accelerometerData { 
     player?.physicsBody?.applyForce(CGVector(dx: 30 * CGFloat(accelerometerData.acceleration.x), dy: 0)) 
    } 
    .... 
} 

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

Надеюсь, что это поможет