前言:拖拽对象是2D游戏中常用的一个功能,例如《植物大战僵尸》中种植植物的表现形式,拖拽植物卡片种植到相应的地点。
思路:在Egret中实现拖拽对象,需要用到TOUCH_MOVE事件的监听,触摸移动触发TOUCH_MOVE,此时计算触摸移动的大小,让拖拽对象也进行相应的移动。
演示:
步骤一:基于通用MVC框架,快速建立一个基本界面。(参考笔记一,笔记十)
涉及到的文件:
\src\example\module\demo\draft\DraftView.ts
\src\example\module\demo\draft\DraftController.ts
\resource/skins/demo/draft/DraftSkin.exml
步骤二:界面文件中编写用来拖拽的objGroup(Group)以及6个用来吸附对象的point01-point06(Group)
文件:\resource/skins/demo/draft/DraftSkin.exml
<e:Group id="gezi" width="496.97" height="736.36" x="56" y="57" anchorOffsetX="0" anchorOffsetY="0">
<e:Group id="point01" width="218" height="94" x="300.17" y="556.71" anchorOffsetY="0">
<e:Image right="0" bottom="0" left="0" top="0" source="border_png" />
</e:Group>
<e:Group id="point02" width="218" height="94" x="-22.63" y="77.86" anchorOffsetY="0">
<e:Image right="0" bottom="0" left="0" top="0" source="border_png" />
</e:Group>
<e:Group id="point03" width="218" height="94" x="-22.62" y="323.5" anchorOffsetY="0">
<e:Image right="0" bottom="0" left="0" top="0" source="border_png" />
</e:Group>
<e:Group id="point04" width="218" height="94" x="301.72" y="324" anchorOffsetY="0">
<e:Image right="0" bottom="0" left="0" top="0" source="border_png" />
</e:Group>
<e:Group id="point05" width="218" height="94" x="-21.11" y="554.18" anchorOffsetY="0">
<e:Image right="0" bottom="0" left="0" top="0" source="border_png" />
</e:Group>
<e:Group id="point06" width="218" height="94" x="301.7" y="78.81" anchorOffsetY="0">
<e:Image right="0" bottom="0" left="0" top="0" source="border_png" />
</e:Group>
<e:Group id="objGroup" x="97" y="201" anchorOffsetX="0" anchorOffsetY="0">
<e:Image source="table_activity" />
</e:Group>
</e:Group>
步骤三:DraftView.ts中添加拖拽相关代码
打开\src\example\module\demo\draft\DraftView.ts
给拖拽对象加上TOUCH_BEGIN,TOUCH_MOVE,TOUCH_END三个监听事件:
private objGroup:eui.Group; //拖拽的对象
private storeX:number; //TOUCH_BEGIN时存储的拖拽对象位置X
private storeY:number; //TOUCH_BEGIN时存储的拖拽对象位置Y
private PointX:number = 100; //吸附点坐标X
private PointY:number = 100; //吸附点坐标Y
private initFirstObj(): void {
this.objGroup.addEventListener(egret.TouchEvent.TOUCH_BEGIN, this.onTouchBegin, this);
this.objGroup.addEventListener(egret.TouchEvent.TOUCH_MOVE, this.onTouchMove, this);
this.objGroup.addEventListener(egret.TouchEvent.TOUCH_END, this.onTouchEnd, this);
}
拖拽部分代码:
private XTouch: number;
private YTouch: number;
private onTouchBegin(e: egret.TouchEvent): void {
//Obj对象的坐标
this.storeX = this.objGroup.x;
this.storeY = this.objGroup.y;
//想办法记录鼠标移动的记录的坐标
this.XTouch = e.stageX;
this.YTouch = e.stageY;
}
private onTouchMove(e: egret.TouchEvent): void {
this.objGroup.x = this.storeX + (e.stageX - this.XTouch);
this.objGroup.y = this.storeY + (e.stageY - this.YTouch);
}
其中每次触摸事件开始,onTouchBegin分别记录拖拽对象的坐标,手指点击的坐标。每当触摸移动的时候,触发onTouchMove函数,手指触摸移动了多少距离,拖拽对象移动同样的距离。
吸附部分代码:
private onTouchEnd(): void {
//console.log("xxxxxxendxxxxx");
//松开手了吸附到最近的地方
//计算最近的坐标
let self = this;
let closePoint:number = 0;//第几个point是最近的
let closelen:number = 1000;//设定个最高值
let len:number = 0;
for(let i:number=1;i<=6;i++){
//两个Obj距离公式
len = Math.sqrt(Math.pow((self["point0"+i].x - self.objGroup.x),2) + Math.pow((self["point0"+i].y - self.objGroup.y),2)); //Math.pow(2,4);表示2的4次方,等于16 ,Math.sqrt(x);
if(len < closelen){
closelen = len;
closePoint = i;
}
}
console.log("算出来的Len和i分别为",len," self[point0+i].x=",self["point0"+5].x);
this.PointX = this["point0"+closePoint].x;
this.PointY = this["point0"+closePoint].y;
let Tween = egret.Tween.get(self.objGroup).to({x:self.PointX,y:self.PointY},400,egret.Ease.cubicOut);
}
触摸松开的时候,触发onTouchEnd()函数,分别计算推拽对象与6个吸附点的距离,公式:(x^2+y^2)^(1/2),并找到最短的距离,利用Tween动画,使得拖拽对象移动到最近吸附点的位置。
步骤四:测试