Disclaimer: Anyone and organizations are welcome to repost the articles in this blog, but the original links and author information must be marked.
Link: http://blog.csdn.net/li_007/archive/2010/01/01/5118098.aspx
Pioneering little turtle -------> csdn
Detailed description of the tuio. As File
Tuioobject. As tuioevent. As tuiocursor. As file detailed comment
I have studied multitouch over a period of time and made a lot of comments on the Code according to my own understanding. Today I have compiled the source code comments for the WordPress 3 version of The touchlib library, which is now released, I hope to discuss the amendment with you. You are also welcome to point out the mistakes or give your own opinions. Subsequent as files will be released slowly after I have finished sorting them out. Okay, paste the Code directly (I would like to host an openframeworks Chinese forum, and then I will publish some personal experiences of CCV and openframeworks. I hope you will study it together)
Package COM. touchlib {</P> <p> Import flash. events. dataevent; <br/> Import flash. events. event; <br/> Import flash. events. ioerrorevent; <br/> Import flash. events. progressevent; <br/> Import flash. events. securityerrorevent; <br/> Import flash. geom. point; <br/> Import flash.net. urlloader; <br/> Import flash.net. URLRequest; <br/> Import flash.net. xmlsocket; <br/> // import flash. system. system; <br/> Import flash. te XT. textfield; <br/> Import flash. text. textfieldautosize; <br/> Import flash. text. textformat; <br/> // import flash. events. mouseevent; <br/> Import flash. display. *; <br/> Import app. core. element. wrapper; <br/> Import flash. events. mouseevent; </P> <p> public class tuio <br/>{< br/> Static Var floscsocket: xmlsocket; <br/> Static Var floscsockethost: string; <br/> Static Var floscsocketport: Number; <br/> Static Var Thestage: stage; </P> <p> // stores all available tuioobject instances. <br/> Static Var objectarray: array; </P> <p> // stores the ID numbers of all available tuiooject objects, but this variable is not used in this source file <br/> Static Var idarray: array; </P> <p> Public Static Var debugmode: Boolean; </P> <p> Static Var debugtext: textfield; <br/> Static Var debugtoggle: textfield; <br/> Static Var recordedxml: XML; <br/> Static Var brecording: Boolean = false; <br/> // Static Var xmlplaybackurl: String = "Www/XML/test. XML "; <br/> Static Var xmlplaybackurl: String =" "; <br/> Static Var xmlplaybackloader: urlloader; <br/> Static Var playbackxml: XML; </P> <p> Static Var binitialized = false; </P> <p> // S: Of course, stage, pass this in the document class. <br/> // host: Server IP address <br/> // port: port. The default CCV value is 3000. <br/> // debugxmlfile: XML file path for debugging <br/> // Debug: A boolen value, indicating whether the current status is debugging (XML debugging is not required) <br/> // This is the initialization function of tuio as 3 Library. The document class can be called at the beginning. <Br/> // <br/> Public static function Init (S: displayobjectcontainer, host: String, Port: Number, debugxmlfile: String, dbug: Boolean = true ): void <br/> {<br/> If (binitialized) <br/> return; <br/> debugmode = dbug; <br/> floscsockethost = host; <br/> floscsocketport = port; <br/> binitialized = true; <br/> thestage = S. stage; // obtain the stage of course document class </P> <p> thestage. align = stagealign. top_left; <br/> thestage. displaystate = ST Agedisplaystate. full_screen; </P> <p> objectarray = new array (); <br/> idarray = new array (); </P> <p> try <br/> {<br/> // establish an XML socket connection with the server, such as CCV. <Br/> // For the xmlsocket programming of flash, you can go to the documentation of ActionScript 3 <br/> floscsocket = new xmlsocket (); </P> <p> floscsocket. addeventlistener (event. close, closehandler); <br/> floscsocket. addeventlistener (event. connect, connecthandler); <br/> floscsocket. addeventlistener (dataevent. data, datahandler); <br/> floscsocket. addeventlistener (ioerrorevent. io_error, ioerrorhandler); <br/> floscsocket. addeventlistener (progresse Vent. progress, progresshandler); <br/> floscsocket. addeventlistener (securityerrorevent. security_error, securityerrorhandler); </P> <p> floscsocket. connect (host, Port); </P> <p>} catch (E) <br/>{< br/>}</P> <p> // if the current status is debugging, set some components required for debugging <br/> If (debugmode) <br/>{< br/> var format: textformat = new textformat (); <br/> debugtext = new textfield (); <br/> format. font = "verdana"; <br/> format. color = 0 xffffff; <br/> Format. size = 10; </P> <p> debugtext. defaulttextformat = format; <br/> debugtext. autosize = textfieldautosize. left; <br/> debugtext. background = true; <br/> debugtext. backgroundcolor = 0x000000; <br/> debugtext. border = true; <br/> debugtext. bordercolor = 0x333333; </P> <p> // Add a dynamic text object to the display list and place it on the top of the display list. <Br/> // In fact, this debugtext object displays the ID number, X, and Y coordinates of the touch point in the debugging status in real time. <br/> thestage. addchild (debugtext); <br/> thestage. setchildindex (debugtext, thestage. numChildren-1); </P> <p> recordedxml = <oscpackets> </oscpackets>; </P> <p> // create a Sprite object for debugging, I will introduce it later <br/> var buttonsprite = new sprite (); <br/> buttonsprite. graphics. beginfill (0 xffffff, 1.0); <br/> buttonsprite. graphics. drawroundrect (0,-10, 50, 60, 10); </P> <p> buttonsprite. ad Deventlistener (mouseevent. click, toggledebug); </P> <p> // create a wrapper object. The wrapper object class is in the app. core. <br/> var wrapperobject: wrapper = new wrapper (buttonsprite); <br/> thestage. addchild (wrapperobject); <br/> thestage. setchildindex (wrapperobject, thestage. numChildren-1); <br/> // trace (thestage. numchildren); </P> <p> // debug XML file processing <br/> If (xmlplaybackurl! = "") <Br/>{< br/> xmlplaybackloader = new urlloader (); <br/> xmlplaybackloader. addeventlistener ("complete", xmlplaybackloaded); <br/> xmlplaybackloader. load (New URLRequest (xmlplaybackurl); </P> <p> thestage. addeventlistener (event. enter_frame, frameupdate); <br/>}</P> <p >}else {<br/> recordedxml = <oscpackets> </oscpackets>; <br/> brecording = false; <br/>}</P> <p> // debug the event processing function after the XML file is loaded <br/> private Static function xmlplaybackloaded (EVT: Event) {<br/> trace ("loaded XML debug data"); <br/> playbackxml = New XML (xmlplaybackloader. data); <br/>}</P> <p> // <br/> Private Static function frameupdate (EVT: Event) <br/>{< br/> If (playbackxml & playbackxml. oscpacket & playbackxml. oscpacket [0]) <br/>{< br/> processmessage (playbackxml. oscpacket [0]); </P> <p> Delete playbackxml. oscpacket [0]; <br/>}</P> <p> // You can see the function from the name. Find all tuioobject instances stored in the objectarray array by ID <br/> Public static function getobjectbyid (ID: number ): tuioobject <br/>{< br/> for (VAR I = 0; I <objectarray. length; I ++) <br/>{< br/> If (objectarray [I]. id = ID) <br/>{< br/> // trace ("found" + id); <br/> return objectarray [I]; <br/>}< br/> // trace ("notfound"); </P> <p> return NULL; <br/>}</P> <p> // This function must be understood in conjunction with the tuioobject class. <Br/> Public static function listenforobject (ID: Number, reciever: Object) <br/>{< br/> var tmpobj: tuioobject = getobjectbyid (ID ); </P> <p> If (tmpobj) <br/>{< br/> tmpobj. addlistener (reciever ); <br/>}</P> <p> // This is the most important data processing function <br/> Public static function processmessage (MSG: XML) <br/>{</P> <p> var fseq: string; <br/> var node: XML; </P> <p> // process the fseq message in the following format: <br/> // tuio/[profilename] fseq int32 <br/> // Profilename indicates the defined fseq value of int32 in the user interface <br/> // fseq <br/> // int32 <br/> for each (node in MSG. message) <br/>{< br/> If (node. argument [0] & node. argument [0]. @ value = "fseq") <br/> fseq = node. argument [1]. @ value; <br/>}< br/> // trace ("fseq =" + fseq); </P> <p> // process alive messages, the format is as follows: <br/> // UIO/[profilename] alive [list of active sessionids] <br/> // profilename indicates the custom frequently-used user interface configuration. <br/> // Alive message identifier <br/> // [list of active sessionids] ID numbers of a series of currently useful target objects <br/> for each (node in MSG. message) <br/>{< br/> If (node. argument [0] & node. argument [0]. @ value = "alive ") <br/>{< br/> // reset the isalive attribute of all tuiooject instances stored in the objectarray array <br/> for each (VAR obj1: tuioobject in objectarray) <br/>{< br/> obj1.isalive = false; <br/>}</P> <p> // a new array is defined here, but it is useless variable. <Br/> var newidarray: array = new array (); </P> <p> // obtain all alive message IDs cyclically <br/> // The alive message is used with the Set message to determine which blobs are useful., that is to say, which set messages contain valid data <br/> // you can use the source code in CCV to understand <br/> for each (VAR aliveitem: XML in node. argument. (@ value! = "Alive") <br/>{< br/> // set the isalive attribute of the tuioobject instance to true based on the ID in the alive message, that is, the current vertex is available <br/> If (getobjectbyid (aliveitem. @ value) <br/> getobjectbyid (aliveitem. @ value ). isalive = true; </P> <p >}</P> <p> // trace (idarray); <br/> idarray = newidarray; <br/>}</P> <p> // process the Set message. <br/> for each (node in MSG. message) <br/>{< br/> If (node. argument [0]) <br/>{< br/> var type: string; </P> <p> // note the differences between the two Prof types 2dobj and 2dcur. The difference between Ile and its structure is as follows, for more information, see tuio protocol specification <br/> // tuio/2 dobj set S I x y a M r <br/> // /tuio/2 dcur set S x Y x y m <br/> // The message structure of/tuio/2dcur is sent by the CCV, therefore, I will first annotate/tuio/2dcur structure Message Processing <br/> // comments for/tuio/2dobj message processing will be added later. </P> <p> If (node. @ name = "/tuio/2 dobj") <br/>{< br/> type = node. argument [0]. @ value; <br/> If (type = "set") <br/> {<br/> var SID = node. argument [1]. @ value; <br/> var id = node. argument [2]. @ value; <br/> var x = Number (node. argument [3]. @ value) * thestage. stagewidth; <br/> var y = Number (node. argument [4]. @ value) * thestage. stageheight; <br/> var A = Number (node. argument [5]. @ value); <br/> var x = Number (node. A Rgument [6]. @ value); <br/> var y = Number (node. argument [7]. @ value); <br/> var A = Number (node. argument [8]. @ value); <br/> var M = node. argument [9]. @ value; <br/> var r = node. argument [10]. @ value; </P> <p> // send object update event .. </P> <p> var objarray: array = thestage. getobjectsunderpoint (new point (x, y); <br/> var stagepoint: Point = new point (x, y); <br/> var displayobjarray: array = thestage. getobjectsunde Rpoint (stagepoint); <br/> var dobj = NULL; </P> <p> // If (displayobjarray. length> 0) <br/> // dobj = displayobjarray [displayobjarray. length-1]; </P> <p> var tuioobj = getobjectbyid (ID); <br/> If (tuioobj = NULL) <br/>{< br/> tuioobj = new tuioobject ("2 dobj", ID, X, Y, X, Y, Sid, A, dobj ); <br/> thestage. addchild (tuioobj. SPR); </P> <p> objectarray. push (tuioobj); <br/> tuioobj. policycreated (); <br/>}else {<br/> TU Ioobj. SPR. X = x; <br/> tuioobj. SPR. y = y; <br/> tuioobj. X = x; <br/> tuioobj. y = y; <br/> tuioobj. DX = x; <br/> tuioobj. DY = y; </P> <p> tuioobj. setobjover (dobj); <br/> tuioobj. policymoved (); <br/>}</P> <p> try <br/>{< br/> If (tuioobj. OBJ & tuioobj. OBJ. parent) <br/>{</P> <p> var localpoint: Point = tuioobj. OBJ. parent. globaltolocal (stagepoint); <br/> tuioobj. OBJ. dispatchevent (New tuioevent (tuioevent. tuio_move, tr UE, false, X, Y, localpoint. x, localpoint. y, tuioobj. oldx, tuioobj. oldy, tuioobj. OBJ, false, true, M, "2 dobj", ID, Sid, A); <br/>}< br/>} catch (E) <br/>{< br/>}< br/> // <br/> // tuio/2 dcur set S x Y x y m <br/> // <br/> else if (node. @ name = "/tuio/2 dcur") <br/>{< br/> // trace ("2 dcur"); <br/> type = node. argument [0]. @ value; </P> <p> // determines whether the message type is set. <br/> If (type = "set") <br/> {<Br/> // the ID of the current vertex <br/> var id = node. argument [1]. @ value; </P> <p> // convert X, Y is multiplied by the stage width and height to the horizontal and vertical coordinates in the global stage coordinates of the current point. <br/> // note why is it multiplied by the stage width and height respectively, need to carefully understand <br/> var x = Number (node. argument [2]. @ value) * thestage. stagewidth; <br/> var y = Number (node. argument [3]. @ value) * thestage. stageheight; </P> <p> // the displacement of the current point. <br/> var x = Number (node. argument [4]. @ value); <br/> var y = Number (node. argument [5]. @ value); </P> <p> // This The value is based on the interpretation of tuio protocol specification and the source code implementation in CCV, which leads to a conflict in my understanding. <Br/> // I need to perform subsequent lab verification. So I do not comment again, but also hope that the discussion with me (leezhm@126.com) <br/> var M = node. argument [6]. @ value; <br/> // var area = node. argument [7]. @ value; </P> <p> var stagepoint: Point = new point (x, y ); </P> <p> // the following code segment is an important part of understanding <br/> // obtain all the displayed objects under the point on the stage based on the coordinates of the current point. For more information about the getobjectsunderpoint function <br/> // you can view docs of ActionScript 3, which returns an array containing all objects <br/> var displayobjarray: array = thestage. getobjectsunderpoint (stagepoint); <br/> var dobj = NULL; </P> <p> // Based on the returned array, get the upper-level Display object <br/> // Why do you want to get the upper-level Display object? How does one implement a touch response? <Br/> // For example, there is a movieclip on the stage and a button on the MC. <Br/> // when your hand touches this button, we get the coordinates of the current vertex (stagex and stagey ), in this way, we <br/> // use the above method to obtain all the display objects under this point, including buttons and movieclip. At this time, we need to obtain the <br/> // top-level button, and then let the button send an event such as tuioevent. tuio_down. Then we only need to <br/> // listen to the tuio_down event on the button in our flash. <Br/> // understand? This is how elements respond to events from a point on the screen to the Flash stage. Learn about the event mechanism of event 3 <br/>. This reminds me of how mouse events are implemented in the box2d library. <Br/> If (displayobjarray. length> 0) <br/> dobj = displayobjarray [displayobjarray. length-1]; </P> <p> var sztmp: String = ""; <br/> // For (VAR I = 0; I <displayobjarray. length; I ++) <br/> // sztmp + = (displayobjarray [I] Is interactiveobject) + ","; <br/> // trace (sztmp ); </P> <p> // query whether a tuioojbect instance exists in the objectarray Array Based on the current ID. <br/> var tuioobj = getobjectbyid (ID ); <br/> If (tuioobj = NULL) <br/>{< br/> // The response tuioo is created Bject object and add it to the stage and array (I personally don't think it is necessary to load it to the stage, <br/> // In addition, a Sprite is redefined for loading, which is a bit redundant) <br/> // note that the last parameter in the parameters passed by the tuioobject instance is created here. Of course, this should also be understood in conjunction with the tuioobject class <br/>. The specifics will be commented out in the tuioobject class. <Br/> tuioobj = new tuioobject ("2 dcur", ID, X, Y, X, Y,-1, 0, dobj); <br/> // tuioobj. area = area; <br/> thestage. addchild (tuioobj. SPR); <br/> objectarray. push (tuioobj); </P> <p> // send tuio_over and tuio_down messages (please refer to the tuioobject code) <br/> tuioobj. policycreated (); <br/>}< br/> else <br/>{< br/> // The information of the current vertex is updated. <br/> tuioobj. SPR. X = x; <br/> tuioobj. SPR. y = y; <br/> tuioobj. X = x; <br/> tuioobj. y = y; <br/> // tuioobj. are A = area; <br/> tuioobj. DX = x; <br/> tuioobj. DY = y; </P> <p> tuioobj. setobjover (dobj); <br/> tuioobj. notifymoved (); <br/>}</P> <p> try <br/> {<br/> // send the tuio_move message <br/> If (tuioobj. OBJ & tuioobj. OBJ. parent) <br/>{< br/> var localpoint: Point = tuioobj. OBJ. parent. globaltolocal (stagepoint); <br/> tuioobj. OBJ. dispatchevent (New tuioevent (tuioevent. tuio_move, true, false, X, Y, localpoint. x, localpoint. y, tuio OBJ. oldx, tuioobj. oldy, tuioobj. OBJ, false, true, M, "2 dobj", ID, Sid, A); <br/>}< br/>} catch (E) <br/>{< br/> trace ("dispatch event failed" + tuioobj. name ); <br/>}</P> <p >}< br/>}</P> <p> // set debugging display text <br/> If (debugmode) <br/>{< br/> debugtext. TEXT = ""; <br/> debugtext. y =-2000; <br/> debugtext. X =-2000; <br/>}</P> <p> for (VAR I = 0; I <objectarray. length; I ++) <br/>{< br/> // If the current vertex is not alive, the total objectarray array is removed and the current vertex is clear. <Br/> If (objectarray [I]. isalive = false) <br/>{< br/> objectarray [I]. kill (); <br/> thestage. removechild (objectarray [I]. SPR); <br/> objectarray. splice (I, 1); <br/> I --; <br/>}< br/> else <br/>{< br/> // The coordinates of the current vertex (stagex and stagey) are displayed in the debugging status) <br/> If (debugmode) <br/>{< br/> debugtext. appendtext ("" + (I + 1) + "-" + objectarray [I]. ID + "X:" + int (objectarray [I]. x) + "Y:" + int (objectarray [I]. y) + "/N"); <br/> Debu Gtext. X = thestage. stageWidth-160; <br/> debugtext. y = 40; <br/>}</P> <p> Private Static function toggledebug (E: Event) <br/>{< br/> If (! Debugmode) {<br/> debugmode = true; <br/> floscsocket. connect (floscsockethost, floscsocketport); <br/> e.tar get. X = 20; <br/>}< br/> else {<br/> debugmode = false; <br/> floscsocket. connect (floscsockethost, floscsocketport); <br/> e.tar get. X = 0; <br/>}</P> <p> // show XML <br/> // brecording = false; <br/> // debugmode = false; <br/> // debugtext. TEXT = recordedxml. tostring (); <br/> // debugtext. X = 0; <br/> // debugtext. y = 0; <br/>}</P> <p> Private Static function closehandler (Event: Event): void {<br/> // trace ("closehandler: "+ Event); <br/>}</P> <p> Private Static function connecthandler (Event: Event): void {<br/> // trace (" connecthandler: "+ Event); <br/>}</P> <p> Private Static function datahandler (Event: dataevent ): void {</P> <p> // trace ("datahandler:" + Event); </P> <p> If (brecording) <br/> recordedxml. appendchild (XML (event. data); </P> <p> processmessage (XML (event. data); <br/>}</P> <p> Private Static function ioerrorhandler (Event: ioerrorevent): void {<br/> // thestage. tfdebug. appendtext ("ioerror:" + event + "/N"); <br/> trace ("ioerrorhandler:" + Event ); <br/>}</P> <p> Private Static function progresshandler (Event: progressevent): void {<br/> // trace ("progresshandler loaded:" + event. bytesloaded + "Total:" + event. bytestotal); <br/>}</P> <p> Private Static function securityerrorhandler (Event: securityerrorevent): void {<br/> trace ("securityerrorhandler: "+ Event); <br/> // thestage. tfdebug. appendtext ("securityerror:" + event + "/N"); <br/>}< br/>}
PS: To be honest, this code is really not standard, and it looks a bit annoying.