Monthly Archives: November 2009

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

Google Analytics Utility

Actionscript:
  1. package com.hapticdata.utils
  2. {
  3.     import flash.external.ExternalInterface;
  4.     /**
  5.      * Simplifies posting to Google's Analytics Tracker, allows easily disabling for development phase
  6.      * and uses ExternalInterface rather than navigateToURL
  7.      * @class Urchin
  8.      * @author Kyle Phillips - <a href="http://www.haptic-data.com">http://www.haptic-data.com</a>
  9.      * @created October 28, 2008
  10.      * @example Analytics.post("section");
  11.      */
  12.    
  13.    
  14.     public class Analytics
  15.     {
  16.        
  17.         public static var enabled:Boolean = true;
  18.         //appended as a directory to all trackings
  19.         public static var swfID:String="/flashevent/";
  20.         //correct for default snippet. Change this if you have a custom-wrapped analytics method
  21.         public static var functionToCall:String = "pageTracker._trackPageview";
  22.        
  23.         /**
  24.          * Will invoke the set javascript function
  25.          * @param location:String - a string identifying where the user is in the site
  26.          */
  27.         public static function post(location:String):void
  28.         {
  29.             if(enabled && ExternalInterface.available)
  30.             {
  31.                 ExternalInterface.call(functionToCall,swfID+location);
  32.             }
  33.         }
  34.     }
  35. }

This contest entry by Kyle Phillips is a utility class for dealing with google analytics. If you haven't messed with google analytics I suggest you give it a try.

Kyle Phillips links:
>> http://workofkylephillips.com
>> http://labs.hapticdata.com

I usually find myself adding google analytics code in a very hacky way... usually because the client asks for it at the 11th hour. Using a class like Kyle's would enable you to simply add the tracking code from the start and then if the client doesn't ask for it... you can just keep the class disabled... or charge more when you offer google analytics tracking for "phase 2" of the project ;)

Posted in external data, misc | Tagged , , , , | 2 Comments

Hide Browser Scrollbars

Actionscript:
  1. /*
  2. This snippet is by Mels le Noble
  3. www.melslenoble.nl
  4. It will hide the browser scrollbars.
  5. */
  6.  
  7. // see if we are testing locally
  8. if (stage.loaderInfo.url.split("/")[2])
  9. {
  10.  ExternalInterface.call("function(){document.body.style.overflow='hidden';document.html.style.overflow = 'hidden';}");
  11. }

This snippet by Mels le Noble will hide the browser scrollbars. The bulk of the snippet is the javascript inside the ExternalInterface.call() method. I like the trick that Mels uses to check if the swf is local.... snippet-worthy in itself.

Posted in UI | Tagged , , , , | Leave a comment

QuickBox2D 1.1 (2 major bug fixes)

Since the release of QuickBox2D 1.0 two bugs were discovered by numerous developers. The first bug was the inability to properly destroy group objects. The second bug was a small memory leak that caused most QuickObjects to remain in memory. Both of these bugs are now resolved.

Download QuickBox2D 1.1

Testing the memory leak. In QuickBox2D 1.0 if you created and destroyed 100s of rigid bodies, the ram would very slowly rise... Sometimes it would get garbage collected, but the memory would never fully be released. I created a simple test to make sure this is fixed in 1.1:

Actionscript:
  1. import com.actionsnippet.qbox.*;
  2.  
  3. var sim:QuickBox2D = new QuickBox2D(this, {debug:false});
  4.  
  5. sim.createStageWalls();
  6.  
  7. var levelParts:Array = [];
  8. const TWO_PI:Number = Math.PI * 2;
  9.  
  10. // destroys and then creates a bunch of rigid bodies
  11. // called every second
  12. buildRandomLevel();
  13. setInterval(buildRandomLevel, 1000);
  14.  
  15. var txt:TextField = TextField(addChild(new TextField()));
  16. txt.x = txt.y = 30;
  17. txt.backgroundColor = 0xFFFFFF;
  18. sim.start();
  19.  
  20. // display amount of ram used, to make sure garbage collection is working
  21. sim.addEventListener(QuickBox2D.STEP, onStep);
  22. function onStep(evt:Event):void{
  23.     txt.text = (System.totalMemory / 100000).toFixed(2) + "mb";
  24. }
  25.  
  26. function buildRandomLevel():void{
  27.     // destroy all rigid bodies
  28.     for (var i:int = 0; i<levelParts.length; i++){
  29.         levelParts[i].destroy();
  30.     }
  31.     levelParts = [];
  32.     // create a bunch of circles and boxes
  33.     for (i = 0; i<16; i++){
  34.         var rad:Number = 0.4 ;
  35.         levelParts.push(sim.addCircle({x:1 + i * rad * 4, y : 2, radius:rad - Math.random()*0.3}));
  36.        
  37.         var rot:Number = Math.random() * TWO_PI;
  38.         levelParts.push(sim.addBox({x:4+Math.random() * i * 2, y:4+Math.random()*i,
  39.                     width:3, height:0.25, angle:rot, density:0}));
  40.     }
  41. }

This snippet creates and destroys a bunch of rigid bodies again and again.... On my macbook 2.6 Ghz intel core duo... the ram runs between 79mb and 112mb. I let it run for 40 minutes and this did not change - it always eventually returned down to 79mb.


Have a look at the swf...

Thanks to all the people who gave feedback that lead to the discover of these bugs.

Posted in Box2D, QuickBox2D, motion, pixel manipulation | Tagged , , , | 25 Comments