30
2016
03

反向动力学应用-可拖动的圆规

还是直接看效果吧。

圆规:

获得 Adobe Flash Player


可以整体拖动,移动位置,也可以拖动单个脚,调整两脚分开的大小。比之前自己一大堆几何算法做出来的效果好多了。

思路就是:拖动左边脚的时候,右边的脚作为固定端,拖动右边脚的时候,左边脚作为固定端,剩下的就是反向动力学的内容了。

源码:

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;
			}
		}
	}
	
}

源码打包下载

« 上一篇下一篇 »

相关文章:

闪电效果  (2017-11-28 15:4:19)

线段与椭圆的交点  (2017-1-6 14:43:41)

as3录制swf并保存flv视频  (2016-12-28 8:43:41)

解九连环  (2016-12-1 20:58:11)

as3实现setTimeout和trace  (2016-11-10 16:47:37)

registerCursor注册系统光标  (2016-9-14 9:49:40)

鼠标光标管理  (2016-9-13 17:44:3)

变形框(transform)实现  (2016-9-13 16:56:6)

flash文本消除锯齿不显示  (2016-8-25 11:43:31)

greenSock的easing曲线  (2016-8-24 18:30:11)

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。