我是一个相当新的应用程序开发人员,也是Sprite Kit的新手。我正在创造一个游戏,我想要一个球总是向下坠落,好像它是在重力。这只是一个2D应用程序,所以我想要的是当球落下时,当你向左倾斜手机时,球向下移动并离开屏幕,如果你向右倾斜手机,球会在屏幕上向下移动。为了更好地了解我想要的东西,我在photoshop中制作了一个快速图表:
我想了解一些最简单,最好的方法。我的第一个想法是记录偏航并用它来决定球向左或向右移动的距离。这需要一些计算才能使球完全落在90度,虽然听起来对我来说很可能,但我不确定它是否真的有可能。
有人认为这是做到这一点的方法还是有更好的方法呢?
我在尝试第一个想法时遇到的一个问题是当我倾斜手机时,球左右移动(没有任何正确的计算,因此它完全不准确),我会将手机向左倾斜(对于例如)我进一步倾斜它,它变得越不敏感,所以球将向左移动更少。这会阻止我的想法工作,我不确定是否有办法绕过它。
我遇到的一个更大的问题是,当我在座位上转身时,偏航也会发生变化!我认为这与指南针有关,因为滚动或音高都没有像我这样改变。我确信可以做些什么来纠正这个问题,因为我玩游戏时使用陀螺仪从来没有这个问题。如果有人能指出我正确的方向,我会很感激,或者我可能只是在一个单独的新问题中提出这个问题。下面是我在photoshop中快速绘制的另一个图表,以帮助解释问题。图1是我希望能够倾斜手机的方式,但当你转身时(图2),球会向左或向右移动,具体取决于你转动的距离。 (是的,这是指在图2中持有电话的人)
非常感谢帮助!
答案 0 :(得分:11)
这是我刚刚从我建立的一个演示项目中抽出的一些代码。这是通过将一堆视图与UIKit Dynamics连接而创建的一条绳索。根据您的描述,我认为行为与您正在寻找的行为相同。
需要注意的是,此代码遵循真正的重力方向,因此如果您将手机设置为平面,则在与屏幕平行的平面中,重力将为0或接近0,因为其完整幅度将沿着z轴。您可能希望对其进行标准化,以使方向发生变化,但幅度保持不变。
在此示例中,self.gravity
是UIGravityBehavior
,但您可以使用相同的代码来提供您想要的任何类型的重力模拟。只需注销运动管理器处理程序中的值,即可查看可能获得的值。
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);
});
}];
我希望这有帮助!
答案 1 :(得分:3)
这是SpriteKit的解决方案:
1.创建一个新的SpriteKit项目
2.添加CoreMotion框架
3.在您的MyScene'中导入新框架。类:
#import <CoreMotion/CoreMotion.h>
4.示例针对此方向进行了优化:
5.将此代码添加到&#39; touchesBegan&#39; “MyScene”的方法&#39;类
sprite.size = CGSizeMake(20, 20);
sprite.physicsBody= [SKPhysicsBody bodyWithCircleOfRadius:sprite.size.width/2];
6.将此代码添加到&#39;更新&#39; “MyScene”的方法&#39;类
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);
}
你必须四处寻找重力的最佳因素。
希望这是有用的
答案 2 :(得分:0)
快捷代码:
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)
}