我们可能都接触过“水果忍者”这款游戏,通过手指在屏幕的滑动来模拟刀的砍切动作。
图9-1-1
我们可能玩过手机上的塔防类的游戏,我们能用手指拖动要建造的箭塔到制定的位置;指头点击箭塔会弹出升级以及贩卖的选项;用两个指头去捏屏幕,能够放大或者缩小地图。那么以上说到的拖动,点击,捏等这些能被手机识别的手势,就属于我们这部分要讲到的手势支持的内容。
图9-1-2
手势支持,顾名思义,就是手机能识别你的手指的动作。目前在MC能做到的手势支持的动作有:点击,拖动,滑动,捏开/合,长按,短按。
<ignore_js_op>
图9-1-3
那么这些功能在MC是如何实现的呢?
手势支持的实现在MC里实现手势支持需要通过以下的途径 1.有四个相关的事件:鼠标按下,鼠标松开,长按,多点触控。这几个事件还是比较好理解的,需要说明的就是多点触控,触发的条件是,多个手指同时按在屏幕上。 2.有四个相关的变量:knob_x,knob_y,knob_r,knob_ang。这四个变量只有在多点触控的情况下才会发生变化,先来解释一下MC实现多点触控的原理:当多个手指头触碰到屏幕上的时候,我们去计算这所有点的坐标的平均值,从而得到取平均后的坐标(knob_x,knob_y)。对于这些点,我们构建一个圆,这个圆的半径为这些点到圆心的平均值。在我们手指捏合的过程中,这个圆的半径在缩小,那么,当前这一帧的圆半径与上一帧的差,就是knob_r,knob_ang是用来判断手指的旋转趋势的。当手指相对屏幕做顺时针运动的时候,knob_ang就为正值,当做逆时针运动的时候,knob_ang为负值。 3.有两个函数可以调用:以下两个函数都是在单个手指滑动的情况下使用的 getOnScrollDXY(float *dx, float *dy)这个函数的返回值dx,dy的含义是,当前帧的拖动点和上一帧拖动点的在x、y的差值。 getOnFlingVXY(float *vx, float *vy)这个函数的返回值vx,vy的意思是,当拖动后手指头离开屏幕那一瞬间的速度学完上面的知识,下面我们就来动一动手。手势支持的实例第一步,我们按照下图对所有角色进行摆放图9-1-2-1
第二步,先搭建边框actBun,对actBun角色添加“碰撞事件”,对应行为“脚本编辑器”添加如下代码:
PhysicalResponse(MOVE_COLLIDE_ACTOR_ONLY, USE_CALCULATED_MASS, 1.000000 , 1.000000, 0.000000, 1.000000);对bird角色添加三个动画,就是bird的三个不同大小的照片,按照大中小命名为:animBirdBig,animBirdMiddle,animBirdSmall。txtKnob角色添加“绘制角色”事件,行为“脚本编辑器”其代码如下: //输出四个变量 sprintf(text,”x=%.6f\n y=%.6f\n r=%.6f\n ang=%.6f\n”, knob_x, knob_y, knob_r, knob_ang); txtScroll角色用来显示getOnScrollDXY函数的返回值,添加“绘制角色”事件,行为“脚本编辑器”其代码如下: float i,j; getOnScrollDXY(&i,&j); sprintf(txtScroll.text,"getOnScrollDXY:%f,%f",i,j); txtFling角色用来显示getOnFlingVXY函数,添加“绘制角色”事件,行为“脚本编辑器”其代码如下: float i,j; getOnFlingVXY(&i,&j); sprintf(txtFling.text,"getOnFlingVXY:%f,%f",i,j); funcPressType角色用来获取按键类型,先建立一个全局变量pressType以侦测按键类型,如图9-1-2-1 然后添加“绘制角色”事件,行为“脚本编辑器”其代码如下: getPressType(&IPressType); if(IPressType == 0) //表示这是刚按下鼠标的状态,进而衍生出短按长按和拖动状态 { sprintf(txtState.text, "on down"); } else if(IPressType == 1)//表示这是长按的状态 { sprintf(txtState.text, "long down"); } else if(IPressType == 2) //表示这是短按 { sprintf(txtState.text, "short down"); } 以上的步骤都是用来做数值的显示的示范,接下来才是具体使用actBird角色,总共有五个事件,全都是“脚本编辑器”行为。图9-1-2-2
在这之前,先定义一些自定义的变量,打开菜单栏“脚本”->“角色脚本”->“自定义变量”,创建四个变量如下图所示
图9-1-2-3
事件一:“创建角色”事件
IBirdSize = 2; DSumR = 0.0; IDragState = 0;事件二:“绘制角色”事件//对小鸟的大小进行判定,在捏合和捏开中能看到 if( IBirdSize == 1 ) { ChangeAnimation("actBird", "animBirdSmall", FORWARD); } else if( IBirdSize == 2 ) { ChangeAnimation("actBird", "animBirdMiddle", FORWARD); } else if( IBirdSize == 3 ) { ChangeAnimation("actBird", "animBirdBig", FORWARD); } sprintf(txtSum.text, "%.6f", DSumR);//拖动状态的判定 if(IDragState == 1) { actBird.xscreen = xmouse; actBird.yscreen = ymouse; } else { if(xvelocity >= 30.0) { xvelocity -= 5.0; } else if(xvelocity <= -30.0) { xvelocity += 5.0; } else { xvelocity = 0.0; } if( yvelocity >= 30.0) { yvelocity -= 5.0; } else if(yvelocity <= -30.0) { yvelocity += 5.0; } else { yvelocity = 0.0; } }事件三:“多点触控事件” DSumR += knob_r; if(DSumR > 0.1) { IBirdSize = 3; } else if(DSumR <- 0.1) { IBirdSize = 1; } else { IBirdSize = 2; }事件四:“鼠标键按下”事件//进入拖动状态,同时速度归零 if(IPressType == 0) { IDragState = 1; } xvelocity = 0; yvelocity = 0;事件五:“鼠标键弹起”事件//状态复位以及侦测甩动后的瞬时速度//状态复位以及侦测甩动后的瞬时速度 float i,j; getOnFlingVXY ( &i, &j ); IDragState = 0; xvelocity = (double)j; yvelocity = (double)i;//考虑到i,j太小,所以强行把初速度改成200 if(xvelocity > 0) xvelocity = 200; else if(xvelocity < 0) xvelocity = -200; if(yvelocity > 0) yvelocity = 200; else if(yvelocity < 0) yvelocity = -200;都做好了,导出到手机看看效果吧。在手机上,你能拖动小鸟,甩动小鸟,捏放或者捏合来改变小鸟的大小,还能通过数值的变化看到具体的参数以及按键类型。Demo下载地址:http://www.dongyo.cn/bbs/forum.php?mod=viewthread&tid=2528&extra=page%3D1%26filter%3Dauthor%26orderby%3Ddateline%26orderby%3Ddateline