Im, не уверенный, почему но если я изменяю каскадный тип для УДАЛЕНИЯ его работы хорошо....
@OneToMany(mappedBy = "fileDetailId.conversation",cascade = CascadeType.REMOVE)
private Set<FileDetailDao> fileDetailDaoSet = new HashSet<>();
Все возвращается к уравнениям Ньютона:
F = m * a
s = s_o + v * t + a * t^2 / 2
v = v_o + a * t
В этом случае F
- сила (тяга), a
- ускорение, и м
- масса корабля. s
- текущее местоположение, s_o
- исходное местоположение, v
- скорость, а t
- текущее время.
] Конечно, это прямая линия, поэтому, если вы хотите преобразовать в двух или трех измерениях, вам придется проделать некоторую математику. F
, s
, v
и a
- все векторы, что означает, что их направление одинаково важно. Технически t
также является вектором, но поскольку время обычно идет только в одном направлении, нам не нужно об этом беспокоиться.
2d:
F^2 = F_x^2 + F_y^2 (use Pythagorean theorem to split force into components)
F_x = m * a_x
F_y = m * a_y
s_x = s_o_x + v_x * t + a_x * t^2 / 2
s_y = s_o_y + v_y * t + a_y * t^2 / 2
v_x = v_o_x + a_x * t
v_y = v_o_y + a_y * t
3d:
F^2 = F_x^2 + F_y^2 + F_z^2 (surprisingly, this works)
F_x = m * a_x
F_y = m * a_y
F_z = m * a_z
s_x = s_o_x + v_x * t + a_x * t^2 / 2
s_y = s_o_y + v_y * t + a_y * t^2 / 2
s_z = s_o_z + v_z * t + a_z * t^2 / 2
v_x = v_o_x + a_x * t
v_y = v_o_y + a_y * t
v_z = v_o_z + a_z * t
Теперь, чтобы отрегулировать вашу скорость в зависимости от направления игрока, у вас есть фиксированная общая сила ( F
), чтобы изменить вашу текущую скорость по направлению к игроку. В физике вещи не происходят мгновенно, но ваша цель должна состоять в том, чтобы минимизировать время, за которое происходит изменение ('t').
Это дает вам уравнение в терминах вашего текущего местоположения ( (s_o_x, s_o_y)
или (s_o_x, s_o_y, s_o_z)
) и текущее местоположение вашего оппонента или ваше целевое местоположение ( (s_x, s_y)
или (s_x, s_y, s_z)
) для вашей целевой скорости (не учитывает ускорение).
v_x = (s_x - s_o_x) / t
v_y = (s_y - s_o_y) / t
v_x = (s_x - s_o_x) / t
v_y = (s_y - s_o_y) / t
v_z = (s_z - z_o_y) / t
Мы можем заменить это на наше другое уравнение:
(s_x - s_o_x) / t = v_o_x + a_x * t
(s_y - s_o_y) / t = v_o_y + a_y * t
(s_x - s_o_x) / t = v_o_x + a_x * t
(s_y - s_o_y) / t = v_o_y + a_y * t
(s_z - z_o_y) / t = v_o_z + a_z * t
Затем мы решаем ускорение (это связано с силой, которой мы являемся пытается вычислить).
(s_x - s_o_x) / t^2 - v_o_x / t = a_x
(s_y - s_o_y) / t^2 - v_o_y / t = a_y
(s_x - s_o_x) / t^2 - v_o_x / t = a_x
(s_y - s_o_y) / t^2 - v_o_y / t = a_y
(s_z - z_o_y) / t^2 - v_o_z / t = a_z
Подставьте это в уравнение силы:
F_x = m * (s_x - s_o_x) / t^2 - m * v_o_x / t
F_y = m * (s_y - s_o_y) / t^2 - m * v_o_y / t
F_x = m * (s_x - s_o_x) / t^2 - m * v_o_x / t
F_y = m * (s_y - s_o_y) / t^2 - m * v_o_y / t
F_z = m * (s_z - z_o_y) / t^2 - m * v_o_z / t
Теперь решите для t
:
t = (-m * v_o_x +/- sqrt(m^2 * v_o_x^2 - 4 * F_x * m * (s_x - s_o_x))) / 2 / F_x
t = (-m * v_o_y +/- sqrt(m^2 * v_o_y^2 - 4 * F_y * m * (s_y - s_o_y))) / 2 / F_y
t = (-m * v_o_x +/- sqrt(m^2 * v_o_x^2 - 4 * F_x * m * (s_x - s_o_x))) / 2 / F_x
t = (-m * v_o_y +/- sqrt(m^2 * v_o_y^2 - 4 * F_y * m * (s_y - s_o_y))) / 2 / F_y
t = (-m * v_o_z +/- sqrt(m^2 * v_o_z^2 - 4 * F_z * m * (s_z - s_o_z))) / 2 / F_z
Время должно сходиться, поэтому времена будут одинаковыми! Это дает нам систему уравнений для каждой координаты (плоскости и сферы). Обратите внимание, что существует несколько возможных значений, но некоторые из них связаны с мнимыми числами, поэтому вам придется исключить эти решения:
(-m * v_o_x +/- sqrt(m^2 * v_o_x^2 - 4 * F_x * m * (s_x - s_o_x))) / 2 / F_x
= (-m * v_o_y +/- sqrt(m^2 * v_o_y^2 - 4 * F_y * m * (s_y - s_o_y))) / 2 / F_y
F^2 = F_x^2 + F_y^2
(-m * v_o_x +/- sqrt(m^2 * v_o_x^2 - 4 * F_x * m * (s_x - s_o_x))) / 2 / F_x
= (-m * v_o_y +/- sqrt(m^2 * v_o_y^2 - 4 * F_y * m * (s_y - s_o_y))) / 2 / F_y
= (-m * v_o_z +/- sqrt(m^2 * v_o_z^2 - 4 * F_z * m * (s_z - s_o_z))) / 2 / F_z
F^2 = F_x^2 + F_y^2 + F_z^2
Решите для (F_x, F_y)
или (F_x, F_y, F_z )
координирует, и у вас есть необходимая сила.
Дайте мне знать, если у вас возникнут вопросы или вы обнаружите ошибки в моих математических расчетах.
Вы должны мыслить в терминах правильной физики. У вас есть скорость, и вы хотите добавить ускорение. Вот и все, что нужно сделать - ускорение - это постепенное изменение скорости, которое будет притягивать противника к игроку, позволять ему пролететь мимо, замедлить (или повернуть), а затем вернуться к игроку.
Ускорение измеряется как d (скорость) / время. Вы хотите ускоряться по направлению к игроку в любой момент времени, поэтому каждый интервал (секунда, сотая доля секунды или что угодно по вашему выбору) вам нужно добавлять вектор между противником и игроком, умноженный на некоторую константу, к вашей скорости.
Velocity = Velocity + c * (Player-Enemy vector)
Константа c будет зависеть от того, насколько быстро вы хотите ускоряться по направлению к игроку и как часто вы обновляете свою скорость.
Если вы хотите «ограничить» максимальную скорость врага, чтобы он не двигался » t продолжать увеличивать величину своей скорости до бесконечности, вы также можете сделать это.
Velocity = Velocity * (Maximum magniture / |Velocity|)
РЕДАКТИРОВАТЬ: чтобы уточнить, добавление скорости просто означает добавление составляющих векторов. Итак,
Vx = Vx + c * Ax
Vy = Vy + c * Ay
где V - скорость, а A - ускорение. Величина измеряется как sqrt (Vx ^ 2 + Vy ^ 2)
, то есть гипотенуза прямоугольного треугольника. Итак, если вы хотите, чтобы максимальная скорость врага была равна m,
Vx = Vx * ( m / sqrt(Vx^2 + Vy^2)
Vy = Vy * ( m / sqrt(Vx^2 + Vy^2)
Некоторое время назад я написал простую игру с астероидами, у которой был «союзник» корабль, который будет выслеживать астероиды и стрелять в них за вас. По сути, он нашел ближайший астероид, затем начал плавно поворачиваться к нему и следовать за ним. К сожалению, у меня больше нет кода, но, если мне не изменяет память, я думаю, что я немного поправлял корабль каждый ход, тогда, если астероид находился далеко, я ускорялся, но если он был близко, я пытался соответствовать скорости астероида. На самом деле это было довольно круто и требовало минимум алгебры.
Лучший способ сделать это - взять 2 радиан и lerp между ними, обрабатывая перенос. (возможно, путем добавления или вычитания 2pi, если необходимо). Затем преобразуйте его в единичный вектор. Затем умножьте это на скорость, с которой корабль разгоняется, и готово!
Подобные проблемы я решал профессионально и советую начинать с простых версий и работать над ними. Убедитесь, что вы получаете ожидаемое поведение на каждом этапе, прежде чем пробовать следующий.
Теперь, если вам нужен искатель, который не может включить ни копейки, но должен изгибаться , все становится сложно ...
Один простой способ (не соответствующий физике) - это вычислить «желаемую скорость» вашего врага, а затем скорректировать текущую скорость врага в соответствии с ней, учитывая любые ограничения сверху или минимальную скорость, которую он имеет.
Например, в небольшой 2-й игре, которую я написал ( http://wordwarvi.sourceforge.net ), есть «ракеты с тепловым наведением». Это выглядит довольно странно, если ракеты останавливаются в воздухе, чтобы развернуться. Я сделал следующее: я вычислил «желаемую скорость» по направлению к игроку. Это просто делается с помощью «похожих треугольников». Я нахожу расстояние до игрока в X и Y, и что больше,
Есть всего несколько указателей, чтобы сделать это правильно и легко. 1) проще всего работать с векторами, чем писать все два или три раза. 2) все будет выглядеть правильно, если вы управляете силой (которая фактически является ускорением, поскольку A = F / масса), а затем динамически изменяете скорость и положение.
Ваш основной цикл для реалистичного движения выглядит так (где CAP - векторы и dt - ваш временной шаг):
while (motion) {
A = get_acceleration(X, V, A, X_target, V_targer, A_target)
V += A*dt // V is the integral of A
X += V*dt // X is the integral of V
}
И действительно, это все, потому что вы динамически эволюционируете.
Затем вам нужно решить, как определить ваше ускорение, то есть написать get_acceleration
. Здесь есть несколько вариантов, которые зависят от множества факторов, и реальные охотники используют несколько стратегий. Например, если у вас большая тяга относительно вашей массы (т. Е. высокое ускорение) вы, вероятно, просто хотите лететь прямо в цель; но если у вас большая масса относительно вашей тяги, вы, вероятно, захотите выбрать курс на перехват. Если вы хотите замедлиться по мере приближения к цели, вы можете изменить ускорение, когда | X-X_target |
станет маленьким (т.е. они приближаются) и / или их скорости близки. Кроме того, демпфирование может помочь вещам не колебаться, и для этого добавьте термин к ускорению, например -c * (V-V_target)
. Я предлагаю вам поиграть с ними, пока вы не получите что-то, что соответствует внешнему виду и ощущениям, к которым вы стремитесь.
| X-X_target |
станет маленьким (т.е. они приближаются) и / или их скорости близки. Кроме того, демпфирование может помочь вещам не колебаться, и для этого добавьте член к ускорению, например -c * (V-V_target)
. Я предлагаю вам поиграть с ними, пока вы не получите что-то, что соответствует внешнему виду и ощущениям, к которым вы стремитесь. вы можете изменить ускорение, когда | X-X_target |
станет маленьким (т.е. они приближаются) и / или их скорости близки. Кроме того, демпфирование может помочь вещам не колебаться, и для этого добавьте термин к ускорению, например -c * (V-V_target)
. Я предлагаю вам поиграть с ними, пока вы не получите что-то, что соответствует внешнему виду и ощущениям, к которым вы стремитесь. Вы можете получить желаемый эффект, обеспечив плавное изменение скорости , а не тяги . Таким образом, если противник пролетает мимо игрока, он может немедленно изменить свое ускорение, что замедлит его и, в конечном итоге, изменит направление его движения.
Вы можете добиться этого, изменяя скорость во время каждой итерации на небольшую величину, которая в зависимости от расстояния от врага до игрока:
while (game_in_progress)
{
// Distance from enemy to player. The larger the
// distance, the greater the acceleration will be.
delta.x = player.x - enemy.x
delta.y = player.y - enemy.y
// Accelerate by changing velocity based on distance,
// where 'scale' is sufficiently small. (Limit v to
// some maximum if you choose; likely to be unnecessary.)
v.x += delta.x * scale
v.y += delta.y * scale
// Update the enemy's position.
enemy.x += v.x
enemy.y += v.y
}
Вычисляя значения x
и y
независимо, вы можете избавить себя от головной боли, связанной с векторами, углами и одновременным
Аналогичным образом, признавая, что ускорение (тяга) - это просто изменение скорости, которое, в свою очередь, является изменением положения,