Flash移动平台触摸和传感器的使用简单教程

第一次在这里写教材,比较简单,如有不好的地方请大家多多包涵。

技术点:
        1.多点触摸
        2.手势识别
        3.加速度感应
        4.全球定位

教材的Demo在附件中
TeachFlashForPhone.rar (70.96 KB, 下载次数: 1103)
apk.rar (31.01 KB, 下载次数: 577)
开发环境:FlashBuilder Burrito
调试环境:android手机,用usb连接,启用调试模式。(注:模拟器无法支持:>_<:)
Demo截图--> window.jpg
首先建立一个基本的Demo模版
界面: 左边竖排4个按钮分别对应4个Demo。
          按钮下输出调试信息。
          右边为Demo展示区域。
代码如下:

  1. package
  2. {
  3.         import cx.teach.phone.*;
  4.         import cx.ui.components.Button;
  5.         
  6.         import flash.display.DisplayObject;
  7.         import flash.display.Sprite;
  8.         import flash.display.StageAlign;
  9.         import flash.display.StageScaleMode;
  10.         import flash.events.MouseEvent;
  11.         
  12.         import net.hires.debug.Logger;
  13.         
  14.         /**
  15.          * Flash移动平台触摸和传感器的使用Demo
  16.          * @author 翼翔天外
  17.          *
  18.          */
  19.         public class TeachFlashForPhone extends Sprite
  20.         {
  21.                 /**
  22.                  * 指向当前Demo
  23.                  */
  24.                 private var _nowDemo:DisplayObject;
  25.                
  26.                 public function TeachFlashForPhone()
  27.                 {
  28.                         super();
  29.                         init();
  30.                 }
  31.                
  32.                 private function init():void
  33.                 {
  34.                         //首先要设置舞台为左上对齐和不拉伸
  35.                         stage.align = StageAlign.TOP_LEFT;
  36.                         stage.scaleMode = StageScaleMode.NO_SCALE;
  37.                         
  38.                         //Demo按钮列表
  39.                         new Button(this,0,0,"多点触摸",onMultitouchClick);
  40.                         new Button(this,0,70,"手势识别",onGestureClick);
  41.                         new Button(this,0,140,"加速度感应",onAccelerometerClick);
  42.                         new Button(this,0,210,"全球定位",onGeolocationClick);
  43.                         
  44.                         //输出信息在界面上
  45.                         var log:Logger = new Logger();
  46.                         log.y = 280;
  47.                         addChild(log);
  48.                 }
  49.                
  50.                 /**
  51.                  * 切换Demo
  52.                  * @param demo
  53.                  *
  54.                  */
  55.                 private function changeDemo(demo:DisplayObject):void
  56.                 {
  57.                         if(_nowDemo)
  58.                         {
  59.                                 removeChild(_nowDemo);
  60.                         }
  61.                         _nowDemo = demo;
  62.                         addChild(_nowDemo);
  63.                 }
  64.                
  65.                 private function onMultitouchClick(e:MouseEvent):void
  66.                 {
  67.                         Logger.clear();
  68.                         Logger.info("多点触摸Demo");
  69.                         changeDemo(new MultitouchDemo);
  70.                 }
  71.                
  72.                 private function onGestureClick(e:MouseEvent):void
  73.                 {
  74.                         Logger.clear();
  75.                         Logger.info("手势识别Demo");
  76.                         changeDemo(new GestureDemo);
  77.                 }
  78.                
  79.                 private function onAccelerometerClick(e:MouseEvent):void
  80.                 {
  81.                         Logger.clear();
  82.                         Logger.info("加速度感应Demo");
  83.                         changeDemo(new AccelerometerDemo);                        
  84.                 }
  85.                
  86.                 private function onGeolocationClick(e:MouseEvent):void
  87.                 {
  88.                         Logger.clear();
  89.                         Logger.info("全球定位Demo");
  90.                         changeDemo(new GeolocationDemo);        
  91.                 }               
  92.         }
  93. }
复制代码


参看工程主类:TeachFlashForPhone

Demo基本方法说明
每个Demo 都有init和destroy方法,分别对应添加到舞台的初始化操作和移出舞台时的释放操作。

1.        多点触摸        
代码参看:cx.teach.phone. MultitouchDemo
范例功能:建立两个小球,可以用两个手指同时拖动,并绘制拖动轨迹。
代码如下:

  1. package cx.teach.phone
  2. {
  3. import cx.teach.phone.display.Ball;

  4. import flash.display.Sprite;
  5. import flash.events.Event;
  6. import flash.events.TouchEvent;
  7. import flash.geom.Point;
  8. import flash.ui.Multitouch;
  9. import flash.ui.MultitouchInputMode;
  10. import flash.utils.Dictionary;

  11. import net.hires.debug.Logger;

  12. /**
  13. * 多点触摸Demo
  14. * @author 翼翔天外
  15. *
  16. */
  17. public class MultitouchDemo extends Sprite
  18. {
  19. private var _ball1:Ball;
  20. private var _ball2:Ball;
  21. /**
  22. * 记录拖动的手指
  23. */
  24. private var _touchDic:Dictionary = new Dictionary();

  25. public function MultitouchDemo()
  26. {
  27. addEventListener(Event.ADDED_TO_STAGE,init);
  28. addEventListener(Event.REMOVED_FROM_STAGE,destroy);
  29. }

  30. /**
  31. * 初始化
  32. *
  33. */
  34. public function init(e:Event = null):void
  35. {
  36. //判断是否支持
  37. if(!Multitouch.supportsTouchEvents)
  38. {
  39. Logger.error("不支持多点触摸!");
  40. return;
  41. }
  42. //添加多点支持
  43. Multitouch.inputMode = MultitouchInputMode.TOUCH_POINT;
  44. //横向排列两个球
  45. _ball1 = new Ball();
  46. _ball1.x = 300;
  47. _ball1.y = 100;
  48. addChild(_ball1);
  49. _ball2 = new Ball();
  50. _ball2.x = 500;
  51. _ball2.y = 100;
  52. addChild(_ball2);
  53. //添加触摸事件
  54. _ball1.addEventListener(TouchEvent.TOUCH_BEGIN, onTouchBegin);
  55. _ball2.addEventListener(TouchEvent.TOUCH_BEGIN, onTouchBegin);
  56. stage.addEventListener(TouchEvent.TOUCH_MOVE, onTouchMove);
  57. stage.addEventListener(TouchEvent.TOUCH_END, onTouchEnd);
  58. }

  59. /**
  60. * 销毁
  61. *
  62. */
  63. public function destroy(e:Event = null):void
  64. {
  65. if(_ball1)_ball1.removeEventListener(TouchEvent.TOUCH_BEGIN, onTouchBegin);
  66. if(_ball2)_ball2.removeEventListener(TouchEvent.TOUCH_BEGIN, onTouchBegin);
  67. stage.removeEventListener(TouchEvent.TOUCH_MOVE, onTouchMove);
  68. stage.removeEventListener(TouchEvent.TOUCH_END, onTouchEnd);
  69. }

  70. /**
  71. * 触摸开始
  72. * @param e
  73. *
  74. */
  75. private function onTouchBegin(e:TouchEvent):void
  76. {
  77. //开始拖拽,并绑定到一个手指
  78. Sprite(e.currentTarget).startTouchDrag(e.touchPointID);
  79. //记录当前手指到字典
  80. _touchDic[e.touchPointID] = new Point(e.stageX,e.stageY);
  81. Logger.info("Begin TouchPointId:" + e.touchPointID);
  82. }

  83. /**
  84. * 触摸移动中
  85. * @param e
  86. *
  87. */
  88. private function onTouchMove(e:TouchEvent) :void
  89. {
  90. var oldPos:Point = _touchDic[e.touchPointID];
  91. var newPos:Point = new Point(e.stageX,e.stageY);
  92. //线条跟随
  93. drawLine(oldPos,newPos,0);
  94. //更新手指位置
  95. _touchDic[e.touchPointID] = newPos;
  96. }

  97. /**
  98. * 触摸结束
  99. * @param e
  100. *
  101. */
  102. private function onTouchEnd(e:TouchEvent):void
  103. {
  104. Logger.info("End TouchPointId:" + e.touchPointID);
  105. delete _touchDic[e.touchPointID];
  106. //停止拖拽
  107. Sprite(e.currentTarget).stopTouchDrag(e.touchPointID);

  108. }

  109. /**
  110. * 绘制线段
  111. * @param fromPos
  112. * @param toPos
  113. * @param color
  114. *
  115. */
  116. private function drawLine(fromPos:Point,toPos:Point,color:uint):void
  117. {
  118. this.graphics.lineStyle(1,color);
  119. this.graphics.moveTo(fromPos.x,fromPos.y);
  120. this.graphics.lineTo(toPos.x,toPos.y);
  121. }
  122. }
  123. }
复制代码


代码说明:
首先是要做一个可行性检测
if(!Multitouch.supportsTouchEvents)
{
      Logger.error("不支持多点触摸!");
      return;
}
不支持就没戏了,可能要做些友好提示,或切换到其他操作模式。
然后这一句就是告诉手机我要使用多点触摸了,要自己来用代码来判断触摸点。
Multitouch.inputMode = MultitouchInputMode.TOUCH_POINT;
我们需要监听TouchEvent中的三个事件(TOUCH_BEGIN,TOUCH_MOVE,TOUCH_END)
分别对应触摸的开始,移动和结束。相当于鼠标的MOUSE_DOWN,MOUSE_MOVE,MOUSE_UP。
开始和停止拖动:
startTouchDrag(e.touchPointID); stopTouchDrag(e.touchPointID);
注意:在拖放中传入了一个参数e.touchPointID,它是flash为每个触摸点分配的唯一的值,就是对应你当前在屏幕上的那个手 指。在每个事件中都通过这个Id来判断。以前操作鼠标因为只有一个点,所以不用加判断。这里有多个点,那么我们就要用一个字典来管理他们,我建立了一个私 有变量_touchDic来管理和保存某个触摸点上次的位置坐标。这样可以根据每个手指做更加复杂的处理。
然后在移动的时候我更新了字典中触摸点的位置,做了画线处理,当然还可以做更加有趣的操作,有待创意了。
大致就是这样的一个流程,代码里面应该写得比较清晰了。

2.        手势识别
代码参看:cx.teach.phone. GestureDemo
范例功能:建立一个方块,用手指在屏幕上做手势来旋转,缩放,移动。
代码如下:

  1. package cx.teach.phone
  2. {
  3. import cx.teach.phone.display.Box;

  4. import flash.display.Sprite;
  5. import flash.events.Event;
  6. import flash.events.GesturePhase;
  7. import flash.events.TransformGestureEvent;
  8. import flash.ui.Multitouch;
  9. import flash.ui.MultitouchInputMode;

  10. import net.hires.debug.Logger;

  11. /**
  12. * 手势识别Demo
  13. * @author 翼翔天外
  14. *
  15. */
  16. public class GestureDemo extends Sprite
  17. {
  18. private var _box:Box;

  19. public function GestureDemo()
  20. {
  21. addEventListener(Event.ADDED_TO_STAGE,init);
  22. addEventListener(Event.REMOVED_FROM_STAGE,destroy);
  23. }

  24. /**
  25. * 初始化
  26. *
  27. */
  28. public function init(e:Event = null):void
  29. {
  30. //判断是否支持
  31. if(!Multitouch.supportsGestureEvents)
  32. {
  33. Logger.error("不支持手势识别!");
  34. return;
  35. }
  36. //添加手势支持
  37. Multitouch.inputMode = MultitouchInputMode.GESTURE;
  38. //建立方块
  39. _box = new Box();
  40. _box.x = 400;
  41. _box.y = 200;
  42. addChild(_box);
  43. //添加手势监听
  44. stage.addEventListener(TransformGestureEvent.GESTURE_ROTATE,onRotate);//旋转:用两根手指做旋转手势
  45. stage.addEventListener(TransformGestureEvent.GESTURE_ZOOM,onZoom);//缩放:用两根手指靠近和远离
  46. stage.addEventListener(TransformGestureEvent.GESTURE_PAN,onPan);//平移:用两根手指在屏幕上滑动
  47. }

  48. /**
  49. * 销毁
  50. *
  51. */
  52. public function destroy(e:Event = null):void
  53. {
  54. stage.removeEventListener(TransformGestureEvent.GESTURE_ROTATE,onRotate);
  55. stage.removeEventListener(TransformGestureEvent.GESTURE_ZOOM,onZoom);
  56. stage.removeEventListener(TransformGestureEvent.GESTURE_PAN,onPan);
  57. }

  58. /**
  59. * 识别为旋转
  60. * @param e
  61. *
  62. */
  63. private function onRotate(e:TransformGestureEvent):void
  64. {
  65. _box.rotation += e.rotation;
  66. switch(e.phase)
  67. {
  68. case GesturePhase.BEGIN:
  69. Logger.info("旋转");
  70. }
  71. }

  72. /**
  73. * 识别为缩放
  74. * @param e
  75. *
  76. */
  77. private function onZoom(e:TransformGestureEvent):void
  78. {
  79. _box.scaleX *= e.scaleX;
  80. _box.scaleY *= e.scaleY;
  81. switch(e.phase)
  82. {
  83. case GesturePhase.BEGIN:
  84. Logger.info("缩放");
  85. }
  86. }

  87. /**
  88. * 识别为移动
  89. * @param e
  90. *
  91. */
  92. private function onPan(e:TransformGestureEvent):void
  93. {

  94. _box.x += e.offsetX;
  95. _box.y += e.offsetY;
  96. //手势事件的阶段
  97. switch(e.phase)
  98. {
  99. case GesturePhase.BEGIN:
  100. Logger.info("移动");
  101. _box.alpha = .5;
  102. break;
  103. case GesturePhase.UPDATE:

  104. break;
  105. case GesturePhase.END:
  106. _box.alpha = 1;
  107. break;
  108. }
  109. }

  110. }
  111. }
复制代码


代码说明:
首先仍然是可行性检测
if(!Multitouch.supportsGestureEvents)
{
        Logger.error("不支持手势识别!");
        return;
}
告诉手机使用手势支持
Multitouch.inputMode = MultitouchInputMode.GESTURE;
Flash支持的手势还是比较多的,当然还要看设备是否支持。
我简单使用了旋转,缩放和平移三个手势。大家可以看API文档获取更多手势。或者也可以自己通过上面例子中的手指移动分析出需要的手势。
手势在TransformGestureEvent中定义,监听特定方法就OK了。
值得说明的是,一般手势都有几个特定阶段
switch(e.phase)
{
       case GesturePhase.BEGIN:
                                        _box.alpha = .5;
                                        break;
       case GesturePhase.UPDATE:
                                       
                                        break;
       case GesturePhase.END:
                                        _box.alpha = 1;
                                        break;
}
分别对应手势的开始,移动中,和结束。可以在其中做一些处理。

3.        加速度感应
代码参看:cx.teach.phone. AccelerometerDemo
范例功能:建立一个小球,平放手机,通过不同方向倾斜来移动它。
代码如下:

  1. package cx.teach.phone
  2. {
  3. import cx.teach.phone.display.Ball;
  4. import cx.teach.phone.utils.AccelerometerMotor;

  5. import flash.display.Sprite;
  6. import flash.events.Event;
  7. import flash.sensors.Accelerometer;

  8. import net.hires.debug.Logger;

  9. /**
  10. * 加速度感应Demo
  11. * @author 翼翔天外
  12. *
  13. */
  14. public class AccelerometerDemo extends Sprite
  15. {
  16. /**
  17. * 传感器引擎
  18. */
  19. private var _acclMotor:AccelerometerMotor;

  20. private var _ball:Ball;

  21. public function AccelerometerDemo()
  22. {
  23. addEventListener(Event.ADDED_TO_STAGE,init);
  24. addEventListener(Event.REMOVED_FROM_STAGE,destroy);
  25. }

  26. /**
  27. * 初始化
  28. *
  29. */
  30. public function init(e:Event = null):void
  31. {
  32. //判断是否支持
  33. if (!Accelerometer.isSupported)
  34. {
  35. Logger.error("没有加速度传感器!");
  36. return;
  37. }
  38. //展示用球
  39. _ball = new Ball();
  40. _ball.x = 400;
  41. _ball.y = 200;
  42. addChild(_ball);

  43. _acclMotor = new AccelerometerMotor();
  44. _acclMotor.start();

  45. //添加监听
  46. _acclMotor.addEventListener(Event.CHANGE,onAcclChange);
  47. this.addEventListener(Event.ENTER_FRAME,update);
  48. }

  49. /**
  50. * 销毁
  51. *
  52. */
  53. public function destroy(e:Event = null):void
  54. {
  55. if(_acclMotor)
  56. {
  57. _acclMotor.removeEventListener(Event.CHANGE,onAcclChange);
  58. _acclMotor.destroy();
  59. }
  60. this.removeEventListener(Event.ENTER_FRAME,update);
  61. }

  62. /**
  63. * 当加速度改变
  64. * @param e
  65. *
  66. */
  67. private function onAcclChange(e:Event):void
  68. {
  69. //Logger.info("X:" + _acclMotor.accelerationX + " Y:" + _acclMotor.accelerationY + " Z:" + _acclMotor.accelerationZ + "\n");
  70. }

  71. /**
  72. * 帧循环,更新位置
  73. * @param e
  74. *
  75. */
  76. private function update(e:Event):void
  77. {
  78. _ball.x += _acclMotor.accelerationX;
  79. _ball.y += _acclMotor.accelerationY;
  80. }
  81. }
  82. }
复制代码


代码说明:
首先 还是是可行性检测,如果没有可不行
if (!Accelerometer.isSupported)
{
       Logger.error("没有加速度传感器!");
       return;
}
然后建立了一个加速度传感器引擎_acclMotor = new AccelerometerMotor();
这是我封装的一个类cx.teach.phone.utils.AccelerometerMotor
它里面通过使用flash自带的Accelerometer对象监听AccelerometerEvent.UPDATE方法来处理传感器数据,做了一些必要的计算减少误差。
AccelerometerEvent里面的accelerationX,accelerationY,accelerationZ分别代表各个轴的加速度。
在帧循环中直接根据引擎中的加速度值附加到小球位置即可实现小球的移动了。
private function update(e:Event):void
{
         _ball.x += _acclMotor.accelerationX;
         _ball.y += _acclMotor.accelerationY;
}        

4.        全球定位
代码参看:cx.teach.phone. GeolocationDemo
范例功能:用一个文本输出经纬度。(会要等待一定时间才有输出)
代码如下:

  1. package cx.teach.phone
  2. {
  3. import flash.display.Sprite;
  4. import flash.events.Event;
  5. import flash.events.GeolocationEvent;
  6. import flash.sensors.Geolocation;
  7. import flash.text.TextField;
  8. import flash.text.TextFieldAutoSize;
  9. import flash.text.TextFormat;

  10. import net.hires.debug.Logger;

  11. /**
  12. * 全球定位Demo
  13. * @author 翼翔天外
  14. *
  15. */
  16. public class GeolocationDemo extends Sprite
  17. {
  18. private var _geo:Geolocation;

  19. private var _txtInfo:TextField;

  20. public function GeolocationDemo()
  21. {
  22. addEventListener(Event.ADDED_TO_STAGE,init);
  23. addEventListener(Event.REMOVED_FROM_STAGE,destroy);
  24. }

  25. /**
  26. * 初始化
  27. *
  28. */
  29. public function init(e:Event = null):void
  30. {
  31. //判断是否支持
  32. if(!Geolocation.isSupported)
  33. {
  34. Logger.error("没有位置传感器!");
  35. return;
  36. }
  37. _geo = new Geolocation();
  38. //判断是否可用
  39. if(_geo.muted)
  40. {
  41. //权限设置如:<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
  42. Logger.error("传感器未开启或设置权限不够!");
  43. return;
  44. }
  45. //设置更新间隔
  46. _geo.setRequestedUpdateInterval(2000);
  47. //显示用文本
  48. _txtInfo = new TextField();
  49. _txtInfo.defaultTextFormat = new TextFormat(null,18,0x0000FF);
  50. _txtInfo.x = 200;
  51. _txtInfo.y = 100;
  52. _txtInfo.autoSize = TextFieldAutoSize.LEFT;
  53. addChild(_txtInfo);

  54. //添加监听
  55. _geo.addEventListener(GeolocationEvent.UPDATE,onGeoUpdate);
  56. }

  57. /**
  58. * 销毁
  59. *
  60. */
  61. public function destroy(e:Event = null):void
  62. {
  63. if(_geo)
  64. {
  65. _geo.removeEventListener(GeolocationEvent.UPDATE,onGeoUpdate);
  66. }
  67. }

  68. /**
  69. * 显示位置信息
  70. * @param e
  71. *
  72. */
  73. private function onGeoUpdate(e:GeolocationEvent):void
  74. {
  75. Logger.info("更新位置信息");
  76. _txtInfo.text = "经:" + e.longitude + " 纬:" + e.latitude;
  77. }
  78. }
  79. }
复制代码


代码说明:
首先当然还是是可行性检测
if(!Geolocation.isSupported)
{
       Logger.error("没有位置传感器!");
       return;
}
_geo = new Geolocation();
由于隐私或用户拒绝,这里要多检测一个是否可用
if(_geo.muted)
{
       Logger.error("传感器未开启或设置权限不够!");
       return;
}
记住一定要在配置文件中设置以下语句来允许使用位置信息
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
Ok,下面建立一个文本和添加GeolocationEvent.UPDATE的侦听函数
当位置信息更新时就会调用,然后就可以输出经纬度了,当然你可以去谷歌地图定位或做其它什么操作。


本教程到此结束,希望对大家的生活和工作有一定的帮助。

posted on 2013-10-08 09:30  风中雨2013  阅读(519)  评论(0编辑  收藏  举报

导航