Автомобиль поворачивая круг и двигая спрайт - PullRequest
2 голосов
/ 11 июля 2009

Я хотел бы использовать Cocos2d на iPhone, чтобы нарисовать двухмерную машину и заставить ее поворачиваться слева направо естественным образом.

Вот что я попробовал:

  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.

Может кто-нибудь дать мне пару советов о том, как это начать? Я искал пример кода, но не могу его найти.

РЕДАКТИРОВАТЬ После комментариев, приведенных ниже Я исправил свои константы, моя wheelBase теперь 50 (спрайт 50 пикселей в высоту), моя carWidth 30 (спрайт 30 пикселей в ширину).

Но теперь у меня проблема в том, что когда моя машина делает первый «тик», вращение правильное (а также размещение), но после этого вычисления кажутся неправильными.

Середина поворотного круга перемещается, а не сохраняется в исходном положении. Что мне нужно (я думаю), так это то, что под каждым углом машины мне нужно пересчитать исходный центр круга поворота. Я думаю, это легко, потому что у меня есть радиус и угол поворота, но я не могу понять, как заставить машину двигаться по кругу.

Есть еще указатели?

1 Ответ

1 голос
/ 11 июля 2009

У вас правильная идея. Константы являются проблемой в этом случае. Вам необходимо указать 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;

Это должно удерживать центр круга поворота в соответствующей точке, даже если автомобиль вращался.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...