The Big init() (nesting DisplayObjects)

Actionscript:
  1. function nest(top:DisplayObjectContainer, structure:Array):void{
  2.        var p:DisplayObjectContainer;
  3.        var key:String;
  4.        for (var i:int = 0; i<structure.length; i++){
  5.                if (structure[i] is DisplayObjectContainer){
  6.                     p = structure[i];
  7.                     if (!p.parent){
  8.                       top.addChild(p);
  9.                     }
  10.                     i++;
  11.                     if (structure[i] is Array){
  12.                                var child:DisplayObject;
  13.                                for (var j:int= 0; j<structure[i].length;  j++){
  14.                                        var val:* = structure[i][j];
  15.                                        if (val is DisplayObject){
  16.                                                child = val;
  17.                                                p.addChild(child);
  18.                                        }else{
  19.                                                for (key in val){
  20.                                                   child[key] = val[key];  
  21.                                                }
  22.                                        }
  23.                                }
  24.                        }else{
  25.                                trace("error, expecting Array");
  26.                                break;
  27.                        }
  28.                }else{
  29.                 trace("error, expecting DisplayObjectContainer (Sprite or MovieClip)");
  30.                        break;
  31.                }
  32.        }
  33. }
  34.  
  35. // create some filler graphics
  36. var window:Sprite = createWindow();
  37. window.x = 10;
  38. window.y = 10;
  39.  
  40. var c0:Sprite = createCircle();
  41. var c1:Sprite = createCircle();
  42. var c2:Sprite = createCircle();
  43. var c3:Sprite = createCircle();
  44. var c4:Sprite = createCircle(0xEFEFEF);
  45.  
  46. var box:Sprite = createBox(60, 50);
  47.  
  48.  
  49. var txt:TextField = new TextField();
  50. txt.text = "HI THERE";
  51.  
  52. // test out the function....
  53. nest(this, [window, [ c0, {x:100, y:100, scaleX:.5, scaleY:.5},
  54.                                     c1, {x:120, y:100, scaleX:.6, scaleY:.6},
  55.                                     c2, {x:140, y:100, scaleX:.7, scaleY:.7},
  56.                                     c3, {x:160, y:100, scaleX:.8, scaleY:.8},
  57.                                     box, {x:10, y:10} ],
  58.                         box, [ txt, c4,{x :30, y:30} ] ]);
  59.  
  60.  
  61. // just some quick functions to create filler graphics
  62.  
  63. function createBox(w:Number, h:Number):Sprite{
  64.     var s:Sprite = new Sprite();
  65.     with(s.graphics) beginFill(0x666666), drawRect(0,0, w, h);
  66.     return s;
  67. }
  68. function createWindow():Sprite{
  69.        var s:Sprite = new Sprite();
  70.        with(s.graphics) beginFill(0xCCCCCC), drawRect(0,0,300,300);
  71.        return s;
  72. }
  73. function createCircle(col:uint = 0xFF0000):Sprite{
  74.        var s:Sprite = new Sprite();
  75.        with(s.graphics) beginFill(col), drawCircle(0,0,10);
  76.        return s;
  77. }

The above uses a function called nest(). nest() is sort of like a superAddChild() function... it is meant to do the same thing as addChild, but with any number of parents and children.

I'm actually not very happy with this function, it was fun to write... but the 2D-Array/Object format is kind of odd looking (see line 53). So for at least the next day or two I'm going to try and think of the best format for a function that could do any number of addChild() calls with any number of children or parents. I realized that I also want to be able to set the properties of any of the children... so one solution might be an xml argument... something like:

Actionscript:
  1. <window>
  2.   <c0 x="100" y="100" />
  3.   <c1 x="200" y="100" />
  4.   <c2 x="300" y="100" />
  5.   <box x="400" y="100" alpha=".5">
  6.      <c3 x="10" y="10" />
  7.   </box>
  8. </window>

That's easy enough to do... it would be nice to think of something more minimalistic, but I think XML is much easier to read than JSON style Object syntax...

It's actually interesting to try and think of minimalistic ways to represent tree structures... check out this failed attempt:

Actionscript:
  1. p(window);
  2. __(c0, {x:100, y:100});
  3. __(c1, {x:100, y:100});
  4. __(c2, {x:100, y:100});
  5.  
  6. p(__(box, {x:100, y:100}));
  7. __(txt, c4, {x:30, y:30});

After writing the above... a few hours later I thought of this:

Actionscript:
  1. propOrder("x", "y", "scaleX", "scaleY", "alpha");
  2.  
  3. bigInit(this, [window, [info, 10, 10,
  4.                         about, 20, 10,
  5.                         contact, 30, 10,
  6.                         box, 40, 10, 2, 2, .5],
  7.                   box, [txt0, 10, 10 * off(),
  8.                         txt1, 10, 10 * off(),
  9.                         txt2, 10, 10 * off(),
  10.                         txt3, 10, 10 * off()],
  11.                   border]);

I think that's pretty close to what I was imagining in terms of simplicity.. the off() function would return an incremental offset... so call it once and it's 0, call it again and it's 1 etc... still not completely happy with this, but it's getting there...

Any additional thoughts on this topic will be in tomorrows post I think.

Posted in misc | Tagged , | Leave a comment

“in” Operator

Actionscript:
  1. var obj:Object = {name: "Joe", hobby: "Guitar", age:"80"};
  2.  
  3. if ("name" in obj){
  4.     trace(obj, " has a name property");
  5. }
  6.  
  7. if ("x" in obj == false){
  8.     trace(obj, " doesn't have an x property");
  9. }
  10.  
  11.  
  12. var mySprite:Sprite = new Sprite();
  13.  
  14. if ("currentFrame" in mySprite == false){
  15.     trace(mySprite, "does not have a currentFrame property");
  16. }

The "in" operator can be used to check if an object has a specific property. In the above example I test a standard Object instance and a Sprite instance for a few different properties.

I could see this operator being used when dealing with * (wildcard) datatypes and dynamic style code....

Posted in Operators, dynamic | Tagged , | Leave a comment

Crackable String Encoding

Actionscript:
  1. var encode:Object = new Object();
  2. var decode:Object = new Object();
  3. var a:Array = " abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890".split("");
  4.  
  5. // change this for different encoded results
  6. var offset:int = 10;
  7.  
  8. for (var i:int = 0; i<a.length; i++){
  9.     var index:int = (a.length - i - offset) % a.length;
  10.     encode[a[i]] = a[index];
  11.     decode[a[index]] = a[i];
  12. }
  13.  
  14. function encodeString(str:String):String{
  15.     return map(str, encode);
  16. }
  17.  
  18. function decodeString(str:String):String{
  19.     return map(str, decode);
  20. }
  21.  
  22. function map(str:String, smode:Object):String{
  23.     var n:String = "";
  24.     for (var i:int = 0; i<str.length; i++){
  25.         var char:String = str.charAt(i);
  26.         var en:String = smode[char];
  27.         if (en){
  28.             n += en;
  29.         }else{
  30.             n += char;
  31.         }
  32.     }
  33.     return n;
  34. }
  35.  
  36. // test out the functions
  37.  
  38. var input:String = "This is a regular string";
  39.  
  40. trace(input);
  41.  
  42. var encoded:String = encodeString(input);
  43.  
  44. trace("encoded: ", encoded);
  45.  
  46. trace("decoded: ",decodeString(encoded));
  47.  
  48. /*
  49. outputs:
  50.  
  51. This is a regular string
  52. encoded:  gSRH1RH1Z1IVTFOZI1HGIRMT
  53. decoded:  This is a regular string
  54.  
  55. */

The above demos an intentionally simple string encoding technique.

This is a technique I use if I need to encode strings but don't care if someone figures out what the string value actually is. For me, this is more common than needing hard/impossible to crack string encoding algorithms. A good example is an e-card... a url for an ecard could look like this:

www.birthdaycardthing.com/?name=joe&age=32

or it could look like this:

www.birthdaycardthing.com/?i=brx&x=5p

I wrapped this snippet up into a class and made a few minor tweaks. The class is called SimpleCipher it has two static methods and one static property...

Actionscript:
  1. import com.actionsnippet.utils.SimpleCipher;
  2. // same as offset above, but can be set at any time
  3. // new encode and decode Objects will be calculated
  4. SimpleCipher.offset = 1;
  5. var input:String = "SimpleCipher encoding and decoding";
  6.              
  7. trace("input: ", input);
  8.              
  9. var encoded:String = SimpleCipher.encode(input);
  10.              
  11. trace("encoded: ", encoded);
  12. trace("decoded: ", SimpleCipher.decode(encoded));
  13. /*
  14. outputs:
  15. input:  SimpleCipher encoding and decoding
  16. encoded:  RhlokdBhogdq0dmbnchmf0 mc0cdbnchmf
  17. decoded:  SimpleCipher encoding and decoding
  18. */

Download SimpleCipher Class
(this class uses a static initializer... see yesterdays post)

Posted in OOP, strings | Tagged , | Leave a comment

Static Constructor / Initializer

Actionscript:
  1. package{
  2.    
  3.     public class Lookup{
  4.        
  5.         private static var _random:Array;
  6.         // static initializer
  7.         {
  8.             trace("I am a static initializer for " + Lookup);
  9.             init();
  10.         }
  11.        
  12.         private static function init():void{
  13.              _random = new Array();
  14.              // generate some filler values
  15.              for (var i:int = 0; i<100; i++){
  16.                 _random.push(Math.random() * i);
  17.              }
  18.         }
  19.        
  20.         public static function get random():Array{
  21.             return _random.concat();
  22.         }
  23.     }
  24. }

...and to test out the above class:

Actionscript:
  1. package {
  2.     import flash.display.Sprite;
  3.  
  4.     public class Main extends Sprite{
  5.         public function Main(){
  6.            trace(Lookup.random[50]);
  7.         }
  8.     }
  9. }
  10. /*
  11. outputs:
  12. I am a static initializer for [class Lookup]
  13. 5.4258062043227255
  14. */

The above shows how to use static initializers. I've found this to be very handy... in this case we create an array of random values....

Tomorrow I'll actually post a real class where I make use of this... the Lookup class in this case is really just filler code....

Posted in OOP | Tagged , | 1 Comment