【问题标题】:Car turning circle and moving the sprite汽车转圈和移动精灵
【发布时间】:2009-07-10 21:09:23
【问题描述】:

我想在 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 tutorial,但我无法真正完全转换它,因为它使用了 Cocoa 不支持的矩阵。

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

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

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

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

还有更多指针吗?

【问题讨论】:

  • 矩阵只是多维数组。您应该能够适应/使用参考代码。

标签: iphone objective-c cocos2d-iphone


【解决方案1】:

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

这解释了为什么您的屏幕上的圈子太小了。 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: 来说明问题。希望对你有帮助!

更新(在 cmets 之后):

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

...
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;

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

【讨论】:

  • 我尝试集成您的 cmets,但仍然无法正常工作。我试图在我的原始帖子中解释这一点。希望你能给我更多的建议?
  • 我添加了一些代码来解决圆心移动的问题。试一试!
  • 谢谢,它仍然需要一些调整,但这似乎是一个很好的开始。我会在我完全工作的那一刻更新我的开始帖子!
  • 很高兴听到这个消息。祝项目好运:)
猜你喜欢
  • 1970-01-01
  • 2015-12-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-20
  • 2012-11-27
  • 1970-01-01
相关资源
最近更新 更多