#actionscript-3 #game-physics
#actionscript-3 #игра-физика
Вопрос:
Я пытаюсь бросить мяч по дуге, либо по дуге, идущей влево или вправо.
Вот мой код:
var gravity = 2;
this.velocity.y = gravity;
_angle = 5;
var theta:Number;
switch(_direction) {
case "left":
theta = _angle * Math.PI/180;
this.velocity.x = Math.cos(theta) - Math.sin(theta);
break;
case "right":
theta = _angle * Math.PI/180;
this.velocity.x = Math.cos(theta) - Math.sin(theta)
break;
}
this.x = this.velocity.x;
this.y = this.velocity.y;
На самом деле не похоже, что мяч вообще «описывает дугу», это больше похоже на диагональную линию?
Комментарии:
1. Вам нужно добавить гравитационную постоянную, которая будет применяться к вашим значениям скорости. Кроме того, вам нужно задать угол только при первоначальном броске мяча.
2. Привет, я обновил свой код, чтобы отразить эти предложения, но, похоже, он по-прежнему движется по прямой (не кривой)?
3. Кроме того, есть ли способ сделать его дугообразным влево для «левого» и дугообразным вправо для «правого»?
4. Правильно ли я понимаю, что вы действительно спрашиваете о том, как сделать кривой мяч?
5. Кроме того, как это просматривается? Я предполагаю 2d-представление из-за отсутствия оси Z. Это боковой скроллер, сверху вниз, iso …?
Ответ №1:
При броске у вас есть два компонента.
-
Вертикальное ускорение из-за магии гравитации. Это будет да.
-
Горизонтальный компонент: без трения о воздух это постоянная скорость.
Допустим, вы бросаете мяч, и в момент выхода из вашей руки он имеет скорость v0 = (v0x, v0y) и находится в положении p0. Тогда v0x будет постоянным все время.
Скорость мяча в момент времени t будет равна v (t) = (v0x, v0y t * ay)
Для каждого такта вашей анимации добавляйте deltat * v (t) к текущему положению мяча, и все должно быть готово.
Каждый раз, когда мяч отскакивает, вы должны отражать вектор его скорости на поверхности, от которой он отскочил, и вычитать определенный процент от его общей энергии (Ekin Epot, хотя Epot будет равен 0, если мяч находится на земле, а потенциал гончей равен нулю), чтобы получить логарифмический отскок.
Если вам тоже нужно трение о воздух, просто вычитайте определенный небольшой процент от общей энергии с каждым тактом анимации.
Вот некоторый код, не на ActionScript, но я надеюсь, читаемый. (Параметрами ctor являются оба Vector2d; clone() используется неявно, но вы можете догадаться, что это делает):
class Vector2d:
def __init__ (x, y):
self.x = x
self.y = y
def add (other):
self.x = other.x
self.y = other.y
def mulScalar (scalar):
self.x *= scalar
self.y *= scalar
def mulVector (vector) # NOT the cross product
self.x *= vector.x
self.y *= vector.y
class BouncingBall:
AGRAV = ? #gravitational acceleration (mg)
DELTAT = ? #time between ticks
ELASTICITY = ? Elasticity of ball/floor
def __init__ (self, pos, v):
self.pos = pos
self.v = v
def tick (self):
deltapos = self.v.clone ()
deltapos.mulScalar (DELTAT)
self.pos.add (deltapos)
if self.pos.y <= 0: #bounce
self.pos.y = 0 #adjust ball to ground, you need to choose DELTAT small enough so nobody notices
self.v.mulVector (1, -1) #mirror on floor
self.v.mulScalar (ELASTICITY)
self.v.add (0, AGRAV * DELTAT)
Комментарии:
1. Зависит от того, куда указывают его оси. Если это происходит на мониторе, где y = 0 — верхняя часть, а y = 100 — нижняя, было бы рекомендовано добавить положительное ускорение. Лучше пусть вектор ускорения указывает на указанное направление, и сумма всегда будет работать.
2. Я думаю, вы хотели сказать «2. Горизонтальная составляющая: без трения о воздух это постоянная величина » Горизонтальная составляющая ускорения равна нулю, а горизонтальная составляющая скорости постоянна.
3. @all Как пишется «вычитать»?
4. @phoog. Конечно, у вас есть a = (0, -m * g) и v (t) = v0 t * a. Но я попытался выразить это немного проще. По этой причине я не привел дифференциальное уравнение для p (t), но рассказал о тиках анимации.
5. Звучит неплохо, но означает ли приведенная выше формула, что положение x на самом деле не изменится со временем? Я ищу дугу…
Ответ №2:
Уравнения (V = скорость, t = прошедшее время, x0, y0 = координаты точки запуска):
x = x0 Vt * cos(angle)
y = y0 Vt * sin(angle) - (g * t^2) / 2
-------------
^
this is gravity effect, without this
the trajectory would be a line
Вам не нужно различать левое и правое направление, для одного направления V положительное, для другого V отрицательное.
Комментарии:
1. Я обнаружил, что при использовании векторных уравнений быстро накапливаются ошибки округления. Компонентно-векторный подход работает намного лучше.
Ответ №3:
Пара моментов: (отказ от ответственности: я вообще не знаком с actionscript, но я создал пару игр, в которых требовались дуги для броска.)
Во-первых, cos и sin оба имеют границы от -1 до 1. Обычно x отображается в пикселях, поэтому изменение x на 0,5 не приведет к заметной разнице. Кроме того, поскольку x должно быть int, оно даже не будет отображаться.
Во-вторых, вычислительная мощность, необходимая для вычисления этого типа физики, вероятно, не является необходимой — возможно, это так, если вы выполняете точное физическое моделирование.
Также рассмотрим второй комментарий Гиперборея: горизонтальность обычно постоянна. Таким образом, предполагая, что это в стиле скроллера, вам нужно будет изменить компонент y, а не x.