转自:http://www.cnblogs.com/NEOCSL/archive/2013/03/04/2942861.html
iterface ITouchable; function OnPick(ETouchType type,float x,float y);
1.定义一个接口。这个接口由MenuObject来实现,也就是所有的按钮Object。
class AntMenuObject extends MobileMenuObject implements(ITouchable); function OnPick(ETouchType type,float x,float y) { if(bIsActive) { if(CheckBound(x,y)) { bIsHightLighted=true; bIsTouched=true; } else if(Type==Touch_Ended||Type==Touch_Cancelled) { bIsHightLighted=false; bIsTouched=false; } } else { bIsHightLighted=true; bIsTouched=true; } } function bool CheckBound(x,y) { if(x>=left&&x<=Left+width&&YTop&&Y>=Top&&Y<=Top+Height) { return true; } return false }
CheckSwipe是一个功能性非常强的函数,该函数可以检测屏幕是划过还是点击。只能在MenuScene中进行检查,因为只有整个屏幕才能检测是否划过。
function bool OnSceneTouch(ETouchType EventType, float TouchX, float TouchY,bool bInside) { if(EventType==Touch_Began) { bSwipe=false; StartTouchLocation.x=TouchX; StartTouchLocation.y=TouchY; } else if(EventType==Touch_Moved) { CurrentTouchLocation.x=TouchX; CurrentTouchLocation.y=TouchY; CheckSwipe(); } }
检测Swipe就是检测两者之间的距离
function bool CheckSwipe() { return bSwipe=VSize(StartTouchLocation-CurrentTouchLocation)>SwipeTolerance; }
2.最重要的地方是List的列表处理,秉承着列表优先原则,但是如果处理不了列表就可以让实现接口的ITouchable,OnPick
if(List.bIsHidden||List==none) { foreach MenuObjects(Touchable) { if(ITouchable(Toucable)!=none) { ITouchable(Touchable).OnPick(EventType,TouchX,TouchY); } } }
否则就处理列表
if(!List.bIsHidden&&List!=none) { ITouchable(List).OnPick(EventType,TouchX,TouchY); }
我们先进入List看看他的OnPick函数是怎么针对Swipe和Touch做处理的。That's very important。
OnPick处理滑动动作,并且感应器范围检测是否为bSwipe,如果是就滚动页面,不是就让foreach Items(Label) {Label.OnPick(EventType,X,Y);}
3.现在根据这个代理我们被引入到Button中,Lable是在List中对所有添加的AntMobileMenuButton的遍历引用按钮。
AntMobileMenuButton中对OnPick做了代理
delegate OnClick(ETouchType EventType,float X,float Y); function OnPick(ETouchType EventType,float x,float y) { //CheckBounds(x,y)Objects内定义的有没有在边界内 if(EventType==Touch_End&&CheckBounds(X,Y)) { //在List的AddItem中可以看到,将NewItem.OnClick=OnSelect;了 //于是我们赶快进入OnSelect中一探究竟,这可是对按钮做对应动作处理的地方 //我很好奇点下按钮我到底在哪里添加功能 OnClick(self,x,y); } }
注意OnClick的第一个参数接受的是自己,button类别,也就是Sender消息。
4.我们进入List的OnSelect中分析
function OnSelect(AntMobileMenuObject sender,float x,float y) { local AntMobileMenuButton label; local int i; //起先设置i为第一个,以后我需不需要这个还说不定 i=0; //若果有接收信号输出,我们就遍历看是哪个按钮接收的 if(AntMobileMenuButton(Sender)!=none) { foreach Items(label) { //匹配对应的按钮,然后执行动作 if(label==AntMobileMenuButton(Sender) { //在这里添加对应的执行内容,例如武器的引用 //最后用按钮来对应具体的动作,例如玩家的武器列表 //通知列表选择的哪个 SelectedIndex=i; Sender.bIsHighLighted=true; //同时我们发现了一个新代理 OnChange(i,Label.Caption,X,Y); //后边我们看看这个代理被分配到了哪里 break; } i++; } } ScrollAmount=0; ScrollInertia=0; }
代理的声明,看看在ComboBox中哪里将会将List.OnChange=?
delegate OnChange(int Idx,string item,float x,float y);
5.进入ComboBox
在初始化的时候将List的OnChange分配给了OnSelect,然后执行选中的动作,也就是关闭List,但是问题来了,即使没有分配OnChange代理也能成功。