我想在iPhone上使用Cocos2d来绘制2D汽车并使其以自然方式从左向右转向。
以下是我的尝试:
计算车轮的角度,然后将其移动到车轮指向的目标点。但这会产生一种非常不自然的感觉。汽车漂移了一半时间
之后我开始研究如何从汽车中获得转弯圈,这意味着我需要一些常量,如轴距和汽车的宽度。
经过大量研究,我创建了以下代码:
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不支持的Matrix。
有人可以给我一些关于如何开始这个的指示吗?我一直在寻找示例代码,但我找不到任何代码。
编辑在下面的评论之后 我纠正了常量,我的wheelBase现在是50(精灵高50px),我的carWidth是30(精灵宽度是30px)。
但是现在我遇到了问题,当我的汽车首先“滴答”时,旋转是正确的(也是放置位置),但之后计算似乎是错误的。
转动圆圈的中间位置而不是保持在原始位置。我需要(我认为)是在汽车的每个角度,我需要重新计算转弯圈的原始中心。我认为这很容易,因为我有半径和转角,但我似乎无法弄清楚如何让汽车保持良好的运动。
还有什么指针?
答案 0 :(得分:1)
你有正确的想法。常量是这种情况下的问题。您需要以与视图大小匹配的单位指定wheelBase
和carWidth
。例如,如果屏幕上的汽车图像的轮距为30像素,则使用30作为WheelBase
变量。
这就解释了为什么屏幕上的圆圈太小了。可可正试图画一个只有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;
即使汽车已经旋转,也应该将转弯中心保持在适当的位置。