Tag Archives: actionsnippet

Slider Navigation

Actionscript:
  1. var thumbNum:Number = 20;
  2. var spacing:Number = 10;
  3. var thumbs:MovieClip = new MovieClip();
  4. addChild(thumbs);
  5. for (var i:int = 0; i<thumbNum; i++){
  6.     var t:MovieClip = new MovieClip();
  7.     with(t.graphics) beginFill(0x666666), drawRect(0,0,100,50);
  8.     t.x = i * (t.width + spacing);
  9.     t.y = 5;
  10.     t.buttonMode = true;
  11.     thumbs.addChild(t);
  12. }
  13. var minX:Number = stage.stageWidth - thumbs.width - spacing;
  14. var destX:Number = thumbs.x = spacing;
  15. var velX:Number = 10;
  16. var stageThird:Number =  stage.stageWidth / 3;
  17. var right:Number = stageThird * 2;
  18. var left:Number  = stageThird;
  19. addEventListener(Event.ENTER_FRAME, onLoop);
  20. function onLoop(evt:Event):void {
  21.     if (mouseX> right){
  22.        destX -= velX;
  23.     }
  24.     if (mouseX <left){
  25.         destX += velX;
  26.     }
  27.     if (destX <minX){
  28.         destX = minX;
  29.     }
  30.     if (destX> spacing){
  31.         destX = spacing;
  32.     }
  33.     thumbs.x += (destX - thumbs.x) /4;
  34. }

This snippet shows a technique for a common type of navigation.

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

Slow Line Drawing

Actionscript:
  1. var canvas:BitmapData = Bitmap(addChild(new Bitmap(new BitmapData(400, 400, false, 0x000000)))).bitmapData;
  2.  
  3. function line(x1:Number, y1:Number, x2:Number, y2:Number, res:int=10):void{
  4.     var dx:Number = x2 - x1;
  5.     var dy:Number = y2 - y1;
  6.     var dist:Number = Math.sqrt((dx * dx) + (dy * dy));
  7.     var step:Number = 1 / (dist / res);
  8.     for (var i:Number = 0; i<=1; i+= step){
  9.         // lerp : a  + (b - a) * f
  10.         canvas.setPixel(x1 + dx * i, y1 + dy * i, 0xFFFFFF);
  11.     }
  12. }
  13.  
  14. addEventListener(Event.ENTER_FRAME, onLoop);
  15. function onLoop(evt:Event):void {
  16.    canvas.fillRect(canvas.rect, 0x000000);
  17.   line(100 , 100, mouseX, mouseY,1);
  18.   line(100 + 50, 100, mouseX+ 50, mouseY,5);
  19. }

Yesterday I posted an implementation of the Bresenham Line Algorithm. Today I'm posting a comparatively slow way to draw a line with setPixel(). This snippet uses lerp and the Pythagorean theorem. It works nicely for small numbers of lines, its easy to draw dotted lines with it and its easy to explain. In a real app where you needed to use setPixel() to draw a line you should use one of the fast algorithms like Wu or Bresenham.

I didn't originally write this snippet to use set pixel... a few weeks ago I wrote something very similar to calculate a set of x y coords between two given points. In the program I used it in speed wasn't an issue (as I only needed to run the function one time). I've needed this kind of function many times before in games and small apps...

This was the original:

Actionscript:
  1. function calculatePoints(x1:Number, y1:Number, x2:Number, y2:Number, res:int=10):Array{
  2.     var points:Array = new Array();
  3.     var dx:Number = x2 - x1;
  4.     var dy:Number = y2 - y1;
  5.     var dist:Number = Math.sqrt((dx * dx) + (dy * dy));
  6.     var step:Number = 1 / (dist / res);
  7.     for (var i:Number = 0; i<=1; i+= step){
  8.         points.push(new Point(x1 + dx * i, y1 + dy * i));
  9.     }
  10.     return points;
  11. }
  12.  
  13. trace(calculatePoints(0,0,100,0,10));
  14. /* outputs:
  15. (x=0, y=0),(x=10, y=0),(x=20, y=0),(x=30.000000000000004, y=0),(x=40, y=0),(x=50, y=0),(x=60, y=0),(x=70, y=0),(x=80, y=0),(x=89.99999999999999, y=0),(x=99.99999999999999, y=0)
  16. */

...and another version to allow you to specify the number of points to calculate rather than the pixel interval at which they should be calculated:

Actionscript:
  1. function calculatePoints(x1:Number, y1:Number, x2:Number, y2:Number, pointNum:int=10):Array{
  2.     var points:Array = new Array();
  3.     var step:Number = 1 / (pointNum + 1);
  4.     for (var i:Number = 0; i<=1; i+= step){
  5.         points.push(new Point(x1 + (x2 - x1) * i, y1 + (y2 - y1) * i));
  6.     }
  7.     return points;
  8. }
  9.  
  10. trace(calculatePoints(0,30,30,0,1));
  11. /* outputs:
  12. (x=0, y=30),(x=15, y=15),(x=30, y=0)
  13. */

This last version isn't perfect, sometimes the pointNum will be off by 1, I may fix that in a future post.

Posted in Math, graphics algorithms, misc, pixel manipulation, setPixel | Also tagged | Leave a comment

Transparent copyPixels()

Actionscript:
  1. var canvas:BitmapData=new BitmapData(400,400,true,0x000000);
  2. var eraser:BitmapData=new BitmapData(400,400,true,0x00000000);
  3. addChild(new Bitmap(canvas));
  4. var redOval:Shape = new Shape();
  5. with(redOval.graphics) lineStyle(0,0), beginFill(0xFF0000), drawEllipse(0,0,10,50);
  6.  
  7. // draw a background to emphasize transparency
  8. createBackground();
  9.  
  10. addEventListener(Event.ENTER_FRAME, onLoop);
  11.  
  12. function onLoop(evt:Event):void {
  13.     // clear canvas so that it is completely transparent
  14.     canvas.copyPixels(eraser, eraser.rect, new Point(0,0), eraser);
  15.     redOval.x = mouseX;
  16.     redOval.y = mouseY;
  17.     redOval.rotation += 10
  18.     // transform.matrix contains all transformation information for
  19.     // the redOval including scaleX, scaleY, x, y, rotation etc...
  20.     canvas.draw(redOval, redOval.transform.matrix);
  21. }
  22.  
  23. function createBackground():void {
  24.     for (var i:int = 0; i<100; i++){
  25.         with(graphics) lineStyle(0,0x000000), lineTo(Math.random()*400, Math.random()*400);
  26.     }
  27. }

This example builds on yesterdays snippet. Instead of just allowing the red oval to be continuously drawn to the canvas BitmapData... in this example the canvas BitmapData is erased again and again before the red oval is drawn to it. To erase it with a flat color you might use BitmapData.fillRect() but if you want to erase it so that it is completely transparent you need to use BitmapData.copyPixels():

Actionscript:
  1. canvas.copyPixels(eraser, eraser.rect, new Point(0,0), eraser);

The eraser BitmapData is a completely transparent BitmapData object. The key here is the fourth argument.... "alphaBitmapData".This is what causes the canvas BitmapData to become completely transparent again at the beginning of each enterFrame.

This argument is separate from the first argument (sourceBitmapData) for added flexibility.

Posted in BitmapData, pixel manipulation | Also tagged | 2 Comments

Procedural Pattern - Navigation

Actionscript:
  1. var currentBtn:MovieClip;
  2.  
  3. var nav:Sprite = new Sprite();
  4. nav.x = nav.y = 20;
  5. addChild(nav);
  6.  
  7. createBtns();
  8.  
  9. nav.addEventListener(MouseEvent.CLICK, onClickBtn);
  10.  
  11. function createBtns():void{
  12.     for (var i:int = 0; i<10; i++){
  13.         var btn:MovieClip = new MovieClip();
  14.         with(btn.graphics) beginFill(0x666666), drawRect(-10,-10,20,20);
  15.         btn.x = i * (btn.width + 10);
  16.         btn.buttonMode = true;
  17.         btn.num = i;
  18.         btn.alpha = .5;
  19.         nav.addChild(btn);
  20.     }
  21. }
  22.  
  23. function onClickBtn(evt:MouseEvent):void {
  24.     //
  25.     // this is the important part
  26.     //
  27.     if (currentBtn){
  28.         currentBtn.scaleX = currentBtn.scaleY = 1;
  29.         currentBtn.alpha = .5;
  30.     }
  31.     currentBtn = MovieClip(evt.target);
  32.     currentBtn.scaleX = currentBtn.scaleY = 1.3;
  33.     currentBtn.alpha = 1;
  34.     trace("current button:", currentBtn.num);
  35.     //
  36. }

This code will create 10 boxes that represent buttons on a navigation. When you click a box it indicates that it is selected by scaling up and changing alpha. Simple enough...

The term Procedural Pattern is just a spin on the idea of Design Patterns. I've come up with lots of small patterns to solve simple recurring problems over the years. Most of these relate to things like drawing programs, ecards and games.

Posted in UI | Also tagged , | Leave a comment