Страницы

среда, 26 декабря 2012 г.

Ограничения (Constraints) в Nape

      Ограничения в Nape связывают тела между собой. Любое ограничение можно отключить установив свойство ignore в true.
      Большинство типов Ограничений - это позиционные ограничения, такие как PivotJoint, который, учитывая две локальных позиции на Телах, блокирует эти точки вместе, что позволяет телам взаимно вращаться вокруг той точки. Некоторым ограничениям дают верхние и нижние пределы, например для DistanceJoint, который блокирует точки на двух Телах, чтобы тела были в данном диапазоне значений.
      Все позиционные ограничения могут быть установлены как жесткие (stiff) или эластичные (elastic). При использовании эластичных ограничений мы можем установить частоту и затухание для управления эластичным поведением, и можем установить maxForce и maxError, чтобы определить, сколько силы используется, и сколько ошибок мы решаем в секунду.


constraint.stiff = false;
constraint.frequency = 30; //Hz
constraint.damping = 10; //Large over-dampening

// Constraint will use no more than 1000 Newtons to resolve constraint.
constraint.maxForce = 1000;
// Constraint will resolve no more than 10 units of positional error per second.
constraint.maxError = 10;
// The exact behaviour of maxError is dependent on constraint formulation.


      Устанавливая надлежащие свойства, мы можем также разрешить разрыв Ограничения, если значение ошибки становится слишком большим, или для эластичных ограничений, если сила, требуемая, чтобы разорвать ограничение, становится слишком большой. С системой обратных вызовов мы можем получить обратный вызов, когда ограничение разорвано.


constraint.breakUnderError = true;
constraint.maxError = 10; // If constraint exceeds 10 units of error, constraint will break.
constraint.removeOnBreak = false; // Instead of removing constraint, it will simply be de-activated when broken.


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

     В Nape есть 7 предопределенных ограничений и плюс "Пользовательское ограничение"

  • PivotJoint
  • WeldJoint
  • DistanceJoint
  • AngleJoint
  • LineJoint
  • MotorJoint
  • PulleyJoint
  • UserConstraint (Пользовательское ограничение)
     Рассмотрим подробнее использование DistanceJoint на взаимодействии Шарика и Кубика из прошлого примера:

package
{ 
    import flash.display.Sprite;
    import flash.events.Event;
    import nape.constraint.DistanceJoint;
    import nape.phys.Compound;
    import nape.phys.Material;
 
    import nape.geom.Vec2;
    import nape.phys.Body;
    import nape.phys.BodyType;
    import nape.shape.Circle;
    import nape.shape.Polygon;
    import nape.space.Space;
    import nape.util.BitmapDebug;
    import nape.util.Debug;
 
    public class Main extends Sprite
    {
        private var space:Space;
        private var debug:Debug;
  
        private var ball:Body;
        private var cube:Body;
  
        //Ограничение для Шара и Кубика
        private var joint:DistanceJoint;

 
        public function Main():void
        {
            super();
 
            if (stage != null) {
                initialise(null);
            }
            else {
                addEventListener(Event.ADDED_TO_STAGE, initialise);
            }
        }
 
        private function initialise(ev:Event):void
        {
            if (ev != null) {
                removeEventListener(Event.ADDED_TO_STAGE, initialise);
            }
 
            var gravity:Vec2 = Vec2.weak(0, 900);
            space = new Space(gravity);
 
            debug = new BitmapDebug(stage.stageWidth, stage.stageHeight,
                stage.color);
   
            //Отображать Ограничения
            debug.drawConstraints = true;
            addChild(debug.display);
   
            setUp();
 
            stage.addEventListener(Event.ENTER_FRAME, enterFrameHandler);
        }
 
        private function setUp():void
        {
            var w:int = stage.stageWidth;
            var h:int = stage.stageHeight;
   
            // Пол
            var floor:Body = new Body(BodyType.STATIC);
            floor.shapes.add(new Polygon(Polygon.regular(320, 100, 6, 0, false),
                new Material(0, 0.1, 0.1, 100, 0.0001)));
            
            floor.position.setxy(300, 300);
            floor.space = space;  
   
            ball = new Body(BodyType.DYNAMIC);
            ball.shapes.add(new Circle(30, null, new Material(0, 3, 3, 3, 30)));
            ball.position.setxy(200, 176);
            ball.angularVel = 55;
            ball.space = space;
   
            cube = new Body(BodyType.DYNAMIC);
            cube.shapes.add(new Polygon(Polygon.box(60, 60),
                new Material(0, 0.05, 0.05, 2, 0.01)));
            cube.position.setxy(100, 220);
            cube.space = space;
   
            //Ограничение для шара и кубика
            joint = new DistanceJoint(ball, cube, ball.localCOM,
                cube.worldPointToLocal(Vec2.get(cube.position.x + 100,
                    cube.position.y - 10)), 50, 90);
            
            //joint.stiff = false;
            joint.space = space;
        }
 
        private function enterFrameHandler(ev:Event):void 
        {
            space.step(1 / stage.frameRate);
 
            joint.anchor1 = ball.localCOM;
            joint.anchor2 = cube.localCOM +
                cube.worldPointToLocal(Vec2.get(cube.position.x + 100,
                    cube.position.y - 10));
   
            debug.clear();
            debug.draw(space);
            debug.flush();
        }
    }
}

      Работу этого примера можно посмотреть тут.

      Подробнее про типы ограничений можно посмотреть на примере.

Комментариев нет:

Отправить комментарий