kin*_*apo 3 objective-c screen-resolution game-physics ios sprite-kit
我正在开发的 SpriteKit 游戏遇到了一些问题。我正在尝试做一个平台游戏风格的游戏,玩家点击屏幕让角色跳跃。我正在通过以下方式实现这一目标:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
// reset the velocity each jump, so that a constant impulse is always applied
self.player.physicsBody.velocity = CGVectorMake(0, 0);
// jump the player up
[self.player.physicsBody applyImpulse:CGVectorMake(0, PLAYER_JUMP_HEIGHT)];
}
Run Code Online (Sandbox Code Playgroud)
PLAYER_JUMP_HEIGHT只是一个常数。我还设置了具有恒定质量的播放器。
这在 iPad 模拟器上非常有效,这是我进行大部分初始测试的地方。然而,在调整我的代码以适应设备分辨率(对于手机等)之后,我的物理性能似乎非常差,尤其是在 iPhone 4S 模拟器上。同样的冲动现在让玩家跳得非常高,而且他们似乎也更快地从平台等物体上掉下来,比以前更像线性曲线。
我通过首先设置场景的缩放模式来缩放我的场景以适应多个设备:
scene.scaleMode = SKSceneScaleModeResizeFill;
Run Code Online (Sandbox Code Playgroud)
我还想出了一种方法,通过将当前设备的分辨率与 iPad 的分辨率进行比较,然后除以得到一个比例因子来乘以所有内容,从而缩放游戏中的其他所有内容。因此,在 iPad 屏幕宽度为 2048 的情况下,如果我在 iPhone 4S 上运行,则比例因子将为 960 / 2048 = 0.46。通过这种方式,我可以使用一组常量来设计游戏,这些常量可以跨所有设备分辨率进行缩放,而不会出现其他缩放模式的裁剪或其他缩放问题。
我对这可能是什么感到非常困惑。我试过将玩家质量和跳跃高度乘以屏幕比例因子,在所有可能的组合中,都无济于事。我还尝试弄乱了physicsWorld 的重力和速度,这也不起作用。如果有人有处理这个问题的经验并愿意分享,任何帮助将不胜感激。谢谢!
您的问题需要考虑几个因素,包括不同设备的不同分辨率、重力和动量。为什么是动量?因为在 中applyImpulse:(CGVector)impulse,冲量是一个向量,描述了添加了多少动量。因此,简单地乘以一个比例因子PLAYER_JUMP_HEIGHT是没有用的。
多亏了这个答案,我们可以使用名为“像素与单位”的比率来计算dy制作脉冲向量所需的数量。
下面是解释如何让玩家不断跳跃PLAYER_JUMP_HEIGHT。您可能想根据不同的分辨率自己调整它,这次您的比例因子应该可以工作。
#define kScale ([[UIScreen mainScreen] bounds].size.height) / 1024.0
const CGFloat PLAYER_JUMP_HEIGHT = 200.0;
- (void)didMoveToView:(SKView *)view
{
self.physicsBody = [SKPhysicsBody bodyWithEdgeLoopFromRect:self.frame];
// Print useful info
NSLog(@"scale: %.3f", kScale);
NSLog(@"total height: %.1f", self.frame.size.height);
NSLog(@"jump height: %.1f%%", kScale * PLAYER_JUMP_HEIGHT / self.frame.size.height * 100);
// Let player jump over the bar
SKSpriteNode *bar = [SKSpriteNode spriteNodeWithColor:[UIColor redColor] size:CGSizeMake(CGRectGetMaxY(self.frame), 1.0)];
bar.position = CGPointMake(CGRectGetMidX(self.frame), PLAYER_JUMP_HEIGHT * kScale);
[self addChild:bar];
self.player = [SKSpriteNode spriteNodeWithColor:[UIColor greenColor] size:CGSizeMake(kScale * 50.0, kScale * 50.0)];
self.player.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:CGSizeMake(kScale * 50.0, kScale * 50.0)];
self.player.physicsBody.mass = 0.25;
self.player.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame)/5.0);
[self addChild:self.player];
// Pixel to unit
ptu = 1.0 / sqrt([SKPhysicsBody bodyWithRectangleOfSize:CGSizeMake(1.0, 1.0)].mass);
}
Run Code Online (Sandbox Code Playgroud)
在上面的代码中,我们首先设置了 const PLAYER_JUMP_HEIGHT,一个表示屏幕上 200 点有多高的条,aplayer和 ratio ptu。
然后计算dy并将其应用于脉冲:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
// reset the velocity each jump, so that a constant impulse is always applied
self.player.physicsBody.velocity = CGVectorMake(0, 0);
self.physicsWorld.gravity = CGVectorMake(0, kScale * (-9.8));
// jump the player up
CGFloat dy = self.player.physicsBody.mass * sqrt(2 * (-self.physicsWorld.gravity.dy) * (kScale * PLAYER_JUMP_HEIGHT * ptu));
[self.player.physicsBody applyImpulse:CGVectorMake(0, dy)];
}
Run Code Online (Sandbox Code Playgroud)
这是用于演示、运行和播放的示例项目(过时)。你会发现盒子精灵实际上并没有跳过红色条而是略低一点。我认为原因是重力。
代码在几个地方更新:
kScale为不同的设备定义宏以进行快速测试。仅适用于纵向。
添加kScale需要的地方(跳跃高度、玩家大小和重力!)。它现在应该以相同的速度跳跃自适应高度。
| 归档时间: |
|
| 查看次数: |
647 次 |
| 最近记录: |