ios - 创建游戏重播时的计时问题(赛车幽灵)

标签 ios objective-c cocos2d-iphone box2d game-physics

我在 cocos2d 中创建了一个 iOS 游戏,它使用 box2d 进行物理处理。我想为这个游戏提供重播功能(你可以在其中与之前的尝试进行比赛)我知道 box2d 是确定性的(好吧,它适用于相同的硬件......所以在你的同一部手机上运行它就可以了)所以这应该是可行的。目前,在测试期间,我已经用

记录了用户输入的时间
NSLog(@"%f", [[NSDate date] timeIntervalSince1970] - gameTime);

gameTime 是游戏开始的时间

然后我这样做是为了重新玩游戏

[self performSelector:@selector(simulateFingerDown:) withObject:nil afterDelay:0.753302];
[self performSelector:@selector(simulateFingerUp:) withObject:nil afterDelay:1.382405];
[self performSelector:@selector(simulateFingerDown:) withObject:nil afterDelay:2.066786];
[self performSelector:@selector(simulateFingerUp:) withObject:nil afterDelay:2.800533];
[self performSelector:@selector(simulateFingerDown:) withObject:nil afterDelay:3.950479];
[self performSelector:@selector(simulateFingerUp:) withObject:nil afterDelay:4.933555];
[self performSelector:@selector(simulateFingerDown:) withObject:nil afterDelay:6.607358];
[self performSelector:@selector(simulateFingerUp:) withObject:nil afterDelay:8.067316];
[self performSelector:@selector(simulateFingerDown:) withObject:nil afterDelay:8.700970];
[self performSelector:@selector(simulateFingerUp:) withObject:nil afterDelay:8.934012];

simulateFingerUp/Down 调用与 ccTouchBegan/Ended 调用相同的东西。我游戏中的唯一功能是触摸屏幕或不触摸屏幕,所以我只是在特定延迟中硬编码何时触摸或不触摸(以测试“幽灵”功能)这个过程按预期工作......并且游戏是“模拟/重播”但是应用程序的每次运行都会得到不同的结果。大概调度选择器取决于系统资源或类似的东西所以它会导致运行之间的不同时间(这可能导致我的游戏有很大差异)

我应该使用什么来模拟回放?我可以记录用户输入的时间,它只会在计算减法 [[NSDate date] timeIntervalSince1970] - gameTime 时关闭,但似乎用 performSelector 回放不可靠。有人有建议吗?

我也认为这可能相关? box2d 的 step 函数总是:_world->Step(0, 8, 3);

我不完全确定为什么是这些值...我从在线教程中获取了一些 box2d 代码,但没有解释这些特定值

最佳答案

一种解决方案是以固定的时间步长运行模拟。假设您选择每次更新 16 毫秒。但您仍然希望事物按实际耗时按比例移动。

现在假设一帧需要 20 毫秒。这意味着您将进行一次 16 毫秒更新,并为下一帧剩余 4 毫秒。然后说下一帧需要15ms。这意味着您需要进行一次 16 毫秒更新,然后为下一帧剩余 3 毫秒,依此类推。然后假设您有一个需要 40 毫秒的长帧 - 您需要为该帧执行两次 16 毫秒的更新。或者可能一帧需要 10 毫秒,而没有足够的剩余时间来达到 16 毫秒 - 在这种情况下,您不会执行物理更新。

现在您有一个(希望如此)确定性*、可重播的更新循环。

到目前为止,此实现的问题是运动不会显得非常平滑;您会遇到一些小问题,因为固定的 16 毫秒更新与您实际耗时不完全一致。

在您的渲染函数中,使用“剩余”时间(例如 4 毫秒)并按该数量及时向前插值。因此,使用汽车的当前速度和角速度,将其渲染到您估计 future 4 毫秒的位置。这应该足够准确以“看起来”正确。希望你能从物理引擎中得到汽车的速度和角速度。

*我满怀希望地说,因为 float 是一件棘手的事情,即使您认为它应该是确定性的,也可能不是。我不确定 iOS FP 数学是否具有确定性,或者它是否取决于编译器设置或其他什么。

关于ios - 创建游戏重播时的计时问题(赛车幽灵),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30747590/

相关文章:

ios - en 系统区域设置中 ru 语言的 strigsdict 文件的错误值

ios - 如何在 UITabBarController 中交换 ViewController

ios - NSFetchRequest 没有参数重复

objective-c - 新的 Google map 在 iOS 6 上实现崩溃

iphone - 使用 AudioToolbox 进行短音效音量控制在 iPad/iPod touch 型号上不起作用

cocoa-touch - 第一次点击 UITextField 时发生奇怪的崩溃

ios - 选择上方 UITextField 时向下滚动 UIScrollView

objective-c - Cocoa/Obj-C 路径控制 - 你能限制它只选择目录吗?

objective-c - 无法初始化类对象 : objective-C

objective-c - Cocos2d :how to implement zooming by pinch