2009-06-18 4 views
1

Я хотел бы отклонить шар под углом в зависимости от того, где он попадает в весло. Прямо сейчас я меняю координату y, что приводит к неинтересному прогибу. Он будет угловым, но независимым от местоположения удара против весла. Мне хотелось бы что-то более увлекательное. Не нужно принимать во внимание скорость, импульс, массу и другие факторы. Просто угол в зависимости от местоположения удара весла. Я читал это Not a number error (NAN) doing collision detection in an iphone app, но это кажется слишком сложным для того, что я ищу. Есть ли более простой способ расчета отклонения?Изменение угла, когда мяч попадает в весло

Объекты - два UIImageViews.

ответ

4

Ну, ничего реалистичного, но вы могли бы что-то сделать, чтобы исходящий угол зависел только от того места, где он попадает.

Я никогда не делал никакого iPhone или объектного кодирования C, поэтому я просто напишу что-нибудь в псевдо-коде.

Сначала я бы рассчитать скорость, которая является длиной вектора скорости, или:

double speed = sqrt(velX * velX + velY * velY); // trigonometry, a^2 + o^2 = h^2 

Тогда мы хотим вычислить новый угол в зависимости от места мы попали весло. Я предполагаю, что вы храните столкновение X в impactX и длину весла в paddleLength. Таким образом, мы можем вычислить исходящий угол. Прежде всего, давайте понять, как рассчитать расстояние так, что мы получаем значение между -1 и 1.

double proportionOfPaddle = impactX/(double) paddleLength; // between 0 and 1 
double impactRange = proportionOfPaddle * 2 - 1; // adjust to -1 and 1 

Давайте предположим, что мы не хотим, чтобы отклонить мяч полностью на стороне, или на 90 градусов, так что было бы довольно сложно восстановиться. Поскольку я собираюсь использовать impactRange как новый velY, я собираюсь масштабировать его, чтобы сказать -0,9 до 0,9.

impactRange = impactRange * 0.9; 

Теперь нам нужно рассчитать velX, чтобы скорость была постоянной.

double newVelX = impactRange; 
double newVelY = sqrt(speed * speed - newVelX * newVelX); // trigonometry again 

Теперь вы возвращаете newVelX и newVelY и у вас есть влияние и в зависимости от скорости отскока.

Удачи вам!

(Возможно, здесь есть ошибки, и я мог бы перевернуть X или Y, но я надеюсь, что вы получите общую идею).

EDIT: Добавление некоторых мыслей о получении удараX.

Предположим, у вас есть ball.center.x и paddle.center.x (не знаете, как вы его называете, но предположим, что paddle.center.x предоставит нам центр весла), мы должен быть в состоянии рассчитать impactRange.

Нам также нужен радиус шара (я буду использовать ball.width как диаметр) и размер лопасти (paddle.width?).

int ballPaddleDiff = paddle.center.x - ball.center.x; 
int totalRange = paddle.width + ball.width; 

Наименьшее значение для ballPaddleDiff будет, когда мяч просто прикасаясь к поверхности весла. Тогда ballPaddleDiff будет paddle.width/2 + ball.width/2. Таким образом, новый impactRange бы, поэтому,

double impactRange = ballPaddleDiff/(double) totalRange/2; 

Вы, вероятно, следует проверить impactRange так, что он на самом деле находится в пределах от -1 и 1, так что мяч не отстреливают на звезды или что-то.

+0

Отлично! Это было просто, чтобы встать и работать. Я не хранил значение impactX. Я просто проверяю, находится ли шар в прямоугольнике весла и обратный ball.center.y. Я пробовал использовать ball.center.x для impactX, но иногда мяч попадает в край и подпрыгивает прямо вверх. Как вы вычисляете impactX? – 4thSpace

0

Вы не обязательно хотите реалистично, вы хотите весело провести время. Это не всегда одно и то же. Если вы хотите реалистично, вы не можете выбрасывать скорость, импульс, массу и т. Д. В обычной игре в пинг-понг точка, в которой он попадает на весло, не имеет большого значения, theres не сладкое место, как на теннисной ракетке ,

Разработка математической функции, которая будет возвращать выходной вектор, или вектор скорости, и единичный вектор, представляющий выходной угол и скорость шара, задавая угол ввода, скорость, точку удара на лопасти и скорость лопатка.

Мы ожидаем, что угол выхода = -1 *. Скорость вывода также должна была бы составлять -1 * входной скорости. Поэтому, если вы хотите его смешивать, настройте их. Вы можете увеличить выходной угол, пропорциональный расстоянию от центра лопасти. Вы также можете увеличить угол или скорость, пропорциональную скорости лопасти при ее ударе.

Существует много способов, которыми вы могли бы это сделать, поэтому я не могу точно сказать, какую именно функцию вы будете использовать, вам нужно будет понять это с помощью тестирования и игры. Если вам по-прежнему нужна дополнительная информация, добавьте больше деталей к вашему вопросу.

+0

Спасибо. Я отредактировал вопрос, чтобы отразить «веселье», а не реалистично, о чем вы правы. Но мне все равно хотелось бы дать совет по настройке кода. Как упоминалось в OP, я хотел бы следовать более простому пути выполнения вычислений. – 4thSpace

0

Следующий код (C++, но достаточно простой для преобразования в ObjC), принимает входящий 2D-вектор и отражает его на основе нормали поверхности (лица вашей летучей мыши).

Вы можете добавить случайный «забавный фактор», рандомизировав смещение, которое вы либо примените к «скаляру», либо чтобы изменить скорость или нормальную поверхность, чтобы изменить угол отражения.

Я использую это в моем iPhone проекта, и он работает отлично :)

void vec2ReflectScalar(vec2& vResult, const vec2& v1, const vec2& normal, float scalar) 
{ 
    vec2 _2ndotvn; 
    float dotVal = vec2DotProduct(v1, normal); 

    vec2Scale(_2ndotvn, normal, scalar * 2.f * dotVal); 
    vec2Subtract(vResult, v1, _2ndotvn); 
} 

void vec2Reflect(vec2& vResult, const vec2& v1, const vec2& normal) 
{ 
    vec2ReflectScalar(vResult, v1, normal, 1.f); 
}