【问题标题】:SpriteKit Physics Inconsistent On Different Screen ResolutionSpriteKit 物理在不同的屏幕分辨率上不一致
【发布时间】:2016-01-01 02:04:35
【问题描述】:

我正在开发的一款 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)];
}

PLAYER_JUMP_HEIGHT 只是一个常数。我还设置了质量恒定的播放器。

这在 iPad 模拟器上效果很好,这是我进行大部分初始测试的地方。然而,在调整我的代码以适应设备分辨率(对于手机等)之后,我的物理现在似乎非常偏离,特别是在 iPhone 4S 模拟器上。现在,同样的冲动让玩家跳得非常高,而且他们似乎也更快地从平台等物体上掉下来,比以前更呈线性曲线。

我通过首先设置场景的缩放模式来缩放我的场景以适应多个设备:

scene.scaleMode = SKSceneScaleModeResizeFill;

我还想出了一种方法来缩放游戏中的其他所有内容,方法是将当前设备的分辨率与 iPad 的分辨率进行比较,然后除以得到一个比例因子来乘以所有内容。因此,如果 iPad 屏幕宽度为 2048,如果我在 iPhone 4S 上运行,比例因子将为 960 / 2048 = 0.46。通过这种方式,我可以使用一组可以在所有设备分辨率上缩放的常量来设计游戏,而不会出现其他缩放模式的裁剪或其他缩放问题。

我很困惑这可能是什么。我尝试在所有可能的组合中将玩家质量和跳跃高度乘以屏幕比例因子,但无济于事。我还尝试弄乱了physicsWorld 的重力和速度,但也没有用。如果有人有处理此问题的经验并愿意分享,我们将不胜感激。谢谢!

【问题讨论】:

  • 您是否根据比例因子调整了CGVectorapplyImpulse
  • @WangYudong 感谢您的快速评论!我确实尝试过将 PLAYER_JUMP_HEIGHT 乘以屏幕比例因子。

标签: ios objective-c sprite-kit game-physics screen-resolution


【解决方案1】:

您的问题需要考虑几个因素,包括不同设备的不同分辨率、重力和动量。为什么是动量?因为在applyImpulse:(CGVector)impulse 中,impulse 是一个向量,描述了添加了多少动量。因此,简单地在PLAYER_JUMP_HEIGHT 上乘以比例因子是没有用的。

感谢this answer,我们可以使用名为“像素与单位”的比率来计算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);
}

在上面的代码中,我们首先设置了常量PLAYER_JUMP_HEIGHT,一个表示屏幕上200个点有多高的条形,一个player和比率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)];
}

这是用于演示的sample project过时),运行并播放。你会发现盒子精灵实际上并没有跳过红色条,而是稍微低了一点。我认为原因是重力。

在多个地方更新了代码:

  1. 为不同的设备定义kScale宏以进行快速测试。仅适用于纵向。

  2. 在需要的地方添加kScale(跳跃高度、玩家尺寸和重力!)。它现在应该以相同的速度跳跃自适应高度。

【讨论】:

  • 感谢您非常详细的回答!不幸的是,它仍然无法解决我的问题。播放器在分辨率较低的 iPhone 4S 上仍然跳得非常高,在 iPad 上跳得很好。我尝试将比例因子应用于ptudy,但没有帮助。重力仍然是这个解决方案的一个问题,因为玩家在分辨率较低的设备上下落得更快,而在 iPad 上下落得更慢(并且以适当的速度)。
  • @kingsapo 你能在我的示例项目中重现你的问题吗?
  • 好的,我做了更多的测试。我确实让它工作将PLAYER_JUMP_HEIGHT 乘以比例因子。不过,我仍然遇到重力在不同屏幕尺寸上不同的问题。例如,从点击屏幕到着陆的整个跳跃在 iPhone 4S 上大约需要 0.6 秒,而在 iPad Air 2 上相同的跳跃大约需要 0.9 秒。在应用相同的缩放技术后,我能够在您的示例项目中重现这一点我在我的项目中使用你的,这只是将barself.player 的大小和位置乘以比例因子。
  • 你真正想要什么?不同高度的跳跃(例如 iPad 上 200 点,iPhone 4s 上 200*0.46)同时完成?
  • 是的,这听起来正是我想要的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多