After getting some multitouch dispositives, iphone, ipad, ipod, htc desire HD and multitouch screen computers like viliv s10, it is about time to programming for Touch Screen devices.

Thats why i got started with ActionScript 3.0 , c# and java.

In this post I will be writing about the ActionScript 3.0 programming.
This will allow you to test the code online if you have a "non-apple" touch screen device.

Click here to run the demo ( requires a touch screen device with flash )

If you have an android device, you can follow this tutorial: 'Getting started with Adobe AIR for Android'. and create an android application using actionscript for AIR.

You can also download this test application for android,
click on this link,
or scan the QR code with your phone.

AIR is out with a BETA version on labs since some time, and it introduces a lots of new features.
I will focus here on multitouch support.


The Multitouch class

Before trying to use multitouch events, it's a good idea to use the Multitouch.supportsGestureEvents property to determine if the device on which your content is running supports the events that your application needs.

If you're writing an application for the iPhone this is not necessary, but if you're writing content that you want to run in multiple places, check the events that the device can launch, is quite an intelligent decision.
After checking if our device is multitouch, we have to set the input mode.

Multitouch.inputMode = MultitouchInputMode.TOUCH_POINT;

All possible inputMode options are:

MultitouchInputMode.GESTURE: if you want multitouch events synthesized into gesture events. Simple events are interpreted as mouse events.

MultitouchInputMode.TOUCH_POINT: if you are interested only in touch events and no mouse or gesture events.

MultitouchInputMode.NONE: if you want to handle all touches as mouse events.

The main touch events are TOUCH_BEGIN, TOUCH_MOVE and TOUCH_END.

All touch events, have an unique identification number (as an int) assigned to the touch point. This allows as to keep tracking of which touch event is doing what.

This touch events, can be store in an array, object or dictionary, to access then when our application need it.

In this example, we track all touch points, and calculate the distances between them.

Click here to run the demo ( requires a touch screen device with flash )

package
  {
  import flash.display.*;
  import flash.events.*;
  import flash.text.*;
  import flash.filters.BlurFilter;
  import flash.geom.*
  import flash.utils.*;
  import flash.ui.*;
  import com.char95.utils.*;
  import flash.desktop.NativeApplication;

  public class MultiTouchScreen extends Sprite
    {
    private const _touches:Object = new Object();
    private const _touchesDistance:Array = new Array();
    private const SQRT:Function = Math.sqrt;

    protected var sourceBmp:BitmapData;
    protected var colorBmp:BitmapData;
    protected var fingerShape:Shape = new Shape();
    protected var isMultitouch:Boolean = false;
    protected var isMouseDown:Boolean = false;
    
    private var _colors:Array = new Array(
         0xff0000,
         0x00ff00,
         0x0000ff,
         0xffff00,
         0xff00ff,
         0x00ffff);
    private var _bitmapData:BitmapData;
    private var _nTouches:uint = 0;
    
    private var _font:Font = new AppFont();
    private var _format:TextFormat;
    private var _formatId:TextFormat;
    private var _tf:TextField = new TextField();

    public function MultiTouchScreen(wo:uint,ho:uint)
      {
      TextFormat = new TextFormat(_font.fontName, 30, 0x68a4e1);
      TextFormat = new TextFormat(_font.fontName, 50, 0xffffff);

      //_bitmapData = new BitmapData( 480 , 800 , true , 0x0 );
      _bitmapData = new BitmapData( wo , ho , true , 0x0 );
      
      try {
        if (Multitouch.supportsTouchEvents)
          {
          Multitouch.inputMode = MultitouchInputMode.TOUCH_POINT;
          isMultitouch = true;
          }
        Log.add('Multitouch device:'+Multitouch.supportsTouchEvents)
        }
      catch (error:ReferenceError)
        {
        Log.add("Sorry, multitouch is not supported.");
        }
      
      addEventListener ( Event.ADDED_TO_STAGE    , addedToStage  );
      
      _tf.defaultTextFormat = _format;
      _tf.autoSize = TextFieldAutoSize.LEFT;
      _tf.multiline = false;
      _tf.border = false;
      _tf.borderColor = 0xff0000;
      _tf.wordWrap = true;
      _tf.selectable = false;
      _tf.embedFonts = true;
      _tf.antiAliasType = AntiAliasType.ADVANCED;

      addChild(new Bitmap(_bitmapData));
      }


    protected function addedToStage( e:Event ):void
      {
      stage.addEventListener( TouchEvent.TOUCH_BEGIN , touchAdd );
      stage.addEventListener( TouchEvent.TOUCH_MOVE , touchMove );
      stage.addEventListener( TouchEvent.TOUCH_END , touchRemove );
      }
      
      
    private function touchAdd( event:TouchEvent ):void
      {
      _touches[event.touchPointID] = event;
      processTouchs()

      Log.add('ADD:'+event.touchPointID)
            
      if (event.stageY<50 && event.stageX>(stage.stageWidth-130))
        {
        Log.add('EXIT')
        NativeApplication.nativeApplication.exit();
        }
      }


    private function touchMove( event:TouchEvent ):void
      {
      _touches[event.touchPointID] = event;
      processTouchs()
      }
      
      
    private function touchRemove( event:TouchEvent ):void
      {
      delete _touches[event.touchPointID];
      processTouchs();

      Log.add('REMOVE: ' + event.touchPointID + '');
      }
      
      
    private function processTouchs():void
      {
      var touch:TouchEvent;
      var touchId:String;
      var touches:Array = new Array();
      var _touchesDistance:Array = new Array();
      var touchA:TouchEvent;
      var touchB:TouchEvent;
      var nTouches:uint;
      var nTouchesB:uint;
      var matrix:Matrix;

      for ( touchId in _touches )
        touches.push(_touches[touchId]);

      nTouches = touches.length;
      graphics.clear();
      _bitmapData.lock();
      _bitmapData.fillRect(_bitmapData.rect , 0x0 );

      while ( nTouches-- )
        {
        touchA    = touches[nTouches];
        nTouchesB  = nTouches;
        
        while ( nTouchesB-- )
          {
          touchB = touches[nTouchesB];

          graphics.lineStyle( 1 , 0x68a4e1 , 1 );
          graphics.moveTo( touchA.stageX , touchA.stageY );
          graphics.lineTo( touchB.stageX , touchB.stageY );

          var dx:Number  = touchB.stageX - touchA.stageX;
          var dy:Number  = touchB.stageY - touchA.stageY;
          var d:Number  = SQRT(dx*dx+dy*dy);

          _touchesDistance.push( {
              from:touchA.touchPointID ,
              to:touchB.touchPointID ,
              d:d } );
 
          // draw the distances
          _tf.defaultTextFormat  = _format;
          _tf.text = String(int(d));

          matrix = new Matrix();
        
          var tx:Number = (touchA.stageX + touchB.stageX - _tf.textWidth)*0.5;
          var ty:Number = (touchB.stageY + touchA.stageY - _tf.textHeight)*0.5;
        
          matrix.translate( tx , ty  )
          
          _bitmapData.draw( _tf , matrix );
          }
        drawTouch( touchA );
        }
      _bitmapData.unlock();
      }
      
    
    protected function onEnter( event:Event ):void
      {
      graphics.clear();
      graphics.lineStyle( 1 , _colors[0] , 1 );
      graphics.beginFill( _colors[0] , 1 );
      graphics.drawCircle( mouseX , mouseY , 10 );
      graphics.moveTo( 0,mouseY );
      graphics.lineTo( stage.height,mouseY );
      graphics.moveTo( mouseX,0 );
      graphics.lineTo( mouseX,stage.width );
      }


    private function drawTouch( touch:TouchEvent ):void
      {
      var x:Number    = touch.stageX;
      var y:Number    = touch.stageY;
      var w:Number    = touch.sizeX;
      var h:Number    = touch.sizeY;
      var pressure:Number  = touch.pressure;
      
      var matrix:Matrix  = new Matrix();
      var rw:Number     = w*500;
      var rh:Number     = h*500;

      // draw lines
      graphics.lineStyle( 1 , _colors[touch.touchPointID] , 1 );
      graphics.moveTo( 0 , y );
      graphics.lineTo( stage.height , y );
      graphics.moveTo( x , 0 );
      graphics.lineTo( x , stage.width );

      // draw conctact area
      rw = 100;
      rh = 100;
      //graphics.beginFill( _colors[touch.touchPointID] , 1 );
      graphics.drawEllipse( x - rw/2 , y-rh/2 , rw , rh );
      graphics.endFill();

      matrix.translate( x - rw , y - rh )
      _tf.defaultTextFormat  = _formatId;
      _tf.text = String(touch.touchPointID+1);
      _bitmapData.draw( _tf , matrix );
      }
    }
  }

Download MultiTouch source code (AS3)