也可以follow catfly围脖:t.sina.com.cn/iscat
通常我们使用的拖放效果,是通过一个DropTarget来确定拖放目的地的。
今天要介绍的这个拖放与置换是通过[拖放对象移动过程中的坐标]来确定拖放目的地的。
先不谈拖放这回事,来解一道有趣的题目吧。
问:如果把100以内的数分成4份,取任意一个100以内的数,如何知道这个数是第几份中的?
看看拖放与置换示例的效果,再来解这个题目(不然要没动力解答了)
var num:unit = getObjNum(12.35,100);
private function getObjNum(aNum:Number,total:Number):uint{
var objNum:uint;
var denfen:uint = 4;
var bi:Number = aNum/total;
if(bi >= 0.75){
objNum = 3;
}else if(bi >= 0.45 && bi < 0.75){
objNum = 2;
}else if(bi >= 0.25 && bi < 0.45){
objNum = 1;
}else if(bi >= 0 && bi < 0.25){
objNum = 0;
}
return objNum;
}
很快就把算法写出来了,那如果把题目改一下
问:如果把100以内的数分成n份,取任意一个100以内的数,如何知道这个数是第几份中的?
var n:uint = 8;
var num:unit = getObjNum(12.35,100);
private function getObjNum(aNum:Number,total:Number):uint{
var objNum:uint;
var denfen:uint = n;
var bi:Number = aNum/total;
for(var i:uint=0;i<denfen;i++){
if(bi >= i/denfen && bi < (i+1)/denfen){
objNum = i;
break;
}
}
return objNum;
}
还可以再改进吗?也许做这个判断并不需要跑for循环吧。而且我运行程序后,发现有一些小bug,拖到最右边时,有时候返回错误的位置编号。
改进版
var n:uint = 8;
var num:uint = getObjNum(12.35,100);
private function getObjNum(aNum:Number,total:Number):uint{
var objNum:uint = Math.min(n-1, Math.floor(aNum / total* n));
return objNum;
}
ok,把上面的问题搞明白了,接下来就好办了。制作这个拖放与置换的示例,需要实现如下两个关键点:
1. 获取指定位置编号上的按钮对象;
2. 获取指定按钮对象所在的位置编号(其实就是根据按钮对象的坐标值,算出它是n个等份中的第几份)。
使用DragFollow类很简单。只需要把两个参数传给它就可以了:var theDrag:DragFollow = new DragFollow(btAllMc,600);
一个是包含了所有拖放按钮的容器对象,
一个是X轴上可以拖放的范围(Y轴可以吗?当然可以,我在类文件中写了个_aix的参数,默认值为空,
把Y轴相关的开发留给大家去思考了!)
先添加鼠标拖与放的事件,以及具体的拖放事件函数,这些都放在构造函数中。
public function DragFollow(_parentMc:Sprite,_trackLength:Number,_aix:String=null){
//所有拖放按钮的容器对象
parentMc = _parentMc;
//轴上可以拖放的范围
trackLength = _trackLength;
for(var i:uint=0;i<parentMc.numChildren;i++){
var ch:Sprite = parentMc.getChildAt(i) as Sprite;
ch.buttonMode = true;
ch.mouseChildren = false;
ch.addEventListener(MouseEvent.MOUSE_DOWN,this.starDragFunc);
ch.stage.addEventListener(MouseEvent.MOUSE_UP,this.endDragFunc);
}
}
private function starDragFunc(e:MouseEvent):void{
targetMc = e.target as Sprite;
dragState = true;
//记录当前拖动对象
moveObj.targetObj = targetMc;
moveObj.targetPosition = targetMc.x;
var rectangle:Rectangle = new Rectangle(0, 0, trackLength, 0);
//设置当前拖动对象显示层级到最上层,并把拖动限制在一个轴
parentMc.setChildIndex(targetMc,parentMc.numChildren-1);
targetMc.startDrag(false,rectangle);
}
private function endDragFunc(e:MouseEvent):void{
if(dragState){
targetMc.stopDrag();
dragState = false;
//设置目标位置编号
//根据拖动对象停止的坐标,设置将要停放到几号位置
setNum(targetMc.x,trackLength);
setChildPostion();
}
}
设置目标位置编号,根据拖动对象停止的坐标,设置将要停放到几号位置,然后与目标停放位置上的对象交换位置。
private function setNum(position:Number,total:Number):void{
num = Math.min(denfen-1, Math.floor(targetMc.x / trackLength * denfen));
}
private function setChildPostion():void{
//目标停放位置上的对象
moveObj.toChangeBt = getNumObj(num);
moveObj.toChangePosition = moveObj.toChangeBt.x;
//与目标停放位置上的对象交换位置
TweenLite.to(targetMc,0.2,{x:moveObj.toChangePosition});
TweenLite.to(moveObj.toChangeBt,0.2,{x:moveObj.targetPosition});
}
嗯,还有这个类文件中最关键的两个方法,那就是获取目标位置编号上的对象,与获取目标对象的位置编号。
//获取目标位置编号上的对象
public function getNumObj(_num:uint):Sprite{
var ch:Sprite;
for(var i:uint=0;i<parentMc.numChildren;i++){
var bt:Sprite = parentMc.getChildAt(i) as Sprite;
if(getObjNum(bt.x,trackLength) == _num){
ch = bt;
break;
}
}
return ch;
}
//获取目标对象的位置编号
private function getObjNum(position:Number,total:Number):uint{
var denfen:uint = parentMc.numChildren;
var objNum:uint = Math.min(denfen-1, Math.floor(position / total * denfen));
return objNum;
}
That is it! 有了这个类,在项目中处理这种拖放置换功能就好办多了,如果需要把Y轴也开发进来,大家自己动手吧。
完全的项目文件可以到这里下载








bates 的人头马项目还算利润丰厚吧。。 kaka[引用]