ios - una - ¿Cómo dar la bola caída a la gravedad del mundo real?
que cae primero una pluma o una bola de boliche (3)
Aquí hay un código que saqué de un proyecto de demostración que construí hace un tiempo. Era un trozo de cuerda creado mediante la conexión de un montón de vistas con UIKit Dynamics. Según su descripción, creo que el comportamiento fue el mismo que el que está buscando.
Una advertencia es que este código sigue la verdadera dirección de la gravedad, por lo que si coloca el teléfono en posición horizontal, la gravedad será 0 o cerca de 0 en el plano paralelo a la pantalla, ya que su magnitud total será a lo largo del eje z. Es posible que desee normalizarlo para que la dirección cambie pero la magnitud permanezca constante.
En esta muestra, self.gravity
es un UIGravityBehavior
, pero podría usar el mismo código para alimentar cualquier tipo de simulación de gravedad que desee. Simplemente cierre los valores dentro del controlador del gestor de movimiento para ver qué tipo de valores es probable que obtenga.
self.motionManager = [[CMMotionManager alloc] init];
[self.motionManager startDeviceMotionUpdatesToQueue:self.motionQueue withHandler:^(CMDeviceMotion *motion, NSError *error) {
CMAcceleration gravity = motion.gravity;
dispatch_async(dispatch_get_main_queue(), ^{
self.gravity.gravityDirection = CGVectorMake(gravity.x, -gravity.y);
});
}];
¡Espero que esto ayude!
Soy un desarrollador de aplicaciones bastante nuevo y muy nuevo para Sprite Kit. Estoy creando un juego en el que quiero que una bola siempre caiga hacia abajo como si estuviera en gravedad. Esta es solo una aplicación 2d, así que todo lo que quiero es cuando la pelota está cayendo, cuando inclinas el teléfono hacia la izquierda, la pelota viaja hacia abajo y hacia la izquierda en la pantalla, y si inclinas el teléfono hacia la derecha, la pelota viaja hacia abajo y hacia la derecha en la pantalla. . Para dar una mejor imagen de lo que quiero, hice un diagrama rápido en photoshop:
Solo quisiera algunas opiniones sobre cuál es la forma más fácil y mejor de hacer esto. Mi primer pensamiento fue grabar la guiñada y usarla para determinar a qué distancia viaja la bola hacia la izquierda o hacia la derecha. Esto requeriría algunos cálculos para que la bola caiga perfectamente a 90 grados y, aunque me parece posible, no estoy seguro de que sea realmente posible.
¿Alguien piensa que esta es la forma de hacerlo o hay una manera mejor de hacerlo?
Un problema que encontré al probar mi primera idea fue cuando inclino el teléfono, la bola se movió hacia la izquierda y hacia la derecha (sin los cálculos adecuados, por lo que era totalmente inexacto), inclinaría el teléfono hacia la izquierda (por ejemplo) y cuanto más lo inclinaba, menos sensible se volvía, de modo que la bola viajaría menos a la izquierda. Esto evitaría que mi idea funcionara y no estoy seguro de si hay alguna manera de evitarlo.
Un problema mayor que encontré fue cuando me giré en mi asiento, ¡la orientación también cambiaría! Supongo que esto tiene algo que ver con la brújula, ya que ni la tirada ni el tono cambiaron como lo hice yo. Estoy seguro de que se puede hacer algo para corregir esto porque nunca tengo este problema con los juegos que uso y que usan el giroscopio. Si alguien pudiera apuntarme en la dirección correcta con eso, estaría agradecido, o podría hacer una nueva pregunta por separado. A continuación hay otro diagrama que dibujé rápidamente en photoshop para ayudar a explicar el problema. El diagrama 1 es la forma en que quiero poder inclinar el teléfono, pero cuando gira (el diagrama 2), la bola se mueve hacia la izquierda o hacia la derecha según la distancia que gire. (Sí, se supone que es una persona que tiene el teléfono en el diagrama 2)
¡La ayuda sería muy apreciada!
Aquí hay una solución con SpriteKit:
1.Crear un nuevo proyecto SpriteKit
2.Agregar el Framework CoreMotion
3.Importe el nuevo marco en su clase ''MyScene'':
#import <CoreMotion/CoreMotion.h>
4. El ejemplo está optimizado para esta orientación:
5. Agregue este código al método ''touchesBegan'' de la clase ''MyScene''
sprite.size = CGSizeMake(20, 20);
sprite.physicsBody= [SKPhysicsBody bodyWithCircleOfRadius:sprite.size.width/2];
6. Agregue este código al método de ''actualización'' de la clase ''MyScene''
CMMotionManager *_motionManager;
-(void)update:(CFTimeInterval)currentTime {
/* Called before each frame is rendered */
if (_motionManager== nil) {
_motionManager=[[CMMotionManager alloc]init];
_motionManager.deviceMotionUpdateInterval=0.025;
[_motionManager startDeviceMotionUpdates];
}
CMAcceleration gravity= _motionManager.deviceMotion.gravity;
self.physicsWorld.gravity = CGVectorMake(gravity.y*4, -gravity.x/4);
}
Tienes que jugar para encontrar los factores óptimos para la gravedad.
Espero que sea de utilidad
Código SWIFT:
if motion.isDeviceMotionAvailable {
self.motion.deviceMotionUpdateInterval = 1.0 / 60.0
self.motion.showsDeviceMovementDisplay = true
self.motion.startDeviceMotionUpdates(using: .xMagneticNorthZVertical)
// Configure a timer to fetch the motion data.
self.timer = Timer(fire: Date(), interval: (1.0/60.0), repeats: true,
block: { (timer) in
if let data = self.motion.deviceMotion {
let gravityData = data.gravity
scene.physicsWorld.gravity = CGVector(dx: 9.8 * (gravityData.x), dy: 9.8 * (gravityData.y))
}
})
// Add the timer to the current run loop.
RunLoop.current.add(self.timer, forMode: .defaultRunLoopMode)
}