Nape 2 — Линейное и угловое торможение для мира

Иногда требуется задать линейное и угловое торможение для всего мира.
Например, вы делаете бильярд или другую какую нибудь top-down игру (гонки напр.). Скорее всего вы будете делать следующим образом — зададите гравитацию в 0,0 и будете двигать объектами. Но, надо как нибудь задать торможение объектам, чтобы объекты останавливались через некоторое время (шары вечно летать по столу не будут). В старом Nape для тела была опция Properties, где и задавались значения в новом этого нету. Есть конечно Material, но он будет работать только в случае столкновения с другими объектами, а в этом случае никакого постороннего тела, которое бы задавало трение, нет.

Одно из простых решений это задать миру параметры торможения. Это будет работать так — каждый шаг ко всем объектам будет применено мировое торможение.
У класса Space есть свойства worldLinearDrag и worldAngularDrag, которые за это отвечают. По умолчанию установлены значения 0.015, при таких значениях тело очень слабо тормозит (возможны значения от 0 (нету торможения) до бесконечности).

_space.worldLinearDrag = 0.3;
_space.worldAngularDrag = 0.9;

Минус этого подхода в том, что вы не можете задать каждому телу отдельное торможение.

Второй способ это самостоятельно реализовать торможение, например так (0 — отсутствие торможения — до бесконечности):

private var _dampening:Number = 0.5; // 0- полное отсутсвие торможения - до бесконечности
private var _timeStep:Number = 1/30.0;
private function update(event:Event):void
{
	var vel:Vec2 = _body.velocity;
	var velX:int = 0;
	var velY:int = 0;
	var ang:int = 0;
 
	velX = (vel.x + ((-1) * vel.x * _dampening * _timeStep)) * 1000;
	velY = (vel.y + ((-1) * vel.y * _dampening * _timeStep)) * 1000;
	vel.x = velX / 1000.0;
	vel.y = velY / 1000.0;
 
	ang = (_body.angularVel + ((-1) * _body.angularVel * _dampening * _timeStep)) * 1000;
	_body.angularVel = ang / 1000.0;
}

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

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

This movie requires Flash Player 9

Поделиться в соц. сетях

Опубликовать в LiveJournal
Опубликовать в Google Plus
  • Hitek55

    Спасибо! Искал как реализовать торможение для тел

    • VirtualMaestro

      Всегда пожалуйста

  • Alex

    Спасибо отличный способ, единственное, не понятно зачем умножать и сразу же делить на 1000?

    • VirtualMaestro

      Дело в том, что умножением/делением на 1000 мы обрезаем дробную часть значения по третьему знаку. Без этого хака дробное значение теоретически могло бы быть бесконечно большим, а нам этого не надо, такая своего рода оптимизация.