Cartographier l'inclinaison de l'appareil par rapport à la gravité physique mondiale ?
-
26-12-2019 - |
Question
Je construis un jeu de labyrinthe "en marbre" afin d'apprendre les bases du spritekit.
Je veux mapper la gravité du jeu à l'inclinaison de l'appareil.J'ai essayé de comprendre comment faire, mais je n'ai réussi à cartographier que l'axe y :
class func obtainGravity(motionManager: CMMotionManager) {
var vec = CGVectorMake(0, 0)
if let attitude = motionManager.deviceMotion?.attitude? {
let y = CGFloat(-attitude.pitch * 2 / M_PI) // This works, it returns 1/-1 when the device is vertical (1 when the home button is upside down)
let x = CGFloat(attitude.roll * 2 / M_PI) // This doesn't work
physicsWorld.gravity = CGVectorMake(x, y)
}
}
Je pourrais cartographier l'axe Y qui fait monter la balle "vers le haut" ou "vers le bas" (par rapport au mode portrait), mais je ne comprends pas comment cartographier l'axe X (la traction depuis le côté de l'appareil).
Par exemple, lorsque vous posez l'appareil à plat sur la table, (x, y) doit être (0,0) et lorsque vous le posez sur la table, écran vers le bas, il doit également être (0,0), mais attitude.roll renvoie -179.De plus, si je garde mon appareil vertical (en mode portrait) et que j'allume mes pieds en gardant l'appareil immobile, la gravité devrait rester (x :0, oui :1) cependant, x continue de changer car il est basé sur attitude.roll
Comment cela peut-il être fait?
La solution
Le moyen le plus simple serait d'effectuer des mises à jour de l'accéléromètre, et non des mises à jour des mouvements de l'appareil, et de lire directement le vecteur de gravité à partir de là - c'est exactement ce que l'accéléromètre capture :une mesure de la gravité dans le système de coordonnées de l'appareil.
Malheureusement, je suis un adepte de Swift, je ne peux donc pas fournir d'exemple de code, mais vous cherchez à fournir un bloc de type CMAccelerometerHandler
qui recevra un CMAccelerationData
à partir duquel vous pouvez obtenir CMAcceleration
struct et c’est, directement, le vecteur gravité à appliquer.
if let data = motionManager.accelerometerData? {
vec = CGVectorMake(CGFloat(data.acceleration.x), CGFloat(data.acceleration.y))
}