还是直接看效果吧。
圆规:
可以整体拖动,移动位置,也可以拖动单个脚,调整两脚分开的大小。比之前自己一大堆几何算法做出来的效果好多了。
思路就是:拖动左边脚的时候,右边的脚作为固定端,拖动右边脚的时候,左边脚作为固定端,剩下的就是反向动力学的内容了。
源码:
Divider.as
package { import flash.display.DisplayObject; import flash.display.MovieClip; import flash.events.Event; import flash.events.MouseEvent; import flash.geom.Point; import flash.geom.Rectangle; public class Divider extends MovieClip { public var legL:MovieClip; public var legR:MovieClip; public var lp:MovieClip; public var mp:MovieClip; public var rp:MovieClip; private var 移动末端:MovieClip; private var 移动端点:Point; private var 关节:MovieClip; private var 固定端点:MovieClip; private var 固定杆:MovieClip; private var 活动杆:MovieClip; private var 可活动长度:Number; private var 活动杆长度:Number; private var 固定杆长度:Number; public function Divider() { // constructor code stage?initStage(null):addEventListener(Event.ADDED_TO_STAGE, initStage); } private function initStage(e:Event):void { removeEventListener(Event.ADDED_TO_STAGE, initStage); legL.addEventListener(MouseEvent.MOUSE_DOWN, dragLhandler); lp.addEventListener(MouseEvent.MOUSE_DOWN, dragLhandler); legR.addEventListener(MouseEvent.MOUSE_DOWN, dragRhandler); rp.addEventListener(MouseEvent.MOUSE_DOWN, dragRhandler); } /** * 拖动右边 * @param e */ private function dragRhandler(e:Event):void { switch(e.type) { case MouseEvent.MOUSE_DOWN: e.stopPropagation(); targetX = mouseX; targetY = mouseY; 移动端点 = new Point(mouseX, mouseY); 移动末端 = rp; 关节 = mp; 固定端点 = lp; 固定杆 = legL; 活动杆 = legR; 活动杆长度 = distance(移动末端, 关节); 固定杆长度 = distance(固定端点, 关节); 可活动长度 = distance(移动端点, 关节); stage.addEventListener(MouseEvent.MOUSE_MOVE, dragLhandler); stage.addEventListener(MouseEvent.MOUSE_UP, dragLhandler); stage.addEventListener(Event.MOUSE_LEAVE, dragLhandler); break; case MouseEvent.MOUSE_MOVE: move(); break; default: stage.removeEventListener(MouseEvent.MOUSE_MOVE, dragLhandler); stage.removeEventListener(MouseEvent.MOUSE_UP, dragLhandler); stage.removeEventListener(Event.MOUSE_LEAVE, dragLhandler); break; } } private function distance(obj1:Object,obj2:Object):Number { return Math.sqrt((obj1.y - obj2.y) * (obj1.y - obj2.y) + (obj1.x - obj2.x) * (obj1.x - obj2.x)); } /** * 拖动左边 * @param e */ private function dragLhandler(e:Event):void { switch(e.type) { case MouseEvent.MOUSE_DOWN: e.stopPropagation(); targetX = mouseX; targetY = mouseY; 移动端点 = new Point(mouseX, mouseY); 移动末端 = lp; 关节 = mp; 固定端点 = rp; 固定杆 = legR; 活动杆 = legL; 活动杆长度 = distance(移动末端, 关节); 固定杆长度 = distance(固定端点, 关节); 可活动长度 = distance(移动端点, 关节); stage.addEventListener(MouseEvent.MOUSE_MOVE, dragLhandler); stage.addEventListener(MouseEvent.MOUSE_UP, dragLhandler); stage.addEventListener(Event.MOUSE_LEAVE, dragLhandler); break; case MouseEvent.MOUSE_MOVE: move(); break; default: stage.removeEventListener(MouseEvent.MOUSE_MOVE, dragLhandler); stage.removeEventListener(MouseEvent.MOUSE_UP, dragLhandler); stage.removeEventListener(Event.MOUSE_LEAVE, dragLhandler); break; } } private var targetX:Number; private var targetY:Number; private function move():void { if (移动末端.hitTestObject(固定端点)) { //trace("撞到了"); var p1:Point = new Point(mouseX - targetX, mouseY - targetY); var p2:Point = new Point(移动末端.x - 固定端点.x, 移动末端.y - 固定端点.y); if (p1.x * p2.x + p1.y * p2.y < 0) { //trace("不能移动"); return; } } // var flag:Boolean = true; var count:uint = 0; targetX = mouseX; targetY = mouseY; while (flag) { move2target(targetX, targetY); var angle01:Number = Math.atan2(targetY - 关节.y, targetX - 关节.x); var angle02:Number = Math.atan2(移动末端.y - 关节.y, 移动末端.x - 关节.x); flag = Math.abs( (angle02 - angle01) * 180 / Math.PI) > 1.0; count++; if (count > 10) break; } 固定杆.x = 关节.x; 固定杆.y = 关节.y; 固定杆.rotation = Math.atan2(固定端点.y - 关节.y , 固定端点.x - 关节.x ) * 180 / Math.PI; 活动杆.x = 关节.x; 活动杆.y = 关节.y; 活动杆.rotation = Math.atan2(移动末端.y - 关节.y, 移动末端.x - 关节.x) * 180 / Math.PI; //trace("循环了" + count + "次"); //关节位于元件的(0,0)点 var offsetX:Number = 关节.x; var offsetY:Number = 关节.y; for (var i:int = 0; i < numChildren;i++ ) { var dis:DisplayObject = getChildAt(i); dis.x -= offsetX; dis.y -= offsetY; } x += offsetX; y += offsetY; } private function move2target(targetX:Number,targetY:Number):void { var angle01:Number = Math.atan2(targetY - 关节.y, targetX - 关节.x); //var 活动杆rotation:Number = angle01 * 180 / Math.PI; 移动端点.x = 关节.x + 可活动长度 * Math.cos(angle01); 移动端点.y = 关节.y + 可活动长度 * Math.sin(angle01); var tx:Number = targetX - 移动端点.x; var ty:Number = targetY - 移动端点.y; 关节.x += tx; 关节.y += ty; var targetX2:Number = 关节.x; var targetY2:Number = 关节.y; var angle02:Number = Math.atan2(targetY2 - 固定端点.y, targetX2 - 固定端点.x); //var 固定杆rotation:Number = angle02 * 180 / Math.PI; 关节.x = 固定端点.x + 固定杆长度 * Math.cos(angle02); 关节.y = 固定端点.y + 固定杆长度 * Math.sin(angle02); 移动末端.x = 关节.x + 活动杆长度 * Math.cos(angle01); 移动末端.y = 关节.y + 活动杆长度 * Math.sin(angle01); } } }
DividerMain.as
package { import flash.display.MovieClip; import flash.events.Event; import flash.events.MouseEvent; import flash.geom.Rectangle; public class DividerMain extends MovieClip { public var divider:Divider; public function DividerMain() { // constructor code trace("DividerMain"); stage?initStage(null):addEventListener(Event.ADDED_TO_STAGE, initStage); } private function initStage(e:Event):void { removeEventListener(Event.ADDED_TO_STAGE, initStage); divider.buttonMode = true; divider.addEventListener(MouseEvent.MOUSE_DOWN, moveDividerHandler); } private function moveDividerHandler(e:Event):void { switch(e.type) { case MouseEvent.MOUSE_DOWN: divider.startDrag(false,new Rectangle(50,50,900,500)); stage.addEventListener(MouseEvent.MOUSE_UP, moveDividerHandler); stage.addEventListener(Event.MOUSE_LEAVE, moveDividerHandler); break; default: divider.stopDrag(); stage.removeEventListener(MouseEvent.MOUSE_UP, moveDividerHandler); stage.removeEventListener(Event.MOUSE_LEAVE, moveDividerHandler); break; } } } }
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。