Category Archives: motion

BitmapData & Particles

Actionscript:
  1. stage.frameRate = 30;
  2. stage.quality = StageQuality.LOW;
  3.  
  4. var canvas:BitmapData = new BitmapData(400,400,false, 0x000000);
  5. addChild(new Bitmap(canvas));
  6. var overlay:BitmapData = new BitmapData(400,400,true, 0x12000000);
  7. var particles:Dictionary = new Dictionary(true);
  8.  
  9. var blur:Array = [new BlurFilter(8,8,1)];
  10.    
  11. addEventListener(Event.ENTER_FRAME, onLoop);
  12. function onLoop(evt:Event):void {
  13.     for (var i:int= 0; i<3; i++) createParticle();
  14.     canvas.copyPixels(overlay, canvas.rect, new Point(0,0), null, null, true);
  15. }
  16.  
  17. function createParticle():void{
  18.     var s:MovieClip = new MovieClip();
  19.     var diameter:Number = Math.random()*50 + 2;
  20.     var radius:Number = diameter / 2;
  21.     var mat:Matrix = new Matrix();
  22.     mat.createGradientBox(diameter, diameter, 0, -radius, -radius);
  23.     mat.createGradientBox(diameter, diameter, 0, -radius, -radius);
  24.     s.graphics.beginGradientFill(GradientType.RADIAL, [ 0xFFCC32, 0xFF0000], [0.5,0.8], [0, 255], mat, SpreadMethod.PAD);
  25.     s.graphics.drawCircle(0,0,radius);
  26.     s.velX = 0;
  27.     s.velY =  -Math.random()*6 + 3;
  28.     s.posX = s.x = 150+ Math.random() * 100;
  29.     s.posY = s.y = 200;
  30.     s.theta= Math.random() * Math.PI * 2;
  31.     s.inc = Math.random() * 0.4 + 0.01;
  32.     s.rad = Math.random() * 4 + 1;
  33.     s.filters = blur;
  34.     // since the particles aren't on the display list, we need to keep a reference to them
  35.     particles[s] = s;
  36.     s.addEventListener(Event.ENTER_FRAME, onRunParticle);
  37. }
  38. function onRunParticle(evt:Event):void {
  39.     var s:MovieClip = MovieClip(evt.currentTarget);
  40.     s.posX += s.velX;
  41.     s.posY += s.velY;
  42.     s.velX = s.rad * Math.cos(s.theta);
  43.     s.theta += s.inc;
  44.     s.scaleX = s.scaleY -=  .03;
  45.     if (s.scaleX <0){
  46.         particles[s] = null;
  47.         s.removeEventListener(Event.ENTER_FRAME, onRunParticle);
  48.     }
  49.     s.x = s.posX;
  50.     s.y = s.posY;
  51.     canvas.draw(s, s.transform.matrix, null, BlendMode.ADD);
  52. }

This is a slight variation on a simple particle system that I show in my intermediate class. It is almost the same as this example. But it makes use of filters and BitmapData.

Here is a still generated with this snippet. You'll notice it vaguely resembles fire.

If you need more particles, there are other approaches that are more appropriate.

Also posted in BitmapData, Graphics | Tagged , , | Leave a comment

Gesture Capture

Actionscript:
  1. var canvas:Shape = Shape(addChild(new Shape()));
  2. var gestures:Array=[];
  3. var gestureNum:int = 0;
  4. var capGesture:Array;
  5. stage.addEventListener(MouseEvent.MOUSE_DOWN, onDown);
  6. stage.addEventListener(MouseEvent.MOUSE_UP, onUp);
  7. function onDown(evt:MouseEvent):void{
  8.      capGesture=[];
  9.      addEventListener(Event.ENTER_FRAME, onCapture);
  10.    
  11.      canvas.graphics.lineStyle(3, 0xFF0000);
  12.      canvas.x = mouseX;
  13.      canvas.y = mouseY;
  14.      canvas.graphics.moveTo(0, 0);
  15. }
  16. function onUp(evt:MouseEvent):void{
  17.     gestures.push(capGesture.concat());
  18.     gestureNum++;
  19.      canvas.graphics.clear();
  20.     removeEventListener(Event.ENTER_FRAME, onCapture);
  21. }
  22. function onCapture(evt:Event):void{
  23.     capGesture.push(new Point(canvas.mouseX, canvas.mouseY));
  24.     canvas.graphics.lineTo(canvas.mouseX, canvas.mouseY);
  25. }
  26.  
  27. var currGesture:Array;
  28. var drawing:Boolean = false;
  29. var lineThickness:Number = 0;
  30. var lineColor:Number = 0x000000;
  31. var index:int = 0;
  32. var pnt:Point;
  33. var trans:Matrix = new Matrix();
  34. var i:int
  35. addEventListener(Event.ENTER_FRAME, onLoop);
  36. function onLoop(evt:Event):void{
  37.     if (gestureNum> 0){
  38.         if (!drawing){
  39.           currGesture = gestures[int(Math.random() * gestureNum)].concat();
  40.           trans.identity();
  41.           trans.rotate(Math.random()*6.28);
  42.           var scale:Number = Math.random() * 2 + .1;
  43.           trans.scale(scale, scale);
  44.           trans.tx = Math.random() * stage.stageWidth
  45.           trans.ty = Math.random() * stage.stageHeight
  46.           for (i = 0; i<currGesture.length; i++){
  47.              currGesture[i] = trans.transformPoint(currGesture[i]);  
  48.           }
  49.           lineThickness = Math.random() * Math.random() * 50;
  50.           if (int(Math.random()*10) ==1){
  51.              var col:uint = uint(Math.random()*255);
  52.              lineColor = col <<16 | col <<8 | col;
  53.           }
  54.           index = 0;
  55.           drawing = true;
  56.           graphics.lineStyle(lineThickness, lineColor);
  57.         }else{
  58.            for (i = 0; i<10; i++){
  59.                 if (drawing == true){
  60.                    pnt = currGesture[index];
  61.                    if (index == 0){
  62.                       graphics.moveTo(pnt.x, pnt.y);  
  63.                    }else{
  64.                       graphics.lineTo(pnt.x, pnt.y);
  65.                    }
  66.                    index++;
  67.                    if (index == currGesture.length){
  68.                        drawing = false;
  69.                    }
  70.                }
  71.            }
  72.         }
  73.     }
  74. }

This snippet is an idea I have been meaning to try for sometime. It's a mini-drawing program. You can draw single gestures (shapes, letters etc...) and the program then randomly scales, rotates, tints and translates these gestures repeatedly on the canvas. You can continue to draw as it does this, the more gestures you draw, the more the program will have to randomly choose from.


Have a look at the swf here...

Also posted in Graphics, misc | Tagged , , | Leave a comment

2D Map Avoid

Actionscript:
  1. [SWF(width=401,height=401,background=0xEFEFEF)]
  2.  
  3. var w:Number = stage.stageWidth-1;
  4. var h:Number = stage.stageHeight-1;
  5. var tileSize:Number = 20;
  6. var halfTileSize:Number = 20;
  7. var hTiles:Number = w / tileSize;
  8. var vTiles:Number = h / tileSize;
  9. var world:Shape = Shape(addChild(new Shape()));
  10. var map:Array=[];
  11. populateMap();
  12. var gridColor:uint = 0xCCCCCC;
  13. grid(tileSize,  gridColor);
  14.  
  15. vTiles -= 1;
  16. var movers:Array = [];
  17. for (var i:int = 0; i<100; i++){
  18.     movers.push(makeMover(i % hTiles, int( i / hTiles),0x000000))
  19.     movers.push(makeMover(i % hTiles, vTiles - int( i / hTiles),0xFF0000))
  20. }
  21. var moverNum:int = movers.length;
  22. hTiles -= 1;
  23.  
  24. addEventListener(Event.ENTER_FRAME, onLoop);
  25. function onLoop(evt:Event):void {
  26.     world.graphics.clear();
  27.     for (var i:int = 0; i<moverNum; i++){
  28.        movers[i]();
  29.      }
  30. }
  31. function populateMap():void{
  32.     for (var i:int = 0; i<vTiles; i++){
  33.         map[i] = [];
  34.         for (var j:int = 0; j<hTiles; j++){
  35.             map[i][j] = 0;
  36.         }
  37.     }
  38. }
  39. function grid(size:Number=30, lineColor:uint=0xFFFF00, lineAlpha:Number=1):void {
  40.     with(graphics){
  41.         lineStyle(0, lineColor, lineAlpha);
  42.         drawRect(0,0,w,h);
  43.         for (var i:Number = size; i<w; i+=size) {
  44.             moveTo(i, 0);
  45.             lineTo(i, w);
  46.         }
  47.         for (i = size; i<h; i+=size) {
  48.             moveTo(0, i);
  49.             lineTo(h, i);
  50.         }
  51.     }
  52. }
  53. function makeMover(x:Number, y:Number, col:uint):Function{
  54.     var xp:Number = x;
  55.     var yp:Number = y;
  56.     var prevX:Number = x;
  57.     var prevY:Number = y;
  58.     map[yp][xp] = 1;
  59.     var dx:Number = xp;
  60.     var dy:Number = yp;
  61.     var counter:int = 0;
  62.     return function():void{
  63.         if (counter> 20){
  64.             if (int(Math.random()*30) == 1){
  65.                 xp += int(Math.random()*2) - 1 | 1;
  66.                 xp = xp <0 ? 0 : xp;
  67.                 xp = xp> hTiles ? hTiles : xp;
  68.                 if (map[yp][xp] == 1){
  69.                      xp = prevX;
  70.                 }else{
  71.                     map[prevY][prevX] = 0;
  72.                     map[yp][xp] = 1;
  73.                     counter = 0;
  74.                 }
  75.                 prevX = xp;
  76.             }else
  77.             if (int(Math.random()*30) == 1){
  78.                 yp += int(Math.random()*2) - 1 | 1;
  79.                 yp = yp <0 ? 0 : yp;
  80.                 yp = yp> vTiles ? vTiles : yp;
  81.                 if (map[yp][xp] == 1){
  82.                      yp = prevY;
  83.                 }else{
  84.                     map[prevY][prevX] = 0;
  85.                     map[yp][xp] = 1;
  86.                     counter = 0;
  87.                 }
  88.                 prevY = yp;
  89.             }
  90.         }
  91.         counter++;
  92.         dx += (xp - dx) * 0.5;
  93.         dy += (yp - dy) * 0.5;
  94.         with(world.graphics){
  95.             lineStyle(0, gridColor,1, true)
  96.             beginFill(col);
  97.             drawRect(dx * tileSize, dy * tileSize, tileSize, tileSize);
  98.         }
  99.     }
  100. }

This (somewhat long) snippet moves boxes around on a grid - the boxes avoid one another by reading values in a 2D array. This technique can also be used for collision detection in tile-based games.


Have a look at the swf here...

Also posted in arrays, random | Tagged , , | Leave a comment

2x mod 1 map

Actionscript:
  1. [SWF(width=800, height=600)]
  2. var xn1:Number;
  3. var xn:Number = Math.random() * Math.random() * .2;
  4. var inc:int = 0;
  5. var xp:Number = 10;
  6. var yp:Number = 10;
  7. var count:int = 1;
  8. scaleX = scaleY = 2;
  9. graphics.lineStyle(0,0x00000);
  10. addEventListener(Event.ENTER_FRAME, onLoop);
  11. function onLoop(evt:Event):void {
  12.    
  13.      xn1 = 2 * xn % 1;
  14.      xn = xn1;
  15.      if (inc == 0){
  16.           graphics.moveTo(xp + inc, yp + 30 - xn1 * 30);
  17.      }else{
  18.          graphics.lineTo(xp + inc, yp + 30 - xn1 * 30);
  19.      }
  20.      inc++
  21.      if (inc == 50){
  22.          inc = 0;
  23.          xp = 10 + count % 6 * 60;
  24.          yp = 10 + int(count / 6) * 60;
  25.          xn = Math.random() * Math.random() * .2;
  26.          trace(xn);
  27.          count++;
  28.      }
  29. }

This snippet plots 2x mod 1 maps with random starting values for xn. More info over at wikipedia and mathworld.

Also posted in Math, misc | Tagged , , | Leave a comment