Category Archives: functions

Recursive 2D Structure

Actionscript:
  1. [SWF(width = 600, height = 700, frameRate=24)]
  2. var canvas:BitmapData = new BitmapData(stage.stageWidth,stage.stageHeight,false, 0xFFFFFF);
  3. addChild(new Bitmap(canvas));
  4.  
  5. var maxBranches:int = 600;
  6. var branches:int = 0;
  7. var startX:Number = 300
  8. makeBranch(startX,690,30,-60, 60);
  9.  
  10. function makeBranch(xp:Number, yp:Number, step:Number, min:Number, max:Number):void {
  11.     var vectors:Shape = Shape(addChild(new Shape()));
  12.     var cX:Number, cY:Number, eX:Number, eY:Number
  13.     var dcX:Number=xp, dcY:Number=yp, deX:Number=xp, deY:Number=yp;
  14.     var theta:Number = (min + Math.random()*(max-min) - 90) * Math.PI / 180;
  15.     cX = xp + step * Math.cos(theta);
  16.     cY = yp + step * Math.sin(theta);
  17.     theta = (min + Math.random()*(max-min)-90) * Math.PI / 180;
  18.     eX = cX + step * Math.cos(theta);
  19.     eY = cY + step * Math.sin(theta);
  20.     var run:Function = function():void{
  21.          dcX +=  (cX - dcX) / 2;
  22.          dcY +=  (cY - dcY) / 2;
  23.          deX +=  (eX - deX) / 8;
  24.          deY +=  (eY - deY) / 8;
  25.          with(vectors.graphics){
  26.               clear();
  27.               beginFill(0xFFFFFF,0.8);
  28.               lineStyle(0,0x000000,0.8);
  29.               moveTo(startX, yp);
  30.               lineTo(xp, yp);
  31.               curveTo(dcX, dcY, deX, deY);
  32.               lineTo(startX, deY);
  33.          }
  34.          if (Math.abs(dcX - cX) <1 && Math.abs(deX - eX) <1 && Math.abs(dcY - cY) <1 && Math.abs(deY - eY) <1){
  35.              canvas.draw(vectors);
  36.              removeChild(vectors);
  37.              if (branches <maxBranches){
  38.                  setTimeout(makeBranch, 10, deX, deY, step - Math.random(), -90, 90);
  39.                  branches++;
  40.                  if (int(Math.random()*2) == 1){
  41.                     setTimeout(makeBranch, 10, deX, deY, step - Math.random()*3, -90, 90);
  42.                     branches++;
  43.                  }
  44.              }
  45.          }else{
  46.              setTimeout(arguments.callee,  1000 / 24);
  47.          }
  48.     }();
  49. }

This snippet uses a technique similar to what you might use to create a recursive tree. A bit of additional logic is added for bezier branches, filled shapes and animation.

WARNING: may run slow on older machines

Have a look at the swf...

Also posted in BitmapData, bezier, misc, motion | Tagged , , | 7 Comments

Counter Function

Actionscript:
  1. var counter:Function = function(count:Array):Function{
  2.     var leng:int = count.length;
  3.     var index:int = 0;
  4.     return counter = function(reset:*=""):Function{
  5.         if (reset=="reset"){
  6.             index = 0;
  7.             return counter;
  8.         }else
  9.         if (reset is Array){
  10.             count = reset;
  11.             return counter;
  12.         }
  13.         trace(count[index % leng]);
  14.         index++;
  15.         return counter;
  16.     }
  17. }
  18.  
  19. // first time it's called you pass an array
  20. trace("count through the array:");
  21. // you can optionally call trigger the counter by calling the newly
  22. // returned function
  23. counter(["a","b","c"])();
  24. counter();
  25. counter();
  26. trace("change the array:");
  27. // here we choose to simply set the array and not trigger the counter
  28. counter([10,20,40,60,80]);
  29. counter();
  30. counter()
  31. trace("reset the counter:");
  32. // reset and the counter is called 3 times
  33. counter("reset")()()();
  34.  
  35. /*outputs :
  36. count through the array:
  37. a
  38. b
  39. c
  40. change the array:
  41. 10
  42. 20
  43. reset the counter:
  44. 10
  45. 20
  46. 40
  47. */

Today I felt like messing around with functions and this is the result. This snippet shows a strange and interesting technique to create a function that iterates through a given array in a few different ways.

I believe the technical term for this kind of thing is a continuation...

There are a bunch of other posts like this on actionsnippet. Some are purely experimental, others are actually quite useful... these can all be found in the functions category.

Also posted in dynamic | Tagged , , | Leave a comment

Instantiate and Set Properties

Actionscript:
  1. function create(obj:Class, props:Object):*{
  2.     var o:* = new obj();
  3.     for (var p:String in props){
  4.         o[p] = props[p];
  5.     }
  6.     return o;
  7. }
  8.  
  9. // test out the function
  10.  
  11. var txt:TextField = create(TextField, {x:200, y:100, selectable:false, text:"hello there", textColor:0xFF0000, defaultTextFormat:new TextFormat("_sans", 20)});
  12. addChild(txt);
  13.  
  14. var s:Sprite = Sprite(addChild(create(Sprite, {x:100, y:100, rotation:45, alpha:.5})));
  15.  
  16. with (s.graphics) beginFill(0xFF0000), drawRect(-20,-20,40,40);
  17.  
  18. var blur:BlurFilter = create(BlurFilter, {blurX:2, blurY:8, quality:1});
  19.  
  20. s.filters = [blur];

This snippet shows a function called create() that takes two arguments. The first argument is the name of a class to instantiate. The second is an Object with a list of properties to set on a newly created instance of the class (referenced in the first argument).

This could be particularly useful for TextFields which for some reason have no arguments in their constructor.

This will currently only work for classes that have either all optional constructor arguments or no constructor arguments.

Also posted in dynamic, one-liners, properties | Tagged , | Comments closed

Object Argument w/ Defaults

Actionscript:
  1. var boxDefaults:Object = {x:10, y:10, width:100, height:100, lineThickness:0, lineColor:0x000000, lineAlpha:1, fillColor:0xCCCCCC, fillAlpha:1}
  2. function drawBox(params:Object=null):void {
  3.     var p:Object=setDefaults(boxDefaults, params);
  4.     graphics.lineStyle(p.lineThickness, p.lineColor, p.lineAlpha);
  5.     graphics.beginFill(p.fillColor, p.fillAlpha);
  6.     graphics.drawRect(p.x, p.y, p.width, p.height);
  7. }
  8.  
  9. function setDefaults(defaults:Object, params:Object=null):Object {
  10.     if (params==null) {
  11.         params = new Object();
  12.     }
  13.     for (var key:String in defaults) {
  14.         if (params[key]==null) {
  15.             params[key]=defaults[key];
  16.         }
  17.     }
  18.     return params;
  19. }
  20.  
  21. // test it out... notice that all object properties are optional and have default values                                         
  22. drawBox();
  23.  
  24. drawBox({x:200, y:200, lineColor:0xFF0000, lineThickness:2, fillColor:0xCCCC00});
  25.  
  26. drawBox({x:200, y:320, width:50, height:150, lineAlpha:0, fillColor:0x416CCF});

This is a technique I've been using recently... inspired by tweening engines. I find this to be suitable when a function or object constructor has lots and lots of arguments (80% of the time if I have a function or object constructor with too many arguments I re-think my design, but every now and then I use this technique).

Basically, the function or object constructor takes one argument of type Object - once passed into the function this Object argument is passed to the setDefault() function which populates it with any properties that it's missing - each property has a default value. As a result you end up with an easy to read function call with a variable number of arguments and well thought out default values.

This snippet just draws a box (not very interesting or usefull) - I wanted to showcase the technique using a simple function. As a real world example... I recently used this technique in a mini-library I created for use with Box2D... will be posting the library in the next few days.... it's a library for fast prototyping and custom rendering.

Also posted in dynamic | Tagged , | 3 Comments