TouchEvent对象
MouseEvent好用但TouchEvent更好用
我想旧习惯是很难改的,特别是这种习惯还好用的时候。(有些开发者很喜欢说,只要没坏,就不用修!还有一句差不多蠢的格言,不要重复发明轮子!)然而,在手机设备上,你最好考虑一下打破老习惯,我已经把自己放在蠢人列表的最顶端了,希望意见能被采纳。首要做的改变就是建立一个移动App,使用TouchEvent而不是MouseEvent。以前做游戏时,我一直乐于用MouseEvent,后来我发现一放到移动设备里就卡住不动了。于是我决定试一下TouchEvent。自然不能用Flash Pro CS5.5测试,我在我的iPhone里启动,效果很明显,不会卡住了。
值得高兴的是MouseEvent跟TouchEvent这两个类在App中运行起来是一样的。我不知道它们在底层是怎么运作的,我也不需要知道这些东西,只要知道在移动设备中哪一个更好就可以了。我们从建立TouchEvent的程序开始,虽然几乎跟MouseEvent一样,程序上还是有一些不同的。不过,首先请点击下面的Play按钮来看电脑上的这个小的测试App,你也可以点击下载按钮来下载Flash 5.5的Fla文件和Client类文件。
这是一个简易的App,它可以将一个“Samurai”人物上下左右移动。App中的按钮是用日文写的,如果你会日文,你会发现这些符号看起来就像一个一年级学生学习写日文那样。(你还可以随意使用日文做一些别的按钮并跟注释一起发送过来。)(译者注:显然这个老外没见过博大精深的中文,呃。。这里不讨论文化问题。)
可能出现的争议:在完成这篇文章之后,我无意中遇到下面的问题:
http://help.adobe.com/en_US/as3/ ... 21e58cc29-8000.html
里面是一篇提示:
注意:侦听touch和gesture事件会消耗很大一部分的进程资源(相当于每秒渲染好几帧),由运算设备和操作系统决定。而当你并不是确实需要额外的触屏和动作功能的时候,还是使用鼠标事件会更好。如果你确实使用了touch和gesture事件,想办法减少可能的位图转换,特别是当这些事件在晃动、旋转、或缩放操作时可能要快速调度。例如,在用户利用缩放动作调整尺寸大小的时候,你就可以在一个组件中停止动画。
这个当然是有意义的,但是我发现即使使用TOUCH_TAP,它也比侦听CLICK事件快并且敏感得多。只有一种方法来解决这个问题,就是自己在任意移动设备上试用一个移动App。使用Comment片段来记录新的发现,示例App已经可以很好的测试了,不过你还是可以随意创建一个自己的。
因为Chico Marx迅速察觉到了,好的,现在你要相信谁呢,是相信我还是相信你的眼睛?还是相信你自己的眼睛并试一下吧!
正确的触屏
创建TouchEvent要导入如下三个类:
import flash.events.TouchEvent;
import flash.ui.Multitouch;
import flash.ui.MultitouchInputMode;
相比之下鼠标事件只要导入一个MouseEvent就可以了。不过,在使用TouchEvent之前还要输入以下代码建立移动关联:
Multitouch.inputMode = MultitouchInputMode.TOUCH_POINT;
这句声明表明输入模式为触屏而非鼠标事件,没有这句声明是不能启动TouchEvent的,所以不要忘记在程序中加上。
最后还需要一个事件侦听,侦听都跟鼠标事件的格式一样,TouchEvent也是。不过不是用CLICK而是TOUCH_TAP,如下所示:
upBtn.addEventListener(TouchEvent.TOUCH_TAP,moveNow);
这样,你就做好准备可以创建一个使用TouchEvent的App了。
一个处理程序,多个接收器
在进程中会占用很大内存,特别在移动设备中会比较明显的就是事件侦听了,每个事件侦听器都会建立一系列操作来保持对事件的侦听。只有一个事件是不够的,但直接关联一个侦听器只要一个步骤(这就可以了)。下面的这个Client会创建一个使用TouchEvent的示例。所有按钮都是SimpleButton对象,而背景是一个大的Sprite。同样的,Sam3是一个Sprite,你可以轻敲移动设备来移开它。
package
{
import flash.display.Sprite;
import flash.display.SimpleButton;
import flash.events.TouchEvent;
import flash.ui.Multitouch;
import flash.ui.MultitouchInputMode;
public final class Client extends Sprite
{
private static var leftBtn:SimpleButton=new Left();
private static var rightBtn:SimpleButton=new Right();
private static var upBtn:SimpleButton=new Up();
private static var downBtn:SimpleButton=new Down();
private static var bkground:Sprite=new Background();
private var sam3:Sprite=new Sam3();
public function Client()
{
addChildAt(bkground,0);
setControls();
setSamurai();
}
private final function setControls():void
{
Multitouch.inputMode = MultitouchInputMode.TOUCH_POINT;
upBtn.x = 825,upBtn.y = 19;
upBtn.addEventListener(TouchEvent.TOUCH_TAP,moveNow);
addChild(upBtn);
leftBtn.x = 740,leftBtn.y = 106;
leftBtn.addEventListener(TouchEvent.TOUCH_TAP,moveNow);
addChild(leftBtn);
rightBtn.x = 873,rightBtn.y = 105;
rightBtn.addEventListener(TouchEvent.TOUCH_TAP,moveNow);
addChild(rightBtn);
downBtn.x = 825,downBtn.y = 202;
downBtn.addEventListener(TouchEvent.TOUCH_TAP,moveNow);
addChild(downBtn);
}
private final function setSamurai():void
{
sam3.x=(960/2); sam3.y=(640/2)+100;
addChild(sam3);
}
private final function moveNow(e:TouchEvent):void
{
switch(e.target.name)
{
case "instance11":
sam3.y -=5;
break;
case "instance1":
sam3.x -=5;
break;
case "instance6":
sam3.x +=5;
break;
case "instance16":
sam3.y +=5;
break;
}
}
}
}
由于我在开发一个大型项目,我将它设置成横版视图来察看。你还可以在moveNow方法中看到,在移动过程中是没有“阻碍”的,所以人物可以任意移动,包括舞台的外部。现在,我有一个全局的移动系统了,它是用状态模式(State Pattern)建立的,可以很好地运行,我还想将本地和全局的移动合并到一个单独的移动中。这个不仅会减少侦听器的数目,也会将其变成一个有趣的游戏。图1就是显示在iPhone上的样子,此外我还需要Android或其他非iOS设备上的一些反馈。
你可能想要将TouchEvent更换为MouseEvent然后再在移动设备上试一下,在点击了几次后你会发现“卡住”了。我们非常欢迎你的意见和反馈。