汽车转动圈和移动精灵

时间:2009-07-10 21:09:23

标签: iphone objective-c cocos2d-iphone

我想在iPhone上使用Cocos2d来绘制2D汽车并使其以自然方式从左向右转向。

以下是我的尝试:

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

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

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

    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)。

    但是现在我遇到了问题,当我的汽车首先“滴答”时,旋转是正确的(也是放置位置),但之后计算似乎是错误的。

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

    还有什么指针?

1 个答案:

答案 0 :(得分:1)

你有正确的想法。常量是这种情况下的问题。您需要以与视图大小匹配的单位指定wheelBasecarWidth。例如,如果屏幕上的汽车图像的轮距为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;

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