如何在平台游戏中轻松实现挥杆动作?


9

我正在开发一款游戏,玩家可以使用绳索摇摆(就像《蜘蛛侠》或《仿生突击队》一样),并且在实现此行为时遇到问题。谁能帮助我做到这一点,我的意思是物理公式等等。到目前为止,我已经提出了3个想法。一种是使用弹簧,但是会消耗大量时间,有时甚至会跳动。另外两个正在尝试计算下一步(一个通过计算势能,一个通过计算扭矩),并且每当演员试图摆动时,两者几乎都会崩溃。

这是我编写的用于计算扭矩的代码:

float dx = Runner->getPosition().x - ancher.x; 
float dy = Runner->getPosition().y - ancher.y;
float t0 = atan2(dy,dx); //my current angle
float k = ((dy) *vx - (dx) * vy) / (dx * dx+dy * dy); //previus angular velocity
k -= gravity * cos(t0) *dt; // new angular velocity (gravity is positive)
t0 += k * dt - acc * cos(t0) *dt * dt / 2; // rotate the rope
float dx1 = r0 * cos(t0); // new position (r0 is rope length)
float dy1 = r0 * sin(t0);
vx = (dx1 - dx) / dt; //calculate velocity
vy = (dy1 - dy) / dt;

相关(在制作绳索上):2D绳索碰撞检测
doppelgreener

@JonathanHobbs这个问题的答案恰好是我如何尝试实施我的绳索,因为在我的情况下碰撞是不必要的,所以我将每个绳索部分都设置为传感器,这样它们就可以自由移动而不会彼此卡住。
Ali1S232 2011年

绳子的简单摆和出现绳子的一些动画呢?我不相信像《仿生突击队》这样的老游戏除了钟摆之外还有别的东西。
user712092 2011年

@user钟摆想法应该可以正常工作。但就我而言,要么是由于玩家的快速移动,要么是因为我的执行不佳,均未获得良好的结果。
Ali1S232 2011年

@Gajet尝试做一些调试绘图,直到您理解正确为止?可以在Box2D中将这条摆线做成足够细的框来进行碰撞(并且可能将其从物理学中排除并手动移动?)。
user712092 2011年

Answers:


6

如果要进行刚性摆动,则到旋转点的距离是恒定的,只需将字符视为以旋转点为中心的圆上的点即可。给他一个一维(沿圆)角速度。每个帧的角加速度应为accelerationDueToGravity * cos(angleOfPlayerOnCircle)(0度指向右)。

如果您希望绳索变长/变短,则可以使用上述方案,并仅改变每帧的半径。


您的回答是我的第二次尝试,但是它的移动速度比我应该编辑我的问题并添加代码的速度要快得多,也许您可​​以发现问题所在。
Ali1S232

3

经过多次尝试,我选择了box2d。

通常有两种方法可以进行此模拟,或者至少我发现2:

  1. 一种是使用一些圆形,然后使用远距接头将它们连接起来。
  2. 另一个是将矩形链本身,然后使用旋转关节将其连接

在每个senario中,您都必须有一个ancher(在我的情况下是一个静态盒子)。最好降低绳索零件的重量(使用圆形或矩形形状),例如,为了具有更真实的物理效果,我将其密度设置为0.1,对于连接在绳索末端的盒子,我使用密度10。

另一件事您需要担心您的绳索部分如何相互反应。我只是希望绳索在场景中自由移动,所以我将所有绳索固定装置标记为传感器。您可能需要不同的方式。

接下来您需要担心的是要向世界更新的迭代次数:对于低段的绳索(最多8个),不需要使用较高的迭代值,也许是10/10,这是box2d本身建议的足够了,但是如果您增加了段的数量(例如,我尝试了30个段),则迭代次数很少,您的绳索似乎增加了它应该增加的长度,因此您可能需要大约40/40的迭代来解决这些情况。

经过一些测试,似乎2d盒子是为对象尺寸为0.1m至10m的场景设计的,对于大型场景,建议的最大尺寸约为50mx50m。因此,基本上,您需要按比例缩小对象以匹配这些参数。以我为例,我首先尝试将像素位置直接传递给box2d,但似乎存在一些速度限制,阻止世界以其应有的速度运动,因此我不得不将场景缩放约64倍才能获得最佳效果。尽管我没有进行自我测试,但是box2d中存在一些限制,这些限制会阻止您使用较大的场景。例如,b2Setting.h文件中有一个定义的值,#define b2_maxTranslation 2.0f您可以更改box2d设置,但似乎不建议这样做。


为什么box2d为我赚了一张downvote是错的?
Ali1S232 2011年

这不能回答问题。至少要写出如何使用Box2D使其工作。
bummzack 2011年

@bummzack:然后我就补充一点,我的答案
Ali1S232

如果您接受此作为答案,则您的问题是否存在缺陷。分段绳索的物理性质与您描述的截然不同。
AttackingHobo

@attackingHobo:当时的问题是正确的,但是当我将代码转换为box2d时,我发现可以轻松实现分段绳索物理。并没有太大的区别,将我的问题想成只是分段绳索的一个部分。几乎我所有的解决方案都是无需box2d即可实现圆形绳索的方法。
Ali1S232 2011年

2

您是否考虑过根据绳索与铅垂线(中心)的距离来减慢摆动速度?


绳索的所有三个接近长度都是我用来计算摆动速度的参数之一。但是我不能保证我已经正确使用了它。我刚刚进行了一些物理计算,并将其求解后的版本应用于游戏。
Ali1S232

离中心的距离越远,绳索摆动的下一次运动之前的延迟就越长。您还可以将延迟的ABSolute值乘以0.28之类的值(您必须对此进行试验)。
兰道夫·理查森

我无法理解您要说的内容,当我计算下一步时,我有一个delta_time常数,并使用我拥有的所有参数(例如前移速度,前移位置,绳索长度等)进行计算新速度,然后将此速度乘以delta_time到最后一个位置以生成新位置。如果您还有其他疑问,请在答案中提供完整的详细信息。
Ali1S232

1

当演奏者的距离超过绳子的长度时,演奏者将立即以等于他经过绳索的距离的力向后推。这应该工作时不会感到弹性,并且应该使玩家感到直观。不过,您可能需要调整物理原理才能获得最佳游戏效果。

附上绳索后。保存一个maxLength值。

每次更新时,请检查,和distance之间的playerattachPoint

如果distance小于maxLength正常更新,则绳子无影响。

如果距离大于maxLength,则找到normalattachPoint到播放器的距离。获取之间的差异distancemaxLength。加到playerVelocitynormal乘以差。

伪代码:

dx = (attachPoint.x - player.x)
dy = (attachPoint.y - player.y)

distance = sqrt(dx*dx+dy*dy);

if (distance > maxDistance)
{
    float dx1 = dx / distance * maxDistance;
    float dy1 = dy / distance * maxDistance;
    v.x += (dx1 - dx) / dt;
    v.y += (dy1 - dy) / dt;
}

playerVel += v * dt;

所以我在您的答案中编辑了代码(对不起,但我找不到更好的地方添加它)?
Ali1S232 2011年

我批准了修改,是的,我认为应该是这样。尽管我以前使用过绳索物理学,并且使用了更为复杂的方法来完成同一操作,但是由于这一点,我不能完全确定此代码是否可以正常工作,但是我认为它应该并且即使不起作用也可以使您得到95 %的方式。
AttackingHobo

经过几次尝试,我想我将为此问题尝试box2d,顺便提一下,您必须更改该代码,以便拥有dx = player.x - attachpoint.xdy = player.y - attachpoint.y
Ali1S232 2011年

1

如果您查看http://www.cocos2d-iphone.org/archives/1112,则有一种绳索的实现方式,该绳索的末端附有刚体。它使用Box2D作为物理引擎。如果您查看源代码,我相信您可以使用任何喜欢的语言来实现它。

另外,上面到Rope问题的链接是我的,上面的演示(提供的链接)确实有用。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.