Tag Archives: as3

XML to ActionScript

Actionscript:
  1. // this xml is inline but could easily be in an external file
  2. var script:XML=<code>
  3.  
  4.   <!-- // call some methods of the main timeline graphics property -->
  5.   <call method="graphics.beginFill" args="0xFF0000" />
  6.    
  7.   <call method="graphics.drawRect" args="0, 0">
  8.      <!-- // use this to access properties of the main movie -->
  9.      <!-- // and use them as arguments -->
  10.      <arg reference="stage.stageWidth" />
  11.      <arg reference="stage.stageHeight" />
  12.   </call>
  13.  
  14.   <call method="graphics.endFill" args=""/>
  15.  
  16.   <call method="graphics.beginFill" args="0x0000FF">
  17.      <!-- //regular non-reference arguments can be passed like this -->
  18.      <arg value="0.5" />
  19.   </call>
  20.  
  21.   <call method="graphics.drawCircle" args="100,100,20" />
  22.  
  23.   <call method="customFunction" args="hello">
  24.      <arg reference="root.loaderInfo.bytesTotal" />
  25.   </call>
  26.  
  27. </code>
  28.  
  29. function customFunction(a:String, b:String):void{
  30.     trace("I am a custom function called from xml");
  31.     trace("Here is an argument: " + a);
  32.     trace("Here is another argument, (total bytes of this swf): " + b);
  33. }
  34.  
  35. // parse and run
  36. runCode(script);
  37.  
  38. function runCode(code:XML):void{
  39.     var children:XMLList = code.children();
  40.     for (var i:int = 0; i<children.length(); i++){
  41.         var child:XML = children[i];
  42.         var type:String = child.name();
  43.         if (type == "call"){
  44.             runMethod(child);
  45.         }
  46.     }
  47. }
  48.  
  49. function runMethod(code:XML):void{
  50.     var i:int = 0;
  51.     // get a reference to the function
  52.     var method:Function = dotSyntax(code.@method);
  53.     // call the function if there are no arguments
  54.     if (code.@args.toXMLString().length == 0 && code.arg.length() == 0){
  55.         method();
  56.     }else{
  57.      
  58.      var args:Array = code.@args.split(",");
  59.      var childArgsLength:int = code.arg.length()
  60.      for (i = 0; i<childArgsLength; i++){
  61.           // add another one with dot syntax
  62.           var val:String = code.arg[i].@value;
  63.           if (val){
  64.             args.push(val);
  65.           }
  66.       }
  67.       for (i = 0; i<args.length; i++){
  68.           if (args[i] != ""){
  69.             args[i] = valueType(args[i]);
  70.           }
  71.       }
  72.       for (i = 0; i<code.arg.length(); i++){
  73.          var rs:String = code.arg[i].@reference;
  74.          if (rs){
  75.              var ref:* = dotSyntax(rs);
  76.              args.push(ref);  
  77.          }
  78.       }
  79.       // run the function
  80.       method.apply(null,args);
  81.     }
  82. }
  83.  
  84. // parse dot syntax and return the last property or method
  85. function dotSyntax(str:String):*{
  86.     var path:Array = str.split(".");
  87.     var curr:* = this;
  88.     for (var i:int = 0; i<path.length; i++){
  89.         curr = curr[path[i]]
  90.     }
  91.     return curr;
  92. }
  93.  
  94. function valueType(val:*):* {
  95.     if (isNaN(Number(val))) {
  96.            // remove leading and trailing white
  97.            // remove "" around strings
  98.            val = val.replace(/^s+|s+$/g,"").replace(/^"|"$/g,"");
  99.            //  see if it's a boolean
  100.            if (val == "true"){
  101.                val = true;
  102.            }else if (val == "false"){
  103.                val = false
  104.            }
  105.     } else {
  106.         val = Number(val);
  107.     }
  108.     return val;
  109. }

WARNING: There area few small bugs in this snippet. If you'd like to use this, check out the AsXML mini-library

A few days ago I had the idea to write some code that would parse ActionScript from XML. The features that I realized would be possible are:

1) call methods of the main timeline
2) read and write properties on the main timeline
3) instantiate classes on the main timeline
4) call methods on these classes
5) read and write properties on these classes

So this morning I wrote the first part. This snippet has the ability to read an XML file and call methods accordingly. It also has the ability to read properties of the main timeline and pass them to these methods.

The XML in this snippet draws a box using the stageWidth and stageHeight. It draws a transparent circle and then calls a custom function. The custom function gets passed the root.loaderInfo.bytesTotal property.

I've done something similar a few times where I specifically targeted the Graphics API. This takes that to the next level by potentially working with any ActionScript classes (excluding Vector maybe... need to think about that).

I'll post another version with more features tomorrow. At the very least it will have class instantiation.

Posted in XML, dynamic, external data, string manipulation | Also tagged , | 6 Comments

Random Guitar Tablature

Actionscript:
  1. // number of notes in chord
  2. var noteNum:int = 3;
  3. var lowNote:Number = 0;
  4. var highNote:Number = 4;
  5. // delay between chords
  6. var delay:int = 2000;
  7. ////////////////////////////////////////
  8. var chord:String = "";
  9. highNote += 1;
  10. var tab:TextField = TextField(addChild(new TextField()));
  11. tab.x = tab.y = 20;
  12. tab.defaultTextFormat = new TextFormat("Courier", 12);
  13. tab.multiline = true;
  14. tab.width = 200;
  15.  
  16. changeChord();
  17. setInterval(changeChord, delay);
  18.  
  19. function changeChord():void{
  20.     var strings:Array = [];
  21.     strings[0] = "e|---------------\n"
  22.     strings[1] = "B|---------------\n"
  23.     strings[2] = "G|---------------\n"
  24.     strings[3] = "D|---------------\n"
  25.     strings[4] = "A|---------------\n"
  26.     strings[5] = "E|---------------\n"
  27.    
  28.     for (var i:int = 0; i<3; i++){
  29.         var place:int = 5 + i * 4;
  30.         var choices:Array = [0,1,2,3,4,5];
  31.         for (var j:int = 0; j<noteNum; j++){
  32.             var ii:int = int(Math.random()*choices.length);
  33.             var index:int = choices[ii];
  34.             strings[index] = strings[index].slice(0, place) + (int(Math.random()*highNote)+lowNote) +  strings[index].substring(place+1);
  35.             choices.splice(ii, 1);
  36.         }
  37.     }
  38.     chord = strings.join("");
  39.     tab.text = chord;
  40. }

I'm working on a small program to help me practice guitar. It randomly generates guitar tabs. The idea for the program is similar to a program that helps you learn to type (like Mavis Beacon).

I wrote this snippet today as a proof of concept - just to help me start thinking about what kind of features I want the program to have. There are settings at the top so that you can tweak the number of notes in the chord and the delay between chords etc....

It generates three chords at a time... here are some stills:

Posted in random, string manipulation, strings | Also tagged , | 6 Comments

Random Negative or Positive

Actionscript:
  1. for (var i:int = 0; i<10; i++){
  2.   // randomly set a variable to -1 or positive 1
  3.   trace(int(Math.random()*2) - 1 | 1);
  4. }
  5.  
  6. /* outputs something like this
  7. 1
  8. 1
  9. -1
  10. 1
  11. -1
  12. -1
  13. 1
  14. 1
  15. -1
  16. -1
  17. */

The past few days I found myself using this one-liner a few times. Just a quick way to randomly get -1 or 1.

I was brainstorming today and wrote a weird/bad inline version of an old post:

var rand:Number = [-3, 2, 1, 1, 1, 0.5][int(Math.random() * 6)];

I need to install a related posts plugin for WordPress - would be nice if this post were related to my old post about Tausworthe random seeds.

Been posting medium/large snippets and snippets the relate to QuickBox2D - so today I figured I'd get back to basics...

Posted in one-liners, random | Also tagged , | 3 Comments

QuickBox2D FRIM

Actionscript:
  1. import com.actionsnippet.qbox.*;
  2. import Box2D.Common.Math.*;
  3.  
  4. // try altering your frame rate
  5. [SWF(backgroundColor=0x000000, width=700, height=600, frameRate=30)]
  6. // try setting frim to false
  7. var sim:QuickBox2D = new QuickBox2D(this, {iterations:20, timeStep:1 / 60, frim:true});
  8.  
  9. sim.setDefault({fillColor:0x003366, lineAlpha:0});
  10. sim.createStageWalls();
  11.  
  12. sim.addBox({x:10, y:18, height:3, density:0});
  13.  
  14. sim.setDefault({fillColor:0x004466, lineColor:0x2B80F5});
  15.  
  16. var cVel:b2Vec2 = new b2Vec2();
  17.  
  18. for (var i:int = 0; i<32; i++){
  19.     var c:QuickObject = sim.addCircle({x:13 + i % 8, y:10 + int(i / 8), friction:0.01, radius:0.2 + Math.random()*0.3, angularDamping:1});
  20.     cVel.x = Math.random() * 4 - 2;
  21.     cVel.y = Math.random() * 4 - 2;
  22.     c.body.SetLinearVelocity(cVel);
  23. }
  24.  
  25. var box:QuickObject = sim.addBox({x:3, y:16, width:2, height: 2});
  26. var boxVel:b2Vec2 = new b2Vec2(15, -25);
  27.  
  28. sim.start();
  29.  
  30. // shoot the box from left to right
  31. setTimeout(positionBox, 200);
  32. function positionBox():void{
  33.     // reset box position
  34.     box.x = 3, box.y = 16;
  35.     setTimeout(shootBox, 500);
  36. }
  37. function shootBox():void{
  38.     box.body.SetLinearVelocity(boxVel);
  39.     box.body.SetAngularVelocity(10);
  40.     // shoot the box again
  41.     setTimeout(positionBox, 4000);
  42. }

You'll need to download the latest version of QuickBox2D in order to run this snippet (alpha 107 as of this post). I recommend checking out the demo below first though...

The most notable feature of this release is FRIM (frame rate independent motion). FRIM is used to attempt to keep the speed of the Box2D simulation constant no matter what frame rate the swf is running at. This is good because frame rates will vary from browser to browser and from computer to computer.

Mr.Doob suggested that I implement this feature in QuickBox2D. If you haven't seen his site I highly recommend checking it out - really great stuff there.

I created a demo to illustrate the FRIM feature... this demo is basically the same as the above snippet with a few extra buttons added to control frame rate and toggle FRIM.


Take a look at the demo here...

While this new feature seems to be working, I believe there still may be room for improvement. Please let me know if the demo doesn't work correctly on your machine. As of now, I've only tested it on my 2.5 Ghz Intel Core 2 Duo.

Also, any suggestions to improve the clarity of this demo are appreciated... I found it kind of hard to think of a good demo to show FRIM in action. The original demo really didn't make much sense... so I gave Rich Shupe a call and he helped me come up with the idea for the current demo.

UPDATE:
I just updated the demo so that the simulation restarts when you change the frame rate (as per Mr.doob's suggestion below)

Posted in Box2D, QuickBox2D, motion | Also tagged , , , | 10 Comments