Building Your First Multi-Touch Application in Flash

From NUI Group Community Wiki

Jump to: navigation, search

This article will assume you know some actionscript, but that is all.


You MUST be working with the SVN files. The download files will NOT work for this

  1. create a new Flash file (actionScript3)
  2. click on the canvas (stage), now the properties for the file should be available.
  3. click on the size button.
  4. change the size to 1024 x 768 and 30+ FPS
  5. click settings (below size button)
  6. Where it says actionScrtip version, make sure ActionScript 3 is selected and click settings
  7. in classpath at the bottom, click on the + button and enter
    1. ../ext
    2. do the same for
    3. ../int
  8. save this flash file in (the touchlib folder) AS3/src (name it what you want) EG touch.fla
  9. in the AS3/int/app/demo folder, create a new folder called MyTouchApp (must be exact *)
  10. create a new ActionScript file.
  11. save it as MyTouchApp.as in AS3/int/app/demo/MyTouchApp (that folder you just made)
  12. go back to ( or click on the tab for) you flash file --> the touch.fla file from above
  13. In the Document Class text field enter app.demo.MyTouchApp.MyTouchApp
  14. select the rectangle button and make a rectangle that is over, and larger than your canvas. This will be the area your program will run on.
  15. right click (control click on a mac) on the black rectangle you just made and select “Convert To Symbol”
  16. make sure movieclip is selected and press ok.
  17. Save file… go back to MyTouchApp.as
  18. copy code from examples and paste it in this file. MAKE SURE THE PAGE IS CLEARED FIRST
  19. save this file again, go back to (click on the tab for) you flash file EG. touch.fla
  20. publish the file. It should work now
*  This can be different, BUT you will need to change the code to reflect that.


1: New Flash AS3 File Doc Properties 3: Doc Size 5, 6: Doc Settings 7: AS Settings 8: Save File 10: New AS File 11: Save AS file as 12: Document class 14 14: Rectangle 15, 16: Convert to MovieClip

Code Examples

Use these examples to build off of.


This app will make a red circle every where you touch.

package app.demo.MyTouchApp{ //adds a circle where you touch (no resize)
 
    import flash.display.*;        
    import flash.events.*;
    import flash.net.*;
    import flash.geom.*;        
 
    public class MyTouchApp extends Sprite {
 
        public function MyTouchApp() {
 
            //--------connect to TUIO-----------------
            TUIO.init(this,'localhost',3000,'',true);
            trace("MyTouchApp Initialized");
            //----------------------------------------        
 
            addEventListener(TouchEvent.MOUSE_DOWN, touchDown); //run touchdown, when touched
        }
 
        public function touchDown(e:TouchEvent):void{        
 
            var curPt:Point = parent.globalToLocal(new Point(e.stageX, e.stageY)); //convert touch points to x,y                
 
            var circle:Sprite = new Sprite(); //create a new sprite
 
            circle.graphics.lineStyle(10, 0xff0000); //set line width to 10px and red
            circle.graphics.drawCircle(0,0,40); // draw a 40px circle
            circle.x = curPt.x; //put it where touch is (x cord)
            circle.y = curPt.y; //put it where touch is (y cord)
 
            addChild(circle); //add the circle where touch happened
 
        }
    }
}


This app will make a red circle every where you touch AND allow you to scale the stage

The below code is really only changed by extending the RotatableScalable class as opposed the sprite class as above, this alone gives it that ability to scale and rote the stage

package app.demo.MyTouchApp{
 
	import flash.display.*;
	import flash.events.*;
	import flash.net.*;
	import flash.geom.*;
	import app.core.action.RotatableScalable;
 
	public class MyTouchApp extends RotatableScalable {//allows it to be scaled around
		public function MyTouchApp() {
 
			//--------connect to TUIO-----------------
			TUIO.init(this,'localhost',3000,'',true);
			trace("MyTouchApp Initialized");
			//----------------------------------------        
			addEventListener(TouchEvent.MOUSE_DOWN, touchDown);//run touchdown, when touched
		}
 
		public function touchDown(e:TouchEvent):void {
 
			var curPt:Point=parent.globalToLocal(new Point(e.stageX,e.stageY));//convert touch points to x,y                
			var circle:Sprite = new Sprite();//create a new sprite
 
			circle.graphics.lineStyle(10, 0xff0000);//set line width to 10px and red
			circle.graphics.drawCircle(0,0,40);// draw a 40px circle
			circle.x=curPt.x;//put it where touch is (x cord)
			circle.y=curPt.y;//put it where touch is (y cord)
			addChild(circle);//add the circle where touch happened
 
		}
	}
}


This app will make a red ripple every where you touch. (no scale rotate)

package app.demo.MyTouchApp{
 
	import flash.events.TUIO; // allows to connect to touchlib/tbeta
	import flash.display.*;
	import flash.events.*;
	import flash.geom.*; // needed for curPt;
 
	public class MyTouchApp extends Sprite {
 
		var ripple:Ring; //ring class at end of code
		var ripples:Array = new Array(); // holds the list of rings to be animated
 
		var color:uint = 0xff0000;
		var radius:Number = 10;
		var thickness:Number = 5;
 
		public function MyTouchApp() {
 
			//--------connect to TUIO-----------------
			TUIO.init(this,'localhost',3000,'',true);
			trace("MyTouchApp Initialized");
			//---------------------------------------- 
 
			stage.addEventListener(TouchEvent.MOUSE_DOWN, onTouchDown);
			addEventListener(Event.ENTER_FRAME, rippler);
 
		}
 
		private function onTouchDown(e:TouchEvent):void { // makes a ripple, puts it in the array and starts the rippler
 
			var curPt:Point=parent.globalToLocal(new Point(e.stageX,e.stageY));
 
			ripple = new Ring(thickness, radius, color); // all defined above
			ripple.x=curPt.x; // x pos of touch
			ripple.y=curPt.y; // y pos of touch
			addChild(ripple); // adds the ripple to the stange
			ripples.push(ripple); // adds it to the ripples array so it can be animated
		}
 
		private function rippler(e:Event):void {
 
			for (var i:uint = 0; i < ripples.length; i++) { // cycle through the ripples on stage and animate them
				ripples[i].width *= 1.15;
				ripples[i].height *= 1.15;
				ripples[i].alpha -= .05;
 
				if (ripples[i].alpha < .01) { // when the ripple's alpha is below 1% remove it from the stage, and the array
					removeChild(ripples[i]);
					ripples.splice(i, 1);
				}
			}
		}
	}
}
 
import flash.display.Sprite; // ring class
 
class Ring extends Sprite {
 
	public function Ring(thickness:Number = 10, radius:Number = 40, color:uint = 0xff0000) {
		graphics.lineStyle(thickness, color);
		graphics.drawCircle(0,0,radius);
		graphics.endFill();
	}
}




This app combines touch and mouse clicks. Just so you know you can do that

It places a red circle where you click the mouse, but allows you to scale/rote around using your fingers

package app.demo.MyTouchApp{
 
    import flash.display.*;
    import flash.events.*;
    import app.core.action.RotatableScalable;
 
    public class MyTouchApp extends RotatableScalable {
 
        public function MyTouchApp() {
 
            //--------connect to TUIO-----------------
            TUIO.init(this,'localhost',3000,'',true);
            trace("MyTouchApp Initialized");
            //----------------------------------------        
 
            addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown); // adds an event listener looking for a mouse click - runs "onMouseDown"
        }
 
 
        private function onMouseDown(event:MouseEvent):void { //creats a circle when the mouse is clicked
 
            var circle:Sprite = new Sprite();
 
            circle.graphics.lineStyle(10, 0xff0000); //set line width to 10px and red
            circle.graphics.drawCircle(0,0,40); // draw a 40px circle
            circle.x = mouseX; //put it where the mouse clicked
            circle.y = mouseY;
 
            addChild(circle); //add the circle to the plane
        }
    }
}



This little app places x number of rings on the stage in random locations. Each one can be moved and scaled. This is done simply by just having the ring class be an extension of the RotatableScalable class so each ring is it's own RotatableScalable

package app.demo.MyTouchApp{
 
    import flash.events.TUIO;// allows to connect to touchlib/tbeta
    import flash.display.Sprite;
 
    public class MyTouchApp extends Sprite {
 
 
        private var num:Number=5; // number of rings to put
        var ring:Ring; //ring class (at bottom)
 
        public function MyTouchApp():void {
 
            //--------connect to TUIO-----------------
            TUIO.init(this,'localhost',3000,'',true);
            trace("MyTouchApp Initialized");
            //----------------------------------------
 
 
            // put "num" rings randomly on the stage
            for (var i:int = 0; i < num; i++) {
                ring = new Ring();
                ring.x = Math.random() * stage.stageWidth;
                ring.y = Math.random() * stage.stageHeight;
                addChild(ring);
            }
        }
 
    }
}
 
import flash.display.Sprite; // ring class
import app.core.action.RotatableScalable;
 
class Ring extends RotatableScalable {
 
    public function Ring(thickness:Number = 10, radius:Number = 40, color:uint = 0xff0000) {
 
        //---RotatableScalable options------------
            //noScale = true;
            noRotate = true;    
            //noMove = true;
        //----------------------------------------
 
        graphics.lineStyle(thickness, color);
        graphics.drawCircle(0,0,radius);
 
        graphics.beginFill(0xffffff);
        graphics.drawCircle(0,0,radius);
        graphics.endFill();
    }
}



Let's get a little more complex, this is a simple drawing application

package app.demo.MyTouchApp{
 
    import flash.events.TUIO; // allows to connect to touchlib/tbeta
 
    import flash.display.*;
    import flash.events.*;
    import flash.geom.*; // needed for curPt;
 
    public class MyTouchApp extends Sprite {
 
        private var color:uint = 0xff0000; // color of lines
        private var thickness:Number = 30; // thickness of lines
 
        private var blobs:Array = new Array(); // blobs we are currently interacting with
        private var lines:Array = new Array(); // array to hold the lines
 
        public function MyTouchApp():void {
 
            //--------connect to TUIO-----------------
            TUIO.init(this,'localhost',3000,'',true);
            trace("MyTouchApp Initialized");
            //---------------------------------------- 
 
            addEventListener(TouchEvent.MOUSE_DOWN, downEvent, false, 0, true); // run when finger down
            addEventListener(TouchEvent.MOUSE_UP, upEvent, false, 0, true); // run when finger up
            addEventListener(Event.ENTER_FRAME, updater, false, 0, true); // keep running
        }
 
        // updates/draws the drawn lines by:
        // cycling through all existing blobs
        // getting the id of each blob
        // use that id to get the line, as the lines are named after their blobs (eg line1280 )
        // tuioobj is the blob - see how it is called by request using the blob id?
        // if it is not there remove it from the blobs array.
        // draw the next segment of the line using lineTo and current loc (tuioobj.x, tuioobj.y)
        function updater(e:Event):void {
            for (var i:int = 0; i < blobs.length; i++) { 
                var tuioobj:TUIOObject=TUIO.getObjectById(blobs[i].id);
 
                // if not found, then it must have died..
                if (! tuioobj) {
                    removeBlob(blobs[i].id);
                } else if (parent != null) {
 
                    lines["line"+blobs[i].id].graphics.lineTo(tuioobj.x, tuioobj.y);
                }
            }
        }
 
        // when touched, this calls addblob with the blob ID and the X/Y of where it started
        public function downEvent(e:TouchEvent):void {
            var curPt:Point=parent.globalToLocal(new Point(e.stageX,e.stageY));
            addBlob(e.ID, curPt.x, curPt.y);
            e.stopPropagation();
        }
 
        // When a finger stops touching, call removeBlob
        public function upEvent(e:TouchEvent):void {
            removeBlob(e.ID);
            e.stopPropagation();
        }
 
        // This takes the sent ID, x,y and puts it all in the blobs array
        // It then creats a new sprite, and sets the starting loc of the line
        // The line is put in an array called lines, so it can be called over and over by name
        // if the lines did not have unique names you could only draw one line at a time
        // so each line is named in the array after the id of the blob (EG line1280)
        function addBlob(id:Number, origX:Number, origY:Number):void {
            blobs.push( {id: id, origX: origX, origY: origY, myOrigX: x, myOrigY:y} );
 
            var line:Sprite = new Sprite();
            lines["line"+id] = line;
            lines["line"+id].graphics.lineStyle(thickness, color); //<-- config above
            lines["line"+id].graphics.moveTo(origX, origY); //starting point of line to be drawn
            addChild(lines["line"+id]); // add line to stage
        }
 
        // when called, this function removes the blobs from the array
        // cycles through the blobs array until the blob is found by its ID, then it is removed.
        function removeBlob(id:Number):void {
            for (var i=0; i < blobs.length; i++) {
                if (blobs[i].id==id) {
                    blobs.splice(i, 1);
                    return;
                }
            }
        }
 
    }
}

More tutorials available at Documents_and_tutorials