Advertisement
liuwong

nape example: fat slice

Feb 11th, 2013
116
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. package example
  2. {
  3.     import flash.display.DisplayObjectContainer;
  4.     import flash.display.Sprite;
  5.     import flash.events.MouseEvent;
  6.     import nape.geom.GeomPoly;
  7.     import nape.geom.GeomPolyList;
  8.     import nape.geom.GeomVertexIterator;
  9.     import nape.geom.Vec2;
  10.     import nape.geom.Vec2List;
  11.     import nape.phys.Body;
  12.     import nape.phys.BodyType;
  13.     import nape.phys.Material;
  14.     import nape.shape.Polygon;
  15.     import nape.shape.Shape;
  16.     import nape.shape.ShapeIterator;
  17.    
  18.     /**
  19.      * ...
  20.      * @author liu wong
  21.      *
  22.      */
  23.    
  24.     public class fatSlice extends baseExample
  25.     {
  26.         private const borderArray:Array = [
  27.             new Vec2(0, 0),
  28.             new Vec2(640, 0),
  29.             new Vec2(640, 480),
  30.             new Vec2(0, 480)
  31.             ];
  32.            
  33.         private var balls:Array/*Body*/;
  34.        
  35.         private var srcBorder:Vec2List;
  36.        
  37.         private var mouse:Boolean = false;
  38.         private var segmentA:Vec2;
  39.         private var segmentB:Vec2;
  40.        
  41.         private var mainSprite:Sprite;
  42.        
  43.         private var borderBody:Body;
  44.        
  45.         public function fatSlice(prnt:DisplayObjectContainer):void
  46.         {
  47.             super(prnt);
  48.         }
  49.        
  50.         override protected function init():void
  51.         {
  52.             super.init();
  53.            
  54.             space.gravity.setxy(0, 0);
  55.             space.worldAngularDrag = 0;
  56.             space.worldLinearDrag = 0;
  57.            
  58.             var points:Array = [
  59.                 new Vec2(100, 100),
  60.                 new Vec2(500, 100),
  61.                 new Vec2(500, 400),
  62.                 new Vec2(100, 400)
  63.                 ]; 
  64.                
  65.             var poly:GeomPoly = new GeomPoly(points);
  66.             srcBorder = geomPolyToVec2List(poly, true);
  67.            
  68.             segmentA = new Vec2();
  69.             segmentB = new Vec2();
  70.            
  71.             mainSprite = new Sprite();
  72.             addChild(mainSprite);
  73.            
  74.             var k:int = 5;
  75.             var i:int;
  76.            
  77.             var b:Body;
  78.             var m:Material = new Material(1, 1, 1, 1, 0);
  79.            
  80.             balls = new Array();
  81.            
  82.             for (i = 0; i < k; i++)
  83.             {
  84.                 b = addCircle(320, 240, 8);
  85.                 b.setShapeMaterials(m);
  86.                 b.applyImpulse(Vec2.fromPolar(100, i * (Math.PI * 2 / k)), b.position);
  87.                
  88.                 balls.push(b);
  89.             }
  90.            
  91.             b = new Body(BodyType.STATIC, new Vec2(0, 0));
  92.             var vl:Vec2List = convert(srcBorder);
  93.            
  94.             vec2ListToShapes(vl, b);
  95.            
  96.             borderBody = b;
  97.            
  98.             b.space = space;
  99.            
  100.             stage.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
  101.             stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
  102.             stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
  103.         }
  104.        
  105.         private function onMouseDown(event:MouseEvent):void
  106.         {
  107.             mouse = true;
  108.            
  109.             segmentA.setxy(mouseX, mouseY);
  110.         }
  111.        
  112.         private function onMouseUp(event:MouseEvent):void
  113.         {
  114.             mouse = false;
  115.            
  116.             segmentB.setxy(mouseX, mouseY);
  117.            
  118.             mainSprite.graphics.clear();
  119.            
  120.             if (segmentA.sub(segmentB).length < 1)
  121.                 return;
  122.                
  123.             var cr:cutResult = cut(new GeomPoly(srcBorder), segmentA, segmentB, checkBalls);
  124.            
  125.             if (cr == null)
  126.                 return;
  127.                
  128.             if (cr.result == null)
  129.                 return;
  130.                
  131.             if (cr.destroy.length < 1)
  132.                 return;
  133.                
  134.             if (borderBody)
  135.             {
  136.                 borderBody.space = null;
  137.             }
  138.            
  139.             borderBody = new Body(BodyType.STATIC, new Vec2(0, 0));
  140.                
  141.             srcBorder = geomPolyToVec2List(cr.result, cr.result.isClockwise());
  142.            
  143.             var vl:Vec2List = convert(srcBorder);
  144.             vec2ListToShapes(vl, borderBody);
  145.            
  146.             borderBody.space = space;
  147.         }
  148.        
  149.         private function onMouseMove(event:MouseEvent):void
  150.         {
  151.             if (mouse == false)
  152.                 return;
  153.            
  154.             segmentB.setxy(mouseX, mouseY);
  155.            
  156.             mainSprite.graphics.clear();
  157.            
  158.             mainSprite.graphics.lineStyle(2, 0xff0000);
  159.             mainSprite.graphics.moveTo(segmentA.x, segmentA.y);
  160.             mainSprite.graphics.lineTo(segmentB.x, segmentB.y);
  161.         }
  162.        
  163.         private function geomPolyToVec2List(src:GeomPoly, ccw:Boolean):Vec2List
  164.         {
  165.             var iterator:GeomVertexIterator;
  166.            
  167.             if (!ccw)
  168.                 iterator = src.forwardIterator()
  169.             else
  170.                 iterator = src.backwardsIterator();
  171.            
  172.             var tmp:Vec2List = new Vec2List();
  173.            
  174.             while (iterator.hasNext())
  175.             {
  176.                 var v:Vec2 = iterator.next();
  177.                
  178.                 tmp.add(v.copy());
  179.             }
  180.            
  181.             return tmp;
  182.         }
  183.        
  184.         private function vec2ListToShapes(src:Vec2List, dst:Body):void
  185.         {
  186.             var tmp:GeomPoly = new GeomPoly(src);
  187.            
  188.             var pl:GeomPolyList = tmp.triangularDecomposition();
  189.             var k:int = pl.length;
  190.            
  191.             if (k > 0)
  192.             {
  193.                 var i:int;
  194.                 for (i = 0; i < k; i++)
  195.                 {
  196.                     var poly:GeomPoly = pl.at(i);
  197.                    
  198.                     if (poly.isDegenerate())
  199.                         continue;
  200.                    
  201.                     dst.shapes.add(new Polygon(poly));
  202.                 }
  203.             }
  204.         }
  205.        
  206.         private function convert(vl:Vec2List):Vec2List
  207.         {
  208.             var k:int = vl.length;
  209.             var len:Number = int.MAX_VALUE;
  210.             var v1:Vec2 = borderArray[0];
  211.             var index:int = 0;
  212.            
  213.             var i:int;
  214.             for (i = 0; i < k; i++)
  215.             {
  216.                 var len2:Number = vl.at(i).sub(v1).length;
  217.                
  218.                 if (i == 0)
  219.                 {
  220.                     len = len2;
  221.                 }
  222.                 else
  223.                 {
  224.                     if (len2 < len)
  225.                         {
  226.                             len = len2;
  227.                             index = i;
  228.                         }
  229.                 }
  230.             }
  231.            
  232.             var tmp:Vec2List = new Vec2List();
  233.            
  234.             for (i = 0; i < 4; i++)
  235.                 tmp.add(borderArray[i].copy());
  236.             tmp.add(borderArray[0].copy());
  237.            
  238.             var j:int = index;
  239.            
  240.             for (i = 0; i < k; i++)
  241.             {
  242.                 tmp.add(vl.at(j).copy());
  243.                
  244.                 j--;
  245.                 if (j < 0)
  246.                     j = k - 1;
  247.             }
  248.            
  249.             tmp.add(vl.at(index).copy());
  250.            
  251.             return tmp;
  252.         }
  253.        
  254.         private function checkBalls(src:GeomPoly):Boolean
  255.         {
  256.             var k:int = balls.length;
  257.            
  258.             if (k == 0)
  259.                 return false;
  260.                
  261.             var i:int;
  262.             for (i = 0; i < k; i++)
  263.             {  
  264.                 if (src.contains(balls[i].position))
  265.                     return true;
  266.             }
  267.            
  268.             return false;
  269.         }
  270.        
  271.         private function cut(src:GeomPoly, s:Vec2, f:Vec2, callback:Function):cutResult
  272.         {
  273.             var tmp:GeomPolyList = src.cut(s, f, true, true);
  274.             var result:cutResult = new cutResult();
  275.            
  276.             var k:int = tmp.length;
  277.             if (k > 1)
  278.             {
  279.                 var i:int;
  280.                 for (i = 0; i < k; i++)
  281.                 {
  282.                     var gp:GeomPoly = tmp.at(i);
  283.                    
  284.                     if (callback(gp))
  285.                     {
  286.                         if (result.result == null)
  287.                             result.result = gp
  288.                         else
  289.                             return null;
  290.                     }
  291.                     else
  292.                     {
  293.                         result.destroy.push(gp);
  294.                     }
  295.                 }
  296.             }
  297.            
  298.             return result;
  299.         }
  300.        
  301.         override public function free():void
  302.         {
  303.             stage.removeEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
  304.             stage.removeEventListener(MouseEvent.MOUSE_UP, onMouseUp);
  305.             stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
  306.            
  307.             super.free();
  308.         }
  309.        
  310.         override public function update():void
  311.         {
  312.             super.update();
  313.            
  314.             var k:int = balls.length;
  315.             if (k > 0)
  316.             {
  317.                 var i:int;
  318.                 for (i = 0; i < k; i++)
  319.                 {
  320.                     var b:Body = balls[i];
  321.                    
  322.                     if (b.velocity.length>1)
  323.                         b.velocity.length = 100;
  324.                     else
  325.                         b.velocity.setxy(100, 0);
  326.                 }
  327.             }
  328.         }
  329.     }
  330.    
  331. }
  332.  
  333. import nape.geom.GeomPoly;
  334.  
  335. class cutResult
  336. {
  337.     var result:GeomPoly;
  338.     var destroy:Array/*GeomPoly*/;
  339.    
  340.     function cutResult():void
  341.     {
  342.         result = null;
  343.         destroy = new Array();
  344.     }
  345. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement