Страницы

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

Объединения (Compounds) в Nape

     Объединения (составные объекты) - это логическая группировка Тел, Ограничений и других объединений в единый объект.

     Пример объединения:

var c = new Compound();
body1.compound = c;
body2.compound = c;
constraint.compound = c;
c.space = space;


Объединения (Compounds) в Nape

     Когда дело доходит до копирования объединений, можно столкнуться с тем, что не все Ограничения привязаны к Телам. На схеме есть ограничение Co1, которое присвоено Объединению C2, но ссылка на Тело B2 находится вне видимости Объединения C2.
     В этом примере, если сделать копию Объединения C1, то все будет хорошо. Но если сделать копию C2, то Ограничение Co1 будет иметь null ссылку на Тело B2, так как Объединение С2 не видит Тело B2.
     В следующем примере покажу как использовать Ограничения и Объединение:

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;
    import nape.shape.Shape;
 
    public class Main extends Sprite
    {
        private var space:Space;
        private var debug:Debug;
  
        private var wheel_front:Body;
        private var wheel_rear:Body;
        private var cabin:Body;
  
        //Ограничение для колес
        private var wheels_joint:DistanceJoint; //Держит расстояние между колес
        private var cabin_front_joint:DistanceJoint; //Амортизатор спереди машины
        private var cabin_rear_joint:DistanceJoint; //Амортизатор сзади машины

        // Объединение - машинка
        private var car:Compound;
 
        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), Material.ice()));
            
            floor.position.setxy(340, 300);
            floor.space = space;  
   
            // Объединение - машина
            car = new Compound();
            //car.cbTypes.add(carType);
      
            // Колесо переднее
            wheel_front = new Body(BodyType.DYNAMIC);
            wheel_front.position.setxy(290, 106);
            var wheel_frontShape:Shape = new Circle(30, null, Material.rubber());
            wheel_frontShape.body = wheel_front; 
            wheel_front.angularVel = 20;
            wheel_front.compound = car;
   
            // Колесо заднее
            wheel_rear = new Body(BodyType.DYNAMIC);
            wheel_rear.position.setxy(200, 106);
            var wheel_rearShape:Shape = new Circle(30, null, Material.rubber());
            wheel_rearShape.body = wheel_rear;  
            wheel_rear.angularVel = 20;
            wheel_rear.compound = car;
   
            // Кузов
            cabin = new Body(BodyType.DYNAMIC);
            cabin.position.setxy(245, 70);
            var cabinShape:Shape = new Polygon(Polygon.box(200, 60), new Material(0, 1, 2, 2, 0.01));
            cabinShape.body = cabin;
            cabin.compound = car;
   
            //Выводим машинку
            car.space = space;
   
            //Ограничение для колес (держит межколесное расстояние)
            wheels_joint = new DistanceJoint(wheel_front, wheel_rear, wheel_front.localCOM,
                wheel_rear.localCOM, 120, 120);
            wheels_joint.compound = car;
   
            //Передний амортизатор
            cabin_front_joint = new DistanceJoint(wheel_front, cabin,
                wheel_front.localCOM, cabin.localCOM, 90, 90);
            cabin_front_joint.compound = car;
   
            //Задний амортизатор
            cabin_rear_joint = new DistanceJoint(wheel_rear, cabin,
                wheel_rear.localCOM, cabin.localCOM, 90, 90);
            cabin_rear_joint.compound = car;
   
            //Выводим машинку со всеми ограничениями
            car.space = space;
        }
 
        private function enterFrameHandler(ev:Event):void 
        {
            space.step(1 / stage.frameRate);
   
            debug.clear();
            debug.draw(space);
            debug.flush();
        }
    }
}

      Реализацию этого примера можно посмотреть тут.

      При использовании объединений удобно их копировать:

var car2:Compound = car.copy();
car2.space = space;


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

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