还是直接看效果吧。
圆规:
可以整体拖动,移动位置,也可以拖动单个脚,调整两脚分开的大小。比之前自己一大堆几何算法做出来的效果好多了。
思路就是:拖动左边脚的时候,右边的脚作为固定端,拖动右边脚的时候,左边脚作为固定端,剩下的就是反向动力学的内容了。
源码:
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;
}
}
}
}
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。