Tag Archives: actionscript

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...

Posted in BitmapData, bezier, functions, misc, motion | Also tagged , | 7 Comments

Smudge Tool #1

Actionscript:
  1. [SWF(backgroundColor = 0xCCCCCC)]
  2. var canvas:BitmapData = new BitmapData(stage.stageWidth,stage.stageHeight,true, 0xFFFFFFFF);
  3. addChild(new Bitmap(canvas));
  4.  
  5. var loader:Loader = new Loader();
  6. loader.load(new URLRequest("http://actionsnippet.com/wp-content/chair.jpg"));
  7. loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete);
  8. function onComplete(evt:Event):void{
  9.     canvas.draw(loader);
  10. }
  11.  
  12. var brush:Shape = new Shape();
  13. var diameter:Number = 120;
  14. var radius:Number = diameter / 2;
  15. var matrix:Matrix = new Matrix();
  16.  
  17. var brushAlpha:BitmapData = new BitmapData(diameter, diameter, true, 0x00000000);
  18. drawRadial();
  19. brushAlpha.draw(brush);
  20.  
  21. var xp:Number = 0, yp:Number = 0, px:Number = 0, py:Number = 0;
  22. var dx:Number, dy:Number;
  23.  
  24. stage.addEventListener(MouseEvent.MOUSE_MOVE, onLoop);
  25. function onLoop(evt:Event):void {
  26.     xp = mouseX - radius;
  27.     yp = mouseY - radius;
  28.     dx = xp - px;
  29.     dy = yp - py;
  30.     canvas.copyPixels(canvas,
  31.                     new Rectangle(px, py, diameter, diameter),
  32.                     new Point(xp, yp), brushAlpha, new Point(0,0), true);
  33.     px = xp;
  34.     py = yp
  35. }
  36.  
  37. function drawRadial():void{
  38.     matrix.createGradientBox(diameter, diameter, 0, 0, 0);
  39.     with (brush.graphics){
  40.         beginGradientFill(GradientType.RADIAL, [0xFFFFFF, 0xFFFFFF], [1,0], [0, 255], matrix, SpreadMethod.PAD);
  41.         drawCircle(radius, radius, radius);
  42.     }
  43. }

This is a quick snippet I wrote while thinking about how to create a smudge tool using BitmapData... it isn't perfect, but it's a good first step. It still needs some linear interpolation and I may need to do some pixel pushing to prevent a strange alpha anomaly that causes the brush to get darker than expected....


Here is the swf...

Posted in BitmapData | Also tagged , | 1 Comment

Isometric Cones (spikes)

Actionscript:
  1. [SWF(width = 600, height = 500, backgroundColor=0xFFFFFF)]
  2.  
  3. var canvas:BitmapData = new BitmapData(stage.stageWidth,stage.stageHeight,false, 0xFFFFFF);
  4. addChild(new Bitmap(canvas));
  5.  
  6. var matrix:Matrix = new Matrix();
  7. var grid:Sprite =   new Sprite();
  8. grid.filters = [new DropShadowFilter(4, 0, 0, 0.05, 20, 10)];
  9. matrix.rotate(Math.PI / 4);
  10. matrix.scale(1, 0.6);
  11. matrix.translate(stage.stageWidth / 2, stage.stageHeight / 2 + 50);
  12. grid.transform.matrix = matrix;
  13.  
  14. var rowCol:int = 9;
  15. var spikeNum:Number = rowCol * rowCol;
  16. var diameter:Number = 30;
  17. var space:Number  = diameter + 10;
  18. var halfGridSize:Number  = rowCol * space / 2;
  19. var radius:Number;
  20. addEventListener(Event.ENTER_FRAME, onLoop);
  21. function onLoop(evt:Event):void {
  22.     radius  = diameter / 2;
  23.     grid.y -= 0.9;
  24.     grid.graphics.clear();
  25.     for (var i:Number = 0; i<spikeNum; i++){
  26.        var xp:Number = i % rowCol;
  27.        var yp:Number = int(i / rowCol);
  28.        drawSpike(xp * space - halfGridSize, yp * space - halfGridSize, (xp + yp) / 4, 0, -yp);
  29.     }
  30.     canvas.draw(grid, grid.transform.matrix);
  31.     diameter -= 0.5;
  32.     if (diameter <3){
  33.         removeEventListener(Event.ENTER_FRAME, onLoop);
  34.     }
  35. }
  36. function drawSpike(xp:Number, yp:Number, rot:Number = 0, xOff:Number=0, yOff:Number = 0):void{
  37.     matrix.createGradientBox(diameter, diameter, rot, xp - radius + yOff, yp - radius + xOff);
  38.     with (grid.graphics){
  39.         beginGradientFill(GradientType.LINEAR, [0xFFFFFF, 0x999999], [1,1], [0, 255], matrix, SpreadMethod.PAD);
  40.         drawCircle(xp, yp, radius);
  41.     }
  42. }

This snippet draws some isometric cones. Here are some images created by tweaking a few of the values:

Posted in 3D, BitmapData, misc | Also tagged , | Leave a comment

Cut Image into Squares (copyPixels)

Actionscript:
  1. [SWF(width=650, height=650)]
  2. var loader:Loader = new Loader();
  3. loader.load(new URLRequest("http://actionsnippet.com/wp-content/chair.jpg"));
  4. loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoaded);
  5.  
  6. var w:Number;
  7. var h:Number;
  8. var rows:Number = 20;
  9. var cols:Number = 20;
  10. var tiles:Vector.<BitmapData> = new Vector.<BitmapData>();
  11. var locX:Vector.<Number> = new Vector.<Number>();
  12. var locY:Vector.<Number> = new Vector.<Number>();
  13. var rX:Vector.<Number> = new Vector.<Number>();
  14. var rY:Vector.<Number> = new Vector.<Number>();
  15. var sX:Vector.<Number> = new Vector.<Number>();
  16. var sY:Vector.<Number> = new Vector.<Number>();
  17. function onLoaded(evt:Event):void{
  18.     w = evt.target.width;
  19.     h = evt.target.height;
  20.     var image:BitmapData = Bitmap(evt.target.content).bitmapData;
  21.     var tileWidth:Number = w / cols;
  22.     var tileHeight:Number = h / rows;
  23.     var inc:int = 0;
  24.     var pnt:Point = new Point();
  25.     var rect:Rectangle = new Rectangle(0,0,tileWidth,tileHeight);
  26.     for (var i:int = 0; i<rows; i++){
  27.         for (var j:int = 0; j<cols; j ++){
  28.              var currTile:BitmapData= new BitmapData(tileWidth, tileHeight, true, 0x00000000);
  29.              rect.x = j * tileWidth;
  30.              rect.y = i * tileHeight;
  31.              currTile.copyPixels(image, rect, pnt, null, null, true);
  32.              tiles[inc] = currTile;
  33.              rect.x += 25;
  34.              rect.y += 25;
  35.              sX[inc] = rect.x;
  36.              sY[inc] = rect.y;
  37.              locX[inc] = rX[inc] = -rect.width * 2
  38.              locY[inc] = rY[inc] =  Math.random() * stage.stageHeight;
  39.              setTimeout(startAnimation, inc *4 + 100, inc, rect.x, rect.y);
  40.              inc++;
  41.         }
  42.     }
  43. }
  44.  
  45. function startAnimation(index:int, dx:Number, dy:Number):void{
  46.     var interval:Number;
  47.     var animate:Function = function(index:int):void{
  48.         locX[index] += (dx - locX[index]) / 4;
  49.         locY[index] += (dy - locY[index]) / 4;
  50.         if (Math.abs(locX[index] - dx) <1 && Math.abs(locY[index] - dy)<1){
  51.             locX[index] = dx;
  52.             locY[index] = dy;
  53.             clearInterval(interval);
  54.         }
  55.     }
  56.    interval = setInterval(animate, 32, index);
  57. }
  58.  
  59. var canvas:BitmapData = new BitmapData(stage.stageWidth,stage.stageHeight,false, 0xFFFFFF);
  60. addChild(new Bitmap(canvas));
  61.  
  62. var loc:Point = new Point();
  63. addEventListener(Event.ENTER_FRAME, onLoop);
  64. function onLoop(evt:Event):void {
  65.       canvas.fillRect(canvas.rect, 0xFFFFFF);
  66.       for (var i:int = 0; i<tiles.length; i++){
  67.             var tile:BitmapData= tiles[i];
  68.             loc.x = locX[i];
  69.             loc.y = locY[i];
  70.             canvas.copyPixels(tile, tile.rect, loc, null, null, true);
  71.       }
  72. }

This snippet cuts a dynamically loaded image into a series of smaller BitmapData instances. These BitmapData instances are then drawn to a canvas BitmapData using copyPixels. The BitmapData.copyPixels() method is extremely fast - so this has some advantages over yesterdays post (which did basically the same thing with Sprites). I used setInterval and setTimeout to do a simple demo animation, but I recommend using TweenLite on a real project.

Posted in BitmapData, Vector | Also tagged , | 10 Comments