Tag Archives: actionscript

Jumping on a 2D Circle

Actionscript:
  1. var circle:Shape = Shape(addChild(new Shape()));
  2. with(circle.graphics) beginFill(0xCCCCCC), drawCircle(0,0,100);
  3. circle.x = stage.stageWidth / 2;
  4. circle.y = stage.stageHeight / 2;
  5.  
  6. var charWorld:MovieClip = MovieClip(addChild(new MovieClip()));
  7. charWorld.x = circle.x ;
  8. charWorld.y = circle.y - 100 - 10
  9. charWorld.thetaSpeed = 0;
  10. charWorld.theta  = -Math.PI / 2;
  11.  
  12. var char:MovieClip = MovieClip(charWorld.addChild(new MovieClip))
  13. with(char.graphics) beginFill(0x000000), drawRect(-10,-10,10,10);
  14. char.posY = 0;
  15. char.velY = 0;
  16.  
  17. addEventListener(Event.ENTER_FRAME, onRunChar);
  18. function onRunChar(evt:Event):void {
  19.    
  20.     char.velY += 1;
  21.     char.posY += char.velY;
  22.    
  23.     charWorld.thetaSpeed *= .6;
  24.     charWorld.theta += charWorld.thetaSpeed;
  25.    
  26.     if (key[Keyboard.UP]){
  27.         if (char.y == 0){
  28.           char.velY = -10;
  29.         }
  30.     }
  31.    
  32.     if (key[Keyboard.RIGHT]){
  33.         charWorld.thetaSpeed = .1;
  34.     }
  35.    
  36.     if (key[Keyboard.LEFT]){
  37.         charWorld.thetaSpeed = -.1;
  38.     }
  39.    
  40.     if (char.posY> 0){
  41.         char.posY = 0;
  42.     }
  43.    
  44.     char.y = char.posY;
  45.    
  46.     charWorld.x = circle.x + 100 * Math.cos(charWorld.theta);
  47.     charWorld.y = circle.y + 100 * Math.sin(charWorld.theta);
  48.     charWorld.rotation = Math.atan2(circle.y- charWorld.y, circle.x - charWorld.x) / Math.PI * 180 - 90;
  49. }
  50.  
  51. var key:Object = new Object();
  52. stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyPressed);
  53. stage.addEventListener(KeyboardEvent.KEY_UP, onKeyReleased);
  54. function onKeyPressed(evt:KeyboardEvent):void {
  55.     key[evt.keyCode] = true;
  56.     key.keyCode = evt.keyCode;
  57. }
  58.  
  59. function onKeyReleased(evt:KeyboardEvent):void {
  60.     key[evt.keyCode] = false
  61. }

For some reason I felt like posting the swf.... have a look here.

This is one that's been kicking around in my head for awhile - finally got around to writing it. It creates a circle and a small black box. The box walks and jumps on the circle with key input (left arrow, right arrow and up arrow).

There's an odd trick going on here. Basically, the box (or char) movieClip is nested inside another clip. Within this clip (charWorld) the box moves on the y axis (jumping/up key). The charWorld clip orbits around the circle and rotates toward the center of the circle - sine/cosine are used for the orbit so the left and the right keys control the speed of theta.

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

Bezier Skin (smooth curveTo())

Actionscript:
  1. // graphics, vector of xy coords, closed boolean
  2. function bezierSkin(g:Graphics, bez:Vector.<Number>, closed:Boolean = true):void {
  3.     var avg:Vector.<Number> = calcAvgs(bez);
  4.     var i:int, n:int;
  5.     var leng:int = bez.length;
  6.  
  7.     if (closed){
  8.         g.moveTo(avg[0], avg[1]);
  9.         for (i = 2; i <leng; i+=2) {
  10.             n=i+1;
  11.             g.curveTo(bez[i], bez[n], avg[i], avg[n]);
  12.         }
  13.         g.curveTo(bez[0], bez[1], avg[0], avg[1]);
  14.     }else{
  15.         g.moveTo(bez[0], bez[1]);
  16.         g.lineTo(avg[0], avg[1]);
  17.         for (i = 2; i <leng-2; i+=2) {
  18.             n=i+1;
  19.             g.curveTo(bez[i], bez[n], avg[i], avg[n]);
  20.         }
  21.         g.lineTo(bez[ leng - 2], bez[ leng - 1]);
  22.     }
  23. }
  24.  
  25. // create anchor points by averaging the control points
  26. function calcAvgs(v:Vector.<Number>):Vector.<Number> {
  27.     var avg:Vector.<Number> = new Vector.<Number>();
  28.     var leng:int=v.length;
  29.     for (var i:int = 2; i<leng; i+=1) {
  30.         var prev:Number=i-2;
  31.         avg.push( (v[prev] + v[i]) / 2 );
  32.     }
  33.     // close
  34.     avg.push( (v[0] + v[ leng - 2]) / 2 );
  35.     avg.push( (v[1] + v[ leng - 1]) / 2 );
  36.     return avg;
  37. }
  38.  
  39. // test out the functions:
  40.  
  41. graphics.lineStyle(0,0x000000);
  42.  
  43. // draw a very rounded rect
  44. bezierSkin(graphics, Vector.<Number>([100,100,200,100,200,200,100,200]) );
  45.  
  46. // draw a random curve with 10 xy coords
  47. var rnd:Vector.<Number> = new Vector.<Number>();
  48. for (var i:int = 0; i<20; i++) rnd.push(Math.random()*100);
  49. bezierSkin(graphics, rnd);
  50.                        
  51. // erase everything and allow the used to draw a smooth curve with the mouse
  52. stage.addEventListener(MouseEvent.MOUSE_DOWN, onLoop);
  53. var index:int = 0;
  54. var pnts:Vector.<Number> = new Vector.<Number>();
  55.  
  56. function onLoop(evt:MouseEvent):void {
  57.      pnts.push(mouseX);
  58.      pnts.push(mouseY);
  59.    
  60.      graphics.clear();
  61.      graphics.lineStyle(0,0x000000);
  62.      
  63.       // draw a smooth curved line
  64.      bezierSkin(graphics,pnts,false);
  65. }

The above code uses averaging to generate anchor points for curveTo() calls. This is an easy way to always draw smooth curves.

This is an old one that I've seen floating around since the drawing api first came out... but I it's an important snippet, so I figured I'd post it.

Posted in Graphics, bezier | Also tagged , | Leave a comment

Quadratic Bezier

Actionscript:
  1. var canvas:BitmapData=new BitmapData(280,280,false,0x000000);
  2. addChild(new Bitmap(canvas, PixelSnapping.AUTO, true));
  3. var color:uint;
  4. // anchor x1, anchor y1,
  5. // control-handle x2, control-handle y2,
  6. // anchor x3, anchor y3, [resolution incremental value between 0-1]
  7. function quadBezier(x1:Number, y1:Number, x2:Number, y2:Number, x3:Number, y3:Number, resolution:Number=.03):void {
  8.     var b:Number,pre1:Number,pre2:Number,pre3:Number,pre4:Number;
  9.     for (var a:Number = 0; a <1;a+=resolution) {
  10.    
  11.         b=1-a;
  12.         pre1=(a*a);
  13.         pre2=2*a*b;
  14.         pre3=(b*b);
  15.        
  16.         canvas.setPixel(pre1*x1 + pre2*x2  + pre3*x3 ,
  17.                                      pre1*y1 + pre2*y2 + pre3*y3, color);
  18.     }
  19. }
  20.  
  21. // draw a few
  22. color = 0xFFFFFF;
  23.  
  24. for (var i:int = 0; i<20; i++){
  25. quadBezier(40,100, 150 , 20 + i * 10 , 200, 100,.01);
  26. }
  27.  
  28. color = 0xFF0000;
  29.  
  30. for (i= 0; i<20; i++){
  31. quadBezier(150,200, 100 + i * 10, 100  , 120, 30,.01);
  32. }

The above demos a function that draws quadratic bezier curves using setPixel().

One of the first posts on this site was a snippet that used setPixel() to draw a cubic bezier curve. I recently needed to do the exact same thing but I wanted to use a quadratic bezier... I knew I had the code laying around somewhere, but I couldn't seem to find it so I just looked on wikipedia and changed the previous cubicBezier() function accordingly.

Posted in BitmapData, bezier, graphics algorithms, pixel manipulation, setPixel | Also tagged , | 2 Comments

Bresenham Circle Filled

Actionscript:
  1. var canvas:BitmapData = new BitmapData(400, 400, false, 0xCCCCCC);
  2. addChild(new Bitmap(canvas));
  3.  
  4. fillCircle(100,100,50,0xFF0000);
  5.  
  6. function fillCircle(xp:Number,yp:Number, radius:Number, col:uint = 0x000000):void {
  7.     var xoff:int =0;
  8.     var yoff:int = radius;
  9.     var balance:int = -radius;
  10.  
  11.     while (xoff <= yoff) {
  12.          var p0:int = xp - xoff;
  13.          var p1:int = xp - yoff;
  14.          
  15.          var w0:int = xoff + xoff;
  16.          var w1:int = yoff + yoff;
  17.          
  18.          hLine(p0, yp + yoff, w0, col);
  19.          hLine(p0, yp - yoff, w0, col);
  20.          
  21.          hLine(p1, yp + xoff, w1, col);
  22.          hLine(p1, yp - xoff, w1, col);
  23.        
  24.         if ((balance += xoff++ + xoff)>= 0) {
  25.             balance-=--yoff+yoff;
  26.         }
  27.     }
  28. }
  29.  
  30. function hLine(xp:Number, yp:Number, w:Number, col:uint):void {
  31.     for (var i:int = 0; i <w; i++){
  32.         canvas.setPixel(xp + i, yp, col);
  33.     }
  34. }

An implementation of yesterdays post that draws a filled circle instead of an outlined circle.

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