Tag Archives: actionscript

Variable Swap

Actionscript:
  1. //
  2. // swap some variables
  3. // all techniques except the first are from http://cpptruths.blogspot.com/2006/04/swapping-two-integers-in-one-liner.html
  4. //
  5. var a:Number = 1.1;
  6. var b:Number= 2.2;
  7.  
  8. trace(a, b);
  9.  
  10. // best, fastest, easiest to read way
  11. var t:Number= a;
  12. a = b;
  13. b = t;
  14.  
  15. trace(a, b);
  16.  
  17. // not recommended slower ways:
  18.  
  19. b=a+b-(a=b);
  20.  
  21. trace(a, b);
  22.  
  23. // xor versions will only work with ints and uints
  24. trace("\nxor kills decimals:");
  25.  
  26. // easy to understand xor version
  27. a^=b;
  28. b^=a;
  29. a^=b;
  30.  
  31. trace(a, b);
  32.  
  33. // one line xor version
  34.  
  35. a=(b=(a=b^a)^b)^a;
  36.  
  37. trace(a, b);
  38.  
  39. /* outputs:
  40. 1.1 2.2
  41. 2.2 1.1
  42. 1.1 2.2
  43.  
  44. xor kills decimals:
  45. 2 1
  46. 1 2
  47. */

The above swaps variables a and b in a few different ways. The first way (using a temp variable) is the best and fastest way... the rest of the ways are just interesting and fun.

I was coding and something reminded me that there are obscure variable swapping techniques out there... so I figured I'd google for a bit.... there are tons of examples of these online - with lots of good explanations.... I got the above from this link.

Posted in Operators, one-liners, variables | Also tagged | Leave a comment

Animate Along Bezier Curve

Actionscript:
  1. var circle:Shape = Shape(addChild(new Shape));
  2. with(circle.graphics) beginFill(0x000000), drawCircle(0,0,5);
  3.  
  4. var bezierPoint:Point = new Point();
  5. function bezier(a:Number, x1:Number, y1:Number, x2:Number, y2:Number, x3:Number, y3:Number):void {
  6.         var b:Number =1-a;
  7.         var pre1:Number=a*a;
  8.         var pre2:Number=2*a*b;
  9.         var pre3:Number=b*b;
  10.         bezierPoint.x = pre1*x1 + pre2*x2  + pre3*x3;
  11.         bezierPoint.y = pre1*y1 + pre2*y2 + pre3*y3;
  12. }
  13.  
  14. var inc:Number = 0;
  15. var theta:Number = 0;
  16.  
  17. addEventListener(Event.ENTER_FRAME, onLoop);
  18. function onLoop(evt:Event):void {
  19.    
  20.      graphics.clear();
  21.      graphics.lineStyle(0,0xFF0000);
  22.      graphics.moveTo(200,200);
  23.      graphics.curveTo(mouseX, mouseY, 400, 200);
  24.  
  25.     theta+= .05;
  26.     inc = .5 + .5*Math.sin(theta);
  27.  
  28.     bezier(inc, 200, 200, mouseX, mouseY, 400, 200);
  29.     circle.x = bezierPoint.x;
  30.     circle.y = bezierPoint.y;
  31. }

The above animates a circle along a quadratic bezier curve. This snippet was written in response to a question spurned by some of the recent bezier posts. I used Math.sin() to animate the circle but you could just as easily use modulus... simply replace lines 25-26 with the following:

Actionscript:
  1. inc += .03;
  2. inc %= 1;

Posted in Graphics, bezier, graphics algorithms, motion | Also tagged | 3 Comments

Seamless Tiles

Actionscript:
  1. [SWF(width=600, height=500, backgroundColor=0xFFFFFF, frameRate=30)]
  2.  
  3. function seamlessTile(img:BitmapData, featherSize:Number = 5):BitmapData{
  4.     var pnt:Point = new Point(0,0);
  5.     var tile:BitmapData = new BitmapData(img.width, img.height, true, 0xFF000000);
  6.     tile.copyPixels(img, img.rect, pnt, null, null, true);
  7.    
  8.     var flipped:BitmapData = new BitmapData(img.width, img.height, true, 0xFF000000);
  9.     var m:Matrix = new Matrix();
  10.     m.scale(-1, 1);
  11.     m.translate(tile.width,0);
  12.     flipped.draw(tile, m);
  13.    
  14.     var aChannel:BitmapData = new BitmapData(img.width, img.height, true, 0x00000000);
  15.     var grad:Sprite = new Sprite();
  16.     m.createGradientBox(img.width, img.height, 0, 0, 0);
  17.    
  18.     grad.graphics.beginGradientFill(GradientType.LINEAR, [0xFFFFFF, 0xFFFFFF],  [1, 0], [0, (255 / img.width) * img.width / featherSize], m, SpreadMethod.PAD);
  19.    
  20.     grad.graphics.drawRect(0,0,img.width, img.height);
  21.     aChannel.draw(grad);
  22.  
  23.     tile.copyPixels(flipped, flipped.rect, pnt, aChannel, pnt, true);
  24.    
  25.     m.identity();
  26.     m.scale(1, -1);
  27.     m.translate(0,tile.height);
  28.     flipped.draw(tile, m)
  29.    
  30.     aChannel.fillRect(aChannel.rect, 0x00000000);
  31.     m.createGradientBox(img.width, img.height, Math.PI / 2, 0, 0);
  32.     grad.graphics.clear();
  33.     grad.graphics.beginGradientFill(GradientType.LINEAR, [0xFFFFFF, 0xFFFFFF], [1, 0], [0, (255 / img.height) * img.height / featherSize],  m, SpreadMethod.PAD);
  34.    
  35.     grad.graphics.drawRect(0,0,img.width, img.height);
  36.     aChannel.draw(grad, grad.transform.matrix);
  37.    
  38.     tile.copyPixels(flipped, flipped.rect, pnt, aChannel, pnt, true);
  39.     return tile;
  40. }
  41.  
  42. // test out the function:
  43. var canvas:BitmapData = new BitmapData(600, 470, true, 0xFF000000);
  44. addChild(new Bitmap(canvas));
  45.  
  46. var image:Loader = new Loader();
  47. image.load(new URLRequest("http://actionsnippet.com/imgs/paper.jpg"));
  48. image.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoaded);
  49. var texture:BitmapData;
  50.  
  51. function onLoaded(evt:Event):void {
  52.     texture =  Bitmap(image.content).bitmapData;
  53.     addEventListener(Event.ENTER_FRAME, onLoop);
  54.     image.removeEventListener(Event.COMPLETE, onLoaded);
  55. }
  56.  
  57. function onLoop(evt:Event):void{
  58.     var tile:BitmapData = seamlessTile(texture, Math.max(1,mouseX/30));
  59.     var p:Point = new Point();
  60.     for (var i:int = 0; i<8; i++){
  61.         p.x = (i % 4) * tile.width;
  62.         p.y = int(i / 4) * tile.height;
  63.         canvas.copyPixels(tile, tile.rect, p);
  64.     }
  65. }

The above demos a function called seamlessTile() which takes a BitmapData object and uses an oldschool seamless tile technique on it.

The result is that you can have an image that would normally tile like this:


end up looking like this:



You can take a look at the swf here.

I learned how seamless tiles worked by observing the KPT seamless welder filter while I was in highschool. I wish I could dig up all that old KPT stuff again....

There are better seamless tile algorithms out there.... this one is very primitive, but it will work nicely if used properly. Could work well with a composite texture in Papervision 3D for instance...

Posted in BitmapData, graphics algorithms, pixel manipulation | Also tagged | 5 Comments

Glitch Auto-asteroids

Actionscript:
  1. [SWF(width=600, height=400, backgroundColor=0x000000, frameRate=30)]
  2. // make some ships
  3. for (var i:int = 0; i<10; i++) makeShip();
  4. //
  5. function makeShip():void {
  6.     // setup vars
  7.     var char:Object ={posX:Math.random()*stage.stageWidth, posY:Math.random()*stage.stageHeight, velX:0, velY:0, rad:4, theta:Math.random()*6.28, thetaDest:Math.random()*6.28, mc: MovieClip(addChild(new MovieClip()))}
  8.     // draw and position the char
  9.     with(char.mc) graphics.lineStyle(0,0xFFFFFF), graphics.moveTo(-15, -5), graphics.lineTo(0, 0), graphics.lineTo(-15, 5), x=char.posX, y=char.posY;
  10.     // loop
  11.     addEventListener(Event.ENTER_FRAME, function(){
  12.         // change position based on velocity, .9 friction
  13.         with (char) posX += velX *= .9, posY += velY *= .9;
  14.         // randomize radius and theta
  15.         if (int(Math.random()*10) == 1) char.thetaDest += Math.random()*2-1;
  16.         if (int(Math.random()*90) == 1) char.rad = Math.random()*4 + 4
  17.         // apply changes to velocity
  18.         char.theta += (char.thetaDest - char.theta) / 12;
  19.         char.velX = char.rad * Math.cos(char.theta);
  20.         char.velY = char.rad * Math.sin(char.theta);
  21.         // screen bounds
  22.         if (char.posX> 620) char.posX = -20;
  23.         if (char.posX <-20) char.posX = 620;
  24.         if (char.posY> 420) char.posY = -20;
  25.         if (char.posY <-20) char.posY = 420;
  26.         // rotation
  27.         char.mc.rotation = (Math.abs(char.mc.y - char.posY)>.7 || Math.abs(char.mc.x - char.posX)> .7) ?  Math.atan2(char.posY - char.mc.y,char.posX -  char.mc.x) / Math.PI * 180 : char.mc.rotation;
  28.         // shoot
  29.         if(int(Math.random()*100) <20) shootBullet(char, 5 * Math.cos(char.mc.rotation * Math.PI / 180)+ char.velX, 5 * Math.sin(char.mc.rotation * Math.PI / 180) + char.velY);
  30.         // apply position
  31.         with(char) mc.x = posX, mc.y = posY;
  32.         });
  33. }
  34. //
  35. function shootBullet(char:Object, vx:Number, vy:Number):void{
  36.     var b:MovieClip = MovieClip(addChild(new MovieClip()));
  37.     b.life = 0;
  38.     with(b) graphics.beginFill(0xFFFFFF), graphics.drawCircle(0,0,2), x = char.mc.x, y = char.mc.y;
  39.     b.addEventListener(Event.ENTER_FRAME, function(){
  40.             with (b) x += vx, y += vy, life++;
  41.             if (b.life> 30) b.removeEventListener(Event.ENTER_FRAME, arguments.callee), removeChild(b);
  42.     });
  43. }

An asteroids inspired code snippet. See the swf here.

Posted in misc, motion | Also tagged | Leave a comment