2

我想在 iPhone 上使用 Cocos2d 来绘制一辆 2D 汽车,让它以自然的方式从左向右转向。

这是我尝试过的:

  1. 计算轮子的角度,然后将其移动到轮子指向的目标点。但这会产生一种非常不自然的感觉。汽车漂移了一半

  2. 之后,我开始研究如何获得汽车的转弯圆,这意味着我需要一些常数,比如轴距和汽车的宽度。

经过大量研究,我创建了以下代码:

float steerAngle = 30; // in degrees
float speed = 20;
float carWidth = 1.8f; // as in 1.8 meters
float wheelBase = 3.5f; // as in 3.5 meters

float x = (wheelBase / abs(tan(steerAngle)) + carWidth/ 2);
float wheelBaseHalf = wheelBase / 2;
float r = (float) sqrt(x * x + wheelBaseHalf * wheelBaseHalf);

float theta = speed * 1 / r;
if (steerAngle < 0.0f)
    theta = theta * -1;

drawCircle(CGPointMake(carPosition.x - r, carPosition.y),
           r, CC_DEGREES_TO_RADIANS(180), 50, NO);

前几行是我的常数。carPosition 是 CGPoint 类型。之后我尝试画一个圆圈来显示我的车的转弯圈,但它画的圆圈太小了。我可以让我的常数更大,让圆圈更大,但是我仍然需要知道如何在这个圆圈上移动我的精灵。

我尝试按照我在该主题上找到的.NET 教程进行操作,但我无法真正完全转换它,因为它使用了 Cocoa 不支持的矩阵。

有人可以给我一些关于如何开始的指示吗?我一直在寻找示例代码,但我找不到。

编辑在下面给出的评论之后, 我更正了我的常量,我的轴距现在是 50(精灵高 50 像素),我的 carWidth 是 30(精灵宽 30 像素)。

但是现在我有一个问题,当我的车第一次“滴答”时,旋转是正确的(还有位置),但之后的计算似乎是错误的。

转弯圆的中间移动而不是保持在原来的位置。我需要(我认为)是在汽车的每个角度我需要重新计算转弯圆的原始中心。我认为这很容易,因为我有半径和转弯角度,但我似乎无法弄清楚如何让汽车在一个漂亮的圆圈内移动。

还有更多指针吗?

4

1 回答 1

1

你有正确的想法。在这种情况下,常量是问题所在。您需要指定wheelBasecarWidth您的视图大小相匹配的单位。例如,如果屏幕上的汽车图像的轴距为 30 像素,则WheelBase变量应使用 30。

这就解释了为什么你的屏幕上的圆圈太小了。Cocoa 正在为一辆只有 1.8 像素宽的小汽车画圆圈!

现在,关于沿着圆圈移动你的车:

您在上面的代码中计算的theta变量是一个旋转速度,您可以使用它来围绕该圆的中心点移动汽车:

让我们假设您的speed变量以每秒像素为单位,以使计算更容易。有了这个假设,您只需每秒执行一次以下代码:

// calculate the new position of the car
newCarPosition.x = (carPosition.x - r) + r*cos(theta);
newCarPosition.y = carPosition.y + r*sin(theta);

// rotate the car appropriately (pseudo-code)
[car rotateByAngle:theta];

注意:我不确定旋转汽车图像的正确方法是什么,所以我只是用来rotateByAngle:说明问题。我希望它有帮助!

更新(评论后):

没想到转弯的圆心会随着车子一起移动。原始代码没有考虑汽车已经旋转到的角度。我将其更改如下:

...
if (steerAngle < 0.0f)
    theta = theta * -1;

// calculate the center of the turning circle,
// taking int account the rotation of the car
circleCenter.x = carPosition.x - r*cos(carAngle);
circleCenter.y = carPosition.y + r*sin(carAngle);

// draw the turning circle
drawCircle(circleCenter, r, CC_DEGREES_TO_RADIANS(180), 50, NO);

// calculate the new position of the car
newCarPosition.x = circleCenter.x + r*cos(theta);
newCarPosition.y = circleCenter.y + r*sin(theta);

// rotate the car appropriately (pseudo-code)
[car rotateByAngle:theta];
carAngle = carAngle + theta;

即使汽车已经旋转,这也应该将转弯圆的中心保持在适当的点。

于 2009-07-10T22:10:14.683 回答