拖放与置换-DragFollow类
即时获得麻球游戏开发的最新消息,关注游戏开发者热门讨论,请各位开发者申请加入麻球官方群:121304476
也可以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轴也开发进来,大家自己动手吧。
完全的项目文件可以到这里下载

猫推拼盘

One Response to “拖放与置换-DragFollow类”

  1. kaka 说:

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

Leave a Reply