Category Archives: motion

Nonsense Clocks

Actionscript:
  1. [SWF(width = 500, height=500, backgroundColor=0x000000)]
  2.  
  3. var clockNum:int = 100;
  4. var clocks:Vector.<Function> = new Vector.<Function>(clockNum, true);
  5.  
  6. var clockContainer:Sprite = Sprite(addChild(new Sprite()));
  7. clockContainer.x = stage.stageWidth / 2;
  8. clockContainer.y = stage.stageHeight / 2;
  9. buildClocks();
  10. runClocks();
  11.  
  12. function buildClocks():void{
  13.     for (var i:int = 0; i<clockNum; i++){
  14.         var theta:Number = Math.random() * Math.PI * 2;
  15.         var radius:Number = Math.random() * 200;
  16.         var xp:Number = radius * Math.cos(theta);
  17.         var yp:Number = radius * Math.sin(theta);
  18.         clocks[i] = makeClock(xp,yp,Math.random() * Math.PI * 2);
  19.     }
  20. }
  21. function runClocks():void{
  22.     addEventListener(Event.ENTER_FRAME, onRunClocks);
  23. }
  24. function onRunClocks(evt:Event):void{
  25.     for (var i:int = 0; i<clockNum; i++){
  26.         clocks[i]();
  27.     }
  28.     clockContainer.rotationX = clockContainer.mouseY / 30;
  29.     clockContainer.rotationY = -clockContainer.mouseX / 30;
  30. }
  31. function makeClock(x:Number, y:Number, time:Number=0):Function{
  32.     var radius:Number = Math.random() * 20 + 5;
  33.     var border:Number = radius * 0.2;
  34.     var smallRadius:Number = radius - radius * 0.3;
  35.    
  36.     var clock:Sprite = Sprite(clockContainer.addChild(new Sprite()));
  37.     clock.x = x;
  38.     clock.y = y;
  39.     clock.z = 100 - Math.random() * 200;
  40.     clock.rotationX = Math.random() * 40 - 20;
  41.     clock.rotationY = Math.random() * 40 - 20;
  42.     clock.rotationZ = Math.random() * 360;
  43.     return function():void{
  44.         with (clock.graphics){
  45.             clear();
  46.             lineStyle(1,0xFFFFFF);
  47.             drawCircle(0,0,radius + border);
  48.             var xp:Number = smallRadius * Math.cos(time/2);
  49.             var yp:Number = smallRadius * Math.sin(time/2);
  50.             moveTo(0,0);
  51.             lineTo(xp, yp);
  52.             xp = radius * Math.cos(time);
  53.             yp = radius * Math.sin(time);
  54.             moveTo(0,0);
  55.             lineTo(xp, yp);
  56.         }
  57.         time+=0.1;
  58.     }
  59. }


You can go check the swf out at wonderfl.net...

Also posted in 3D, Graphics, misc | Tagged , , | 3 Comments

Rotation Property Weirdness

Actionscript:
  1. var boxA:Shape = Shape(addChild(new Shape()));
  2. with (boxA.graphics) beginFill(0), drawRect(-10,-10,20,20);
  3.  
  4. var boxB:Shape = Shape(addChild(new Shape()));
  5. with (boxB.graphics) beginFill(0), drawRect(-10,-10,20,20);
  6.  
  7. boxA.x = 100;
  8. boxA.y = 100;
  9.  
  10. boxB.x = 200;
  11. boxB.y = 100;
  12.  
  13. var rot:Number = 32750;
  14.  
  15. addEventListener(Event.ENTER_FRAME, onLoop);
  16. function onLoop(evt:Event):void {
  17.   rot += 1
  18.   // will stop rotating
  19.   boxA.rotation = rot
  20.   // will keep rotating
  21.   boxB.rotation = rot % 360;
  22. }

I recently became aware of a strange aspect of the rotation property on DisplayObjects. For some reason, once it's value goes a little beyond ~32750 the DisplayObject will simply stop rotating. If you read the rotation property it is still changing, but there is no visual update - a quick check on the DisplayObject.transform.matrix property will show that the value has stopped.

The easy fix is to use mod before applying the value to the rotation property. Surprised I've never come across this one before. Maybe someone can shed some light on this.


// for people searching google for solutions to this problem I'll add the following key words:
MovieClip stops rotating, DisplayObject stops rotating, rotation property broken, not rotating

Also posted in DisplayObject, misc | Tagged , , | 1 Comment

Fp10 3d Logo

Actionscript:
  1. var container:Sprite = new Sprite();
  2. container.x = stage.stageWidth / 2;
  3. container.y = stage.stageHeight / 2;
  4. addChild(container);
  5.  
  6. var redBox:Sprite = new Sprite();
  7. redBox.graphics.beginFill(0xFF0000);
  8. redBox.graphics.drawRect(-50,-250,100,500);
  9. redBox.rotationZ = 10;
  10. container.addChild(redBox);
  11.  
  12. var logos:Array = []
  13. var elements:Array = [];
  14. elements.push({element:redBox, z:0});
  15.  
  16. // add the logos
  17. for (var i:int = 0; i<6; i++){
  18.     var logoContainer:MovieClip = new MovieClip();
  19.     var logoText:TextField = new TextField();
  20.     logoText.defaultTextFormat = new TextFormat("_sans", 50);
  21.     logoText.text = "LOGO";
  22.     logoText.autoSize = "left";
  23.     logoText.selectable= false;
  24.    
  25.     logoText.x = -logoText.width / 2;
  26.     logoText.y = -logoText.height / 2;
  27.     logoContainer.addChild(logoText);
  28.     logoText.backgroundColor = 0xFFFFFF;
  29.    
  30.     container.addChild(logoContainer);
  31.     logos.push(logoContainer);
  32.     elements.push({element:logoContainer, z:0});
  33. }
  34.  
  35. var ang:Number = -Math.PI / 2;
  36. var rotationSpeed:Number = 0.05;
  37. addEventListener(Event.ENTER_FRAME, onLoop);
  38. function onLoop(evt:Event):void {
  39.    
  40.      var dx:Number = (mouseY - stage.stageHeight / 2) / 10;
  41.      var dy:Number = (mouseX - stage.stageWidth / 2) / 10;
  42.      container.rotationX += (dx - container.rotationX) / 4;
  43.      container.rotationY += (dy - container.rotationY) / 4;
  44.      
  45.      ang += rotationSpeed;
  46.      for (var i:int = 0; i<logos.length; i++){
  47.          var logo:Sprite = logos[i];
  48.          logo.x = 150 * Math.cos(ang + i);
  49.          logo.z = 150 * Math.sin(ang + i);
  50.          logo.alpha = 1 - logo.z / 200;
  51.          logo.rotationY = -Math.atan2(logo.z, logo.x)  / Math.PI * 180  - 90;
  52.      }
  53.      
  54.      // z-sort
  55.      for (i = 0; i<elements.length; i++){
  56.           elements[i].z = elements[i].element.transform.getRelativeMatrix3D(this).position.z;
  57.      }
  58.      
  59.     elements.sortOn("z", Array.NUMERIC | Array.DESCENDING);
  60.     for (i = 0; i<elements.length; i++) {
  61.         container.addChild(elements[i].element);
  62.     }
  63. }

A student of mine was having trouble creating a 3D logo for a client. I created this snippet to help explain how some of the fp10 3D stuff works.... z-sorting etc... The code could be optimized a bit... but it works nicely...


Have a look at the swf...

Also posted in 3D, misc | Tagged , , , | 2 Comments

Bounce Ball Inside a Circle

Actionscript:
  1. package  {
  2.     import flash.display.Shape;
  3.     import flash.display.Sprite;
  4.     import flash.geom.Point;
  5.  
  6.     /**
  7.      * Re: http://board.flashkit.com/board/showthread.php?t=797453
  8.      * @author makc
  9.      * @license WTFPLv2
  10.      */
  11.     public class BouncingBall extends Sprite{
  12.         public function BouncingBall () {
  13.             r = 10;
  14.             ball = new Shape;
  15.             ball.graphics.beginFill (0);
  16.             ball.graphics.drawCircle (0, 0, r);
  17.             addChild (ball);
  18.             v = new Point;
  19.             v.x = Math.random ();
  20.             v.y = Math.random ();
  21.             V = 1 + 20 * Math.random ();
  22.             v.normalize (V);
  23.             R = 200; X = 465 / 2; Y = 465 / 2;
  24.             graphics.lineStyle (0);
  25.             graphics.drawCircle (X, Y, R);
  26.             ball.x = X + 100;
  27.             ball.y = Y - 100;
  28.             addEventListener ("enterFrame", loop);
  29.         }
  30.         private var r:Number;
  31.         private var ball:Shape;
  32.         private var v:Point;
  33.         private var V:Number;
  34.         private var R:Number;
  35.         private var X:Number;
  36.         private var Y:Number;
  37.         private function loop (e:*):void {
  38.             ball.x += v.x;
  39.             ball.y += v.y;
  40.             // R-r vector
  41.             var P:Point = new Point (X - ball.x, Y - ball.y);
  42.             if (P.length> Math.sqrt ((R - r) * (R - r))) {
  43.                 // normalize R-r vector
  44.                 P.normalize (1);
  45.                 // project v onto it
  46.                 var vp:Number = v.x * P.x + v.y * P.y;
  47.                 // subtract projection
  48.                 v.x -= 2 * vp * P.x;
  49.                 v.y -= 2 * vp * P.y;
  50.                 v.normalize (V);
  51.                 // move away from bounding circle
  52.                 P = new Point (X - ball.x, Y - ball.y);
  53.                 while (P.length> Math.sqrt ((R - r) * (R - r))) {
  54.                     ball.x += v.x;
  55.                     ball.y += v.y;
  56.                     P = new Point (X - ball.x, Y - ball.y);
  57.                 }
  58.             }
  59.         }
  60.     }
  61. }

Makc3d said I could choose one of his excellent wonderfl.net pieces and submit it to the contest. This snippet creates a ball that bounces off the inside of a circle. I thought this was a pretty unique way to go about doing this - and found it easy to add gravity and other cool features to it.

Have a look at the swf over at wonderfl....

Some Makc3d links:
>> http://makc3d.wordpress.com/
>>http://code.google.com/p/makc/
>> http://wonderfl.net/user/makc3d

Makc3d elaborated on his code a bit via e-mail. He said that his technique sacrifices accuracy for simplicity... and that if you simplify too much it would be easy to break the code. "e.g. comment out piece of code where it says "move away from bounding circle""...

Here is a picture that Makc3d drew explaining why you need to multiply by 2:

Posted in motion | Tagged , , , | Comments closed