Вопрос

Я бы хотел отклонить мяч на угол, в зависимости от того, где он ударяет по веслу. Прямо сейчас я изменяю только координату y, что приводит к неинтересному отклонению. Он будет наклоняться, но не зависит от места удара о весло. Я хотел бы что-нибудь более веселое. Скорость, импульс, масса и другие факторы не должны приниматься во внимание. Просто угол в зависимости от места удара весла. Я читал это ошибка (NAN) при обнаружении столкновений в приложении для iphone , но это кажется слишком сложным для того, что я ищу. Есть ли более простой способ рассчитать прогиб?

Объекты - это два UIImageView.

Это было полезно?

Решение

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

Я никогда не делал ни iPhone, ни объективного C-кодирования, поэтому просто напишу что-нибудь в псевдо-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 градусов, так как это будет довольно сложно восстановить. Так как я собираюсь использовать в качестве нового velY ImpactRange, я собираюсь уменьшить его до значения от -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, но я надеюсь, что вы поняли основную идею).

РЕДАКТИРОВАТЬ : добавьте некоторые мысли о получении воздействия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;

Вероятно, вам следует проверить значение responseRange, чтобы оно действительно находилось в диапазоне от -1 до 1, чтобы шар не попал в звезды или что-то в этом роде.

Другие советы

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

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

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

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

Следующий код (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);
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top