"Анимируем объекты с использованием физики в...
TRANSCRIPT
Анимируем объекты с использованием физики
в JavaScript
Иванова Елена @liveldi90
Фронтенд разработчик Astroshock
25 июня 2015
СОДЕРЖАНИЕ
Конструкторы Движение Сила трения
Ускорение и прыжки
Пружины и колебания
Анимация
АНИМАЦИЯ
4 / 42
5 / 42
setTimeout(func, 1000/fps); setInterval(func, 1000/fps); requestAnimaponFrame(func);
6 / 42
6 / 42
setTimeout(func, 1000/fps); setInterval(func, 1000/fps); requestAnimaponFrame(func);
var t0 = 0, dt; funcpon onTimer() { var t1 = new Date().getTime(); dt = t1 — t0; t0 = t1; // Меняем кадры
}
7 / 42
КОНСТРУКТОРЫ
ОБЪЕКТ — параметры var Obj = funcpon (ops) { this.$el // Доступ к элементу this.mass // Масса
this.x // Позиция x, y this.y
this.vx // Cкорость по x, y this.vy … };
9 / 42
ОБЪЕКТ — методы
Obj.prototype.pos Obj.prototype.velo
10 / 42
ВЕКТОР — параметры
var Vector = funcpon (x, y) { this.x = x; this.y = y; };
11 / 42
ВЕКТОР — методы
Vector.prototype.length() Vector.prototype.add(vec) Vector.prototype.subtract(vec) Vector.prototype.mulpply(k) Vector.prototype.divide(k)
12 / 42
ВЕКТОР — методы
Vector.prototype.addScaled = funcpon (vec, k) {
return new Vector( this.x + k * vec.x,
this.y + k * vec.y); };
13 / 42
ДВИЖЕНИЕ
15 / 42
16 / 42
obj.pos = new Vector(10, 0); obj.velo = new Vector(60, 0);
17 / 42
obj.pos = new Vector(10, 0); obj.velo = new Vector(60, 0); funcpon move() { obj.pos = obj.pos.addScaled(obj.velo, dt);
}
17 / 42
СИЛА ТРЕНИЯ
КИНЕТИЧЕСКАЯ ЭНЕРГИЯ 19 / 42
20 / 42
МОЩНОСТЬ
МОЩНОСТЬ
СИЛА ТРЕНИЯ
20 / 42
МОЩНОСТЬ
СИЛА ТРЕНИЯ
20 / 42
ИЗМЕНЕНИЕ КИНЕТИЧЕСКОЙ ЭНЕРГИИ
21 / 42
ИЗМЕНЕНИЕ КИНЕТИЧЕСКОЙ ЭНЕРГИИ
21 / 42
var displ = obj.pos.subtract(obj.pos0); obj.velo = displ.divide((t1 — t0) * kSmoothing); ke = new Vector( 0.5 * obj.mass * obj.vx * obj.vx,
0.5 * obj.mass * obj.vy * obj.vy);
НАЧАЛЬНЫЕ РАСЧЕТЫ 22 / 42
var powerLoss = new Vector( powerLossFactor * obj.vx * obj.vx * dt,
powerLossFactor * obj.vy * obj.vy * dt); ke = ke.subtract(powerLoss);
ОБНОВЛЕНИЕ КИНЕТИЧЕСКОЙ ЭНЕРГИИ
23 / 42
obj.velo = new Vector( Math.sqrt(2 * ke.x / obj.mass), Math.sqrt(2 * ke.y / obj.mass)
);
ОБНОВЛЕНИЕ СКОРОСТИ 24 / 42
ОБНОВЛЕНИЕ ПОЗИЦИИ
obj.pos = obj.pos.addScaled(obj.velo, dt);
25 / 42
ДОБАВЛЕНИЕ МОЩНОСТИ
if (applyThrust) { ke = ke.add(new Vector( powerApplied * dt, powerApplied * dt) );
}
26 / 42
УСКОРЕНИЕ И ПРЫЖКИ
Сила сопротивления (D)
Гравитация (W)
УСКОРЕНИЕ 28 / 42
УСКОРЕНИЕ 29 / 42
30 / 42
obj.force = new Vector(0, obj.mass * g — k * obj.vy);
obj.acc = force.divide(obj.mass);
РАСЧЕТ СИЛЫ
ОБНОВЛЕНИЕ УСКОРЕНИЯ
31 / 42
obj.velo = obj.velo.addScaled(obj.acc, dt);
obj.pos = obj.pos.addScaled(obj.velo, dt);
ОБНОВЛЕНИЕ СКОРОСТИ
ОБНОВЛЕНИЕ ПОЗИЦИИ
УДАР О ПОВЕРХНОСТЬ 32 / 42
33 / 42
ЗАЛИПАНИЯ
34 / 42
floor = new Vector(0, winH — floorH); var displ = floor.subtract(obj.pos); if (displ.y — obj.radius <= 0) { obj.y = floor.y — obj.radius; obj.vy *= —vfac; }
ПРОВЕРКА УДАРА
34 / 42
floor = new Vector(0, winH — floorH); var displ = floor.subtract(obj.pos); if (displ.y — obj.radius <= 0) { obj.y = floor.y — obj.radius; obj.vy *= —vfac; }
ПРОВЕРКА УДАРА
34 / 42
floor = new Vector(0, winH — floorH); var displ = floor.subtract(obj.pos); if (displ.y — obj.radius <= 0) { obj.y = floor.y — obj.radius; obj.vy *= —vfac; }
ПРОВЕРКА УДАРА
ПРУЖИНЫ И КОЛЕБАНИЯ
36 / 42
37 / 42
ПРОСТОЕ ГАРМОНИЧЕСКОЕ КОЛЕБАНИЕ
Закон Роберта Гука
Закон Гука Второй закон Ньютона
УСКОРЕНИЕ 38 / 42
39 / 42
var displ = obj.pos.subtract(center); var restoring = displ.mulpply(—kSpring); var damping = obj.velo.mulpply(—kDamping); obj.force = Vector.add([restoring, damping]);
РАСЧЕТ СИЛЫ
40 / 42
41 / 42
cursorForce = new Vector(0, 0); if (cursorPos.x >= 0) {
displCursor = obj.pos.subtract(cursorPos); cursorDist = displCursor.length();
if (cursorDist > 1 &&
cursorDist <= cursorForceZoomed) { var func = cursorForceZoomed / (cursorDist * cursorDist ) cursorForce = displCursor.mulpply(func);
} }
РАСЧЕТ СИЛЫ КУРСОРА
41 / 42
cursorForce = new Vector(0, 0); if (cursorPos.x >= 0) {
displCursor = obj.pos.subtract(cursorPos); cursorDist = displCursor.length();
if (cursorDist > 1 &&
cursorDist <= cursorForceZoomed) { var func = cursorForceZoomed / (cursorDist * cursorDist ) cursorForce = displCursor.mulpply(func);
} }
РАСЧЕТ СИЛЫ КУРСОРА
41 / 42
cursorForce = new Vector(0, 0); if (cursorPos.x >= 0) {
displCursor = obj.pos.subtract(cursorPos); cursorDist = displCursor.length();
if (cursorDist > 1 &&
cursorDist <= cursorForceZoomed) { var func = cursorForceZoomed / (cursorDist * cursorDist ) cursorForce = displCursor.mulpply(func);
} }
РАСЧЕТ СИЛЫ КУРСОРА
41 / 42
cursorForce = new Vector(0, 0); if (cursorPos.x >= 0) {
displCursor = obj.pos.subtract(cursorPos); cursorDist = displCursor.length();
if (cursorDist > 1 &&
cursorDist <= cursorForceZoomed) { var func = cursorForceZoomed / (cursorDist * cursorDist ) cursorForce = displCursor.mulpply(func);
} }
РАСЧЕТ СИЛЫ КУРСОРА
cursorForce = new Vector(0, 0); if (cursorPos.x >= 0) {
displCursor = obj.pos.subtract(cursorPos); cursorDist = displCursor.length();
if (cursorDist > 1 &&
cursorDist <= cursorForceZoomed) { var func = cursorForceZoomed / (cursorDist * cursorDist ) cursorForce = displCursor.mulpply(func);
} }
41 / 42
РАСЧЕТ СИЛЫ КУРСОРА
Иванова Елена @liveldi90
physicsdemos.liveldi.ru