Archive for the “experiments” Category

For a special purpose I had to extend a Singleton, to make my system fully flexible. I found complicated solutions that wasn't fully working as intended.

To use PureMVC, you have to extend a Singleton (Facade), which is the entry point of the framework. This is working only if you don't use the Facade class (the super Singleton) before using the subclass, otherwise you get an error, as the super singleton has already been instantiated.

Well this might be a simple solution but not working in my case.

First of all, they are a lot of solutions to correctly "lock" a Singleton, because in AS3, private constructor doesn't exist. Some of them have turn around, that you can solve with a bit more code, but the solution I prefer is instantiate the Singleton out of the constructor and method:

Actionscript:
  1. private static var _instance:Singleton = new Singleton();

So, if I use the super singleton with a Singleton.getInstance(), and then use the subclass with a SingletonExtended.getInstance(), this will throw an error as when the SingletonExtended is called, the Singleton is called as well and has already been instantiated.

The solution I found is compare the super class name with a static class name, basically you can't use the keyword "this" when you declare a variable, but using "super" will return the same result (well that's odd but it is what I saw):

Actionscript:
  1. private static var _className:String = getQualifiedClassName(super);

And then compare it with the super classname in the Singleton constructor:

Actionscript:
  1. if (_instance != null && getQualifiedSuperclassName(this) != _className) throw new Error

if I trace(_className + " - " + getQualifiedSuperclassName(this)) in the Singleton constructor:

- when I use the Singleton class, I get: "null - Object"
- when I use the SingletonExtended class, I get: "Singleton - Singleton", meaning the constructor has been called from a subclass.

Until now, it is working pretty well, I can use:

Actionscript:
  1. Singleton.getInstance().singletonValue
  2. SingletonExtended.getInstance().singletonValue
  3. SingletonExtended.getInstance().singletonExtendedValue

But we're not completely done. We can access to our two Singleton... but wait, "two Singleton", is that possible?

In fact, it is completely possible and it is even a problem. Let's say I have a undefined value in Singleton, like:

Actionscript:
  1. private var _myValueNotInitialized:String;

And then you have a public method that is setting a value to this variable:

Actionscript:
  1. public function initializeMyValue():void {
  2.     _myValueNotInitialized = "I am initialized";
  3. }

You can now use:

Actionscript:
  1. Singleton.getInstance().initializeMyValue();
  2. or
  3. SingletonExtended.getInstance().initializeMyValue();

But here is the problem: you still have 2 instances. One in Singleton and the other in SingletonExtended. If you use:
Singleton.getInstance().initializeMyValue();
and trace:
SingletonExtended.getInstance().myValueNotInitialized
you will get null, which is normal.

This doesn't make a lot of sense for a Singleton, does it?

The solution I found is updating the Singleton instance with the SingletonExtended one.

In the Singleton, I'm now able to update the instance:

Actionscript:
  1. public function updateInstance(instance:Singleton):void {
  2.     if (instance != null && instance is Singleton) _instance = instance;
  3.     else throw new Error("Incorrect Singleton update");
  4. }

And in the subclass SingletonExtended, I change the getInstance method:

Actionscript:
  1. public static function getInstance():SingletonExtended {
  2.     Singleton.getInstance().updateInstance(_instance);
  3.     return _instance;
  4. }

This is doing the job I needed, a fully Extended Singleton with no errors accessing the super or he subclass.

I tried to break it, but if it is possible, I didn't find the hole. And if you have a better solution, I'd be very happy to see it.

You can download the source by clicking here, or see the classes below.

The main class:

Actionscript:
  1. package {
  2.    
  3.     import flash.display.Sprite;
  4.    
  5.     /**
  6.      * <b>Author:</b> Romuald Quantin - <a href="http://www.soundstep.com/" target="_blank">www.soundstep.com</a><br />
  7.      * <b>Class version:</b> 1.0<br />
  8.      * <b>Actionscript version:</b> 3.0<br />
  9.      * <b>Date:</b> 11-2008<br />
  10.      */
  11.     
  12.     public class Main extends Sprite {
  13.        
  14.         //------------------------------------
  15.         // private properties
  16.         //------------------------------------
  17.        
  18.         //------------------------------------
  19.         // public properties
  20.         //------------------------------------
  21.        
  22.         //------------------------------------
  23.         // constructor
  24.         //------------------------------------
  25.        
  26.         public function Main() {
  27.            
  28.             trace("--- public properties ---");
  29.             trace(Singleton.getInstance().singletonValue + ">>> from Singleton");
  30.             trace(SingletonExtended.getInstance().singletonValue + ">>> from SingletonExtended");
  31.             trace(SingletonExtended.getInstance().singletonExtendedValue + ">>> from SingletonExtended");
  32.             trace(Singleton.getInstance().singletonValue + ">>> from Singleton");
  33.            
  34.             trace("--- access to public methods ---");
  35.             trace(Singleton.getInstance().publicSingletonMethod() + ">>> from Singleton");
  36.             trace(SingletonExtended.getInstance().publicSingletonMethod() + ">>> from SingletonExtended");
  37.             trace(SingletonExtended.getInstance().publicSingletonExtendedMethod() + ">>> from SingletonExtended");
  38.            
  39.             trace("--- access to private methods ---");
  40.             trace(Singleton.getInstance().accessPrivateSingletonMethod() + ">>> from Singleton");
  41.             trace(SingletonExtended.getInstance().accessPrivateSingletonMethod() + ">>> from SingletonExtended");
  42.             trace(SingletonExtended.getInstance().accessPrivateSingletonExtendedMethod() + ">>> from SingletonExtended");
  43.            
  44.             trace("--- access to protected and overriden methods ---");
  45.             trace(Singleton.getInstance().accessProtectedSingletonMethod() + ">>> from Singleton");
  46.             trace(SingletonExtended.getInstance().accessProtectedSingletonMethod() + ">>> from SingletonExtended");
  47.             trace(SingletonExtended.getInstance().accessOverridenSingletonExtendedMethod() + ">>> from SingletonExtended");
  48.            
  49.             trace("--- value not initialized ---");
  50.             trace("before = ", Singleton.getInstance().myValueNotInitialized);
  51.             Singleton.getInstance().initializeMyValue(); // or SingletonExtended.getInstance().initializeMyValue();
  52.             trace("after = ", Singleton.getInstance().myValueNotInitialized);
  53.            
  54.             // this will generate errors
  55.             // as you can't instantiate twice a Singleton or a sublass of Singleton
  56.            
  57.             //var s1:Singleton = new Singleton();
  58.             //var s2:SingletonExtended = new SingletonExtended();
  59.            
  60.         }
  61.        
  62.         //
  63.         // PRIVATE, PROTECTED
  64.         //________________________________________________________________________________________________
  65.        
  66.         //
  67.         // PUBLIC
  68.         //________________________________________________________________________________________________
  69.        
  70.     }
  71. }

The Singleton class:

Actionscript:
  1. package {
  2.  
  3.     import flash.utils.getQualifiedClassName;
  4.     import flash.utils.getQualifiedSuperclassName;
  5.  
  6.     /**
  7.      * <b>Author:</b> Romuald Quantin - <a href="http://www.soundstep.com/" target="_blank">www.soundstep.com</a><br />
  8.      * <b>Class version:</b> 1.0<br />
  9.      * <b>Actionscript version:</b> 3.0<br />
  10.      * <b>Date:</b> 11-2008<br />
  11.      */
  12.     
  13.     public class Singleton {
  14.        
  15.         //------------------------------------
  16.         // private properties
  17.         //------------------------------------
  18.        
  19.         private static var _instance:Singleton = new Singleton();
  20.         private static var _className:String = getQualifiedClassName(super);
  21.        
  22.         private var _myValueNotInitialized:String;
  23.        
  24.         //------------------------------------
  25.         // public properties
  26.         //------------------------------------
  27.        
  28.         public var singletonValue:String = "Singleton value";
  29.        
  30.         //------------------------------------
  31.         // constructor
  32.         //------------------------------------
  33.        
  34.         public function Singleton() {
  35.             if (_instance != null && getQualifiedSuperclassName(this) != _className) throw new Error("Singleton is obviously... Singleton.");
  36.         }
  37.        
  38.         //
  39.         // PRIVATE, PROTECTED
  40.         //________________________________________________________________________________________________
  41.        
  42.         private function privateSingletonMethod():String {
  43.             return "privateSingletonMethod";
  44.         }
  45.        
  46.         protected function protectedSingletonMethod():String {
  47.             return "protectedSingletonMethod";
  48.         }
  49.        
  50.         //
  51.         // PUBLIC
  52.         //________________________________________________________________________________________________
  53.        
  54.         public function initializeMyValue():void {
  55.             _myValueNotInitialized = "I am initialized";
  56.         }
  57.        
  58.         public function updateInstance(instance:Singleton):void {
  59.             if (instance != null && instance is Singleton) _instance = instance;
  60.             else throw new Error("Incorrect Singleton update");
  61.         }
  62.  
  63.         public static function getInstance():Singleton {
  64.             return _instance;
  65.         }
  66.        
  67.         public function publicSingletonMethod():String {
  68.             return "publicSingletonMethod value";
  69.         }
  70.        
  71.         public function accessPrivateSingletonMethod():String {
  72.             return privateSingletonMethod();
  73.         }
  74.        
  75.         public function accessProtectedSingletonMethod():String {
  76.             return protectedSingletonMethod();
  77.         }
  78.        
  79.         public function get myValueNotInitialized():String {
  80.             return _myValueNotInitialized;
  81.         }
  82.     }
  83. }

The SingletonExtended class:

Actionscript:
  1. package {
  2.  
  3.     /**
  4.      * <b>Author:</b> Romuald Quantin - <a href="http://www.soundstep.com/" target="_blank">www.soundstep.com</a><br />
  5.      * <b>Class version:</b> 1.0<br />
  6.      * <b>Actionscript version:</b> 3.0<br />
  7.      * <b>Date:</b> 11-2008<br />
  8.      */
  9.     
  10.     public class SingletonExtended extends Singleton {
  11.        
  12.         //------------------------------------
  13.         // private properties
  14.         //------------------------------------
  15.        
  16.         private static var _instance:SingletonExtended = new SingletonExtended();
  17.        
  18.         //------------------------------------
  19.         // public properties
  20.         //------------------------------------
  21.        
  22.         public var singletonExtendedValue:String = "SingletonExtended value";
  23.        
  24.         //------------------------------------
  25.         // constructor
  26.         //------------------------------------
  27.        
  28.         public function SingletonExtended() {
  29.             if (_instance != null) throw new Error("SingletonExtended is obviously also... Singleton.");
  30.         }
  31.        
  32.         //
  33.         // PRIVATE, PROTECTED
  34.         //________________________________________________________________________________________________
  35.        
  36.         private function privateSingletonExtendedMethod():String {
  37.             return "privateSingletonExtendedMethod";
  38.         }
  39.        
  40.         override protected function protectedSingletonMethod():String {
  41.             return "protectedSingletonMethod overriden in SingletonExtended, value in super.protectedSingletonMethod(): " + super.protectedSingletonMethod();
  42.         }
  43.        
  44.         //
  45.         // PUBLIC
  46.         //________________________________________________________________________________________________
  47.        
  48.         public static function getInstance():SingletonExtended {
  49.             Singleton.getInstance().updateInstance(_instance);
  50.             return _instance;
  51.         }
  52.        
  53.         public function publicSingletonExtendedMethod():String {
  54.             return "publicSingletonExtendedMethod value";
  55.         }
  56.        
  57.         public function accessPrivateSingletonExtendedMethod():String {
  58.             return privateSingletonExtendedMethod();
  59.         }
  60.        
  61.         public function accessOverridenSingletonExtendedMethod():String {
  62.             return protectedSingletonMethod();
  63.         }
  64.    
  65.     }
  66. }

Vote in HexoSearch

Comments 4 Comments »

The ScrollPane component is a nice tool to use if you need to scroll a content or a list with more than text.

If you like to have everything a bit "tweened" in the sites you developed, you will feel the scroll movement of the scrollpane a bit straightforward.

There is an easy way to get this done.

When the user is scrolling the content with the scrollbar of the ScrollPane, the component dispatch an event:

ScrollEvent.SCROLL

The idea is to stop the movement of the content when this event is dispatched using:

e.stopImmediatePropagation()

And then handle the scrolling using a tweener.

I made an simple example with the CanvasUI class I built as it is using a ScrollPane component for the content, but you can use this code for a normal ScrollPane instance.

Here is the demo and the source, code of the main class below for a quick look.

Actionscript:
  1. package {
  2.  
  3.     import flash.display.Sprite;
  4.     import fl.events.ScrollEvent;
  5.     import fl.containers.ScrollPane;
  6.     import fl.controls.ScrollBarDirection;
  7.     import gs.TweenMax;
  8.    
  9.     import com.soundstep.ui.layouts.*; 
  10.     import com.soundstep.ui.*; 
  11.  
  12.     /**
  13.      * <b>Author:</b> Romuald Quantin - <a href="http://www.soundstep.com/" target="_blank">www.soundstep.com</a><br />
  14.      * <b>Actionscript version:</b> 3.0<br />
  15.      */
  16.     
  17.     public class Main extends Sprite {
  18.  
  19.         //------------------------------------
  20.         // private properties
  21.         //------------------------------------
  22.        
  23.         private var _canvas:CanvasUI;
  24.        
  25.         //------------------------------------
  26.         // public properties
  27.         //------------------------------------
  28.        
  29.        
  30.  
  31.         //------------------------------------
  32.         // constructor
  33.         //------------------------------------
  34.        
  35.         public function Main() {
  36.             _canvas = new CanvasUI();
  37.             addChild(_canvas);
  38.             _canvas.canvasAlpha = .2;
  39.             _canvas.horizontalCenter = 0;
  40.             _canvas.verticalCenter = 0;
  41.             _canvas.width = 300;
  42.             _canvas.height = 300;
  43.             _canvas.addChildUI(new ContentText());
  44.             _canvas.refresh();
  45.             _canvas.scrollPane.addEventListener(ScrollEvent.SCROLL, scrollHandler, true);
  46.         }
  47.        
  48.         //
  49.         // PRIVATE, PROTECTED, INTERNAL
  50.         //________________________________________________________________________________________________
  51.        
  52.         private function scrollHandler(e:ScrollEvent):void {
  53.             e.stopImmediatePropagation();
  54.             switch (e.direction) {
  55.                 case ScrollBarDirection.HORIZONTAL:
  56.                     TweenMax.to(_canvas.scrollPane.content, .5, {x:e.position*-1});
  57.                     break;
  58.                 case ScrollBarDirection.VERTICAL:
  59.                     TweenMax.to(_canvas.scrollPane.content, .5, {y:e.position*-1});
  60.                     break;
  61.             }
  62.         }
  63.        
  64.         // PUBLIC
  65.         //________________________________________________________________________________________________
  66.        
  67.        
  68.        
  69.     }
  70. }

Vote in HexoSearch

Comments 7 Comments »

I had to get an AIR application without the OS window, let's say windowless or chromeless.

I needed to be able, with my own graphics, to minimize, restore, maximize, close, close in the system tray or dock, fullscreen and resize.

You can find several tutorials on Internet (with which I got inspired) but I put all these functionalities in one small example as it is convenient.

You need to set 2 parameters out of the code, in the XML description file:

Actionscript:
  1. <systemChrome>none</systemChrome>
  2. <transparent>true</transparent>

I won’t explain the code, I guess it is easy enough to find out. You can comment if something is not clear for you.

Here is the code of the main mxml file:

Actionscript:
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" showFlexChrome="false" creationComplete="init()">
  3.  
  4. <mx:Script>
  5. <![CDATA[
  6.  
  7. [Embed(source="assets/iconDock.png")]
  8. [Bindable]
  9. public var IconDock:Class;
  10.  
  11. private function init():void {
  12.     registerMovementHandler();
  13.     setDock();
  14. }
  15.  
  16. public function registerMovementHandler():void {
  17.     appCanvas.addEventListener(MouseEvent.MOUSE_DOWN, mouseDrag);
  18.     btResizeBottomRight.addEventListener(MouseEvent.MOUSE_DOWN, resizeWindow);
  19.     btResizeBottomLeft.addEventListener(MouseEvent.MOUSE_DOWN, resizeWindow);
  20.     btResizeTopRight.addEventListener(MouseEvent.MOUSE_DOWN, resizeWindow);
  21.     btResizeTopLeft.addEventListener(MouseEvent.MOUSE_DOWN, resizeWindow);
  22. }
  23.  
  24. public function mouseDrag(e:MouseEvent):void {
  25.     if (e.target == e.currentTarget) stage.nativeWindow.startMove();
  26. }
  27.  
  28. public function resizeWindow(e:MouseEvent = null):void {
  29.     if (e.target == e.currentTarget) {
  30.         var corner:String;
  31.         switch(e.currentTarget){
  32.             case btResizeBottomRight:
  33.                 corner = NativeWindowResize.BOTTOM_RIGHT;
  34.                 break;
  35.             case btResizeBottomLeft:
  36.                 corner = NativeWindowResize.BOTTOM_LEFT;
  37.                 break;
  38.             case btResizeTopRight:
  39.                 corner = NativeWindowResize.TOP_RIGHT;
  40.                 break;
  41.             case btResizeTopLeft:
  42.                 corner = NativeWindowResize.TOP_LEFT;
  43.                 break;
  44.         }
  45.         stage.nativeWindow.startResize(corner);
  46.     }
  47. }
  48.  
  49. public function setDock():void {
  50.     if (NativeApplication.supportsSystemTrayIcon){
  51.         dockProperties();
  52.         SystemTrayIcon(NativeApplication.nativeApplication.icon).menu = dockMenu();
  53.     }
  54. }
  55.  
  56. private function dockProperties():void{
  57.     SystemTrayIcon(NativeApplication.nativeApplication.icon).tooltip = "Soundstep | chromeless window";
  58.     SystemTrayIcon(NativeApplication.nativeApplication.icon).addEventListener(MouseEvent.CLICK, undock);
  59. }
  60.  
  61. private function dockMenu():NativeMenu {
  62.     var menu:NativeMenu = new NativeMenu();
  63.     var open:NativeMenuItem = new NativeMenuItem("Open");
  64.     var close:NativeMenuItem = new NativeMenuItem("Close");
  65.     open.addEventListener(Event.SELECT, undock);
  66.     close.addEventListener(Event.SELECT, closeWindow);
  67.     menu.addItem(open);
  68.     menu.addItem(new NativeMenuItem("",true));
  69.     menu.addItem(close);
  70.     return menu;
  71. }
  72.  
  73. public function dock():void {
  74.     stage.nativeWindow.visible = false;
  75.     NativeApplication.nativeApplication.icon.bitmaps = [new IconDock() as Bitmap];
  76. }
  77.  
  78. public function undock(evt:Event):void {
  79.     stage.nativeWindow.visible = true;
  80.     stage.nativeWindow.orderToFront();
  81.     NativeApplication.nativeApplication.icon.bitmaps = [];
  82. }
  83.  
  84. public function closeWindow(e:Event = null):void {
  85.     stage.nativeWindow.close();
  86. }
  87.  
  88. public function setFullscreen():void {
  89.     var state:String = (stage.displayState == StageDisplayState.FULL_SCREEN) ? StageDisplayState.NORMAL : StageDisplayState.FULL_SCREEN;
  90.     stage.displayState = state;
  91. }
  92.  
  93. ]]>
  94. </mx:Script>
  95.  
  96. <mx:Canvas right="0" left="0" top="0" bottom="0" backgroundColor="#CF3232" id="appCanvas">
  97.  
  98.     <mx:Label buttonMode="true" mouseChildren="false" text="Min" top="10" color="#000000" id="btMin" click="minimize()" horizontalCenter="58"/>
  99.     <mx:Label buttonMode="true" mouseChildren="false" text="Max" top="10" color="#000000"  id="btMax" click="maximize()" horizontalCenter="-45"/>
  100.     <mx:Label buttonMode="true" mouseChildren="false" text="Close" top="10" color="#000000" id="btClose" click="closeWindow()" horizontalCenter="96"/>
  101.     <mx:Label buttonMode="true" mouseChildren="false" text="Restore" color="#000000" id="btRestore" click="restore()" top="10" horizontalCenter="-91"/>
  102.     <mx:Label buttonMode="true" mouseChildren="false" y="10" text="Tray/Dock" color="#000000" id="btSys" click="dock()" horizontalCenter="8"/>
  103.     <mx:Label buttonMode="true" mouseChildren="false" text="Fullscreen" color="#000000" horizontalCenter="0" bottom="10" id="btFullscreen" click="setFullscreen()"/>
  104.    
  105.     <mx:Canvas width="20" height="20" backgroundColor="#7B0707" borderStyle="none" borderColor="#FFFFFF" id="btResizeBottomRight" themeColor="#494949" right="0" bottom="0" />
  106.    
  107.     <mx:Canvas width="20" height="20" backgroundColor="#7B0707" borderStyle="none" borderColor="#FFFFFF" id="btResizeTopLeft" themeColor="#494949"  left="0" top="0" />
  108.    
  109.     <mx:Canvas width="20" height="20" backgroundColor="#7B0707" borderStyle="none" borderColor="#FFFFFF" id="btResizeBottomLeft" themeColor="#494949" bottom="0" left="0" />
  110.  
  111.     <mx:Canvas width="20" height="20" backgroundColor="#7B0707" borderStyle="none" borderColor="#FFFFFF" id="btResizeTopRight" themeColor="#494949" right="0" top="0" />
  112.  
  113. </mx:Canvas>
  114.    
  115. </mx:WindowedApplication>

You can download the source or install the AIR application:

In order to view this page
You must enable Javascript
And download the Flash Player
get flash player


Vote in HexoSearch

Comments 10 Comments »

I made some experiments on how to easily access to data in a Flash site. It is probably a mix with good and bad ways but I think it is worth having a look.

What I’ve done here is get data with syntax that is similar to what you get using E4X in AS3. For example with XML and E4X you can use syntax like that:

xml..item[2].author.name.text();

I’m not saying that this experiment is a good practice but I want to show you what you can do by extending the Array class and extending the Proxy class in AS3. The Proxy class is the replacement of the __resolve we were using in AS2.

Let’s say we have a website that will load data from a database at the start, for example using AMFPHP or whatever, and we are going to fill this data at run-time.

In my example I have a kind of tree with countries > cities > people.

I would like to be able to loop easily through the data, as well as getting them with a friendly/readable syntax if needed.

In my example, I have a Singleton class that contains all the data. I don’t load the data in my example, I statically fill the class. I will access to the data like that:

Content.data

This will return me a array of data, which will contains an array of countries, each instance of the country array will contains an array of cities, which will contains an array of people, etc…

So I’d like to access to my data like this:

To browse the countries:
Content.data[0]
Content.data[1]

To browse the cities in the countries:
Content.data[0][0]
Content.data[0][1]

To browse the people in the cities:
Content.data[0][0][0]
Content.data[0][0][1]

That’s nice to loop through with a “for each” or whatever. An Array is a pretty nice tool to store data as you get some functions to manage it like push, splice, reverse, etc.

But these arrays have a problem, what if I need to get more info on my countries, like the weather, an ID or the surface of the country? I would like access to more data like that:

Content.data[0].name
Content.data[0].id

This is possible with an Array as it is one of the few classes in AS3 that are dynamic. It means you can set any property at run time. For example MovieClip is dynamic and Sprite is not, try to add properties at run-time on these classes to see the result. Some people are saying that is it a good and bad things. It is easy to use but you don’t know what kind of properties will be added in your Array at run-time.

So you don’t want that, and better, you want to control what kind of data they are going to put in your Array. We will get that by extending the Array class.

There’s a nice explanation here to extends an Array, as well as control the data type your custom Array class will accept.

So far it is not bad, we can easily access to our data, we can have properties on these arrays and finally we know that we will have the right type of content inside.

The other thing I want is access to my data with a nice E4X-like:

Content.data.France.name
Content.data.France.Paris.name

Easy, we just need a property France on this array and it is done. Well, the thing is we don’t know yet what this array will be filled with, so we are talking about dynamic properties. These dynamic properties will have to be added to the array when we create it because we said we want to control and we don’t want people adding their own properties.

How do we do that?

We’re going to use the Proxy class that make able us able to handle dynamic properties and dynamic calling.

We will have a class that will be an array (what you get when you call Content.data), a class for the countries, a class for the cities and a class for the people. The people class won’t be an array.

So we have the classes DataArray, CountryArray and CityArray that are extending the Array class. We will also have a Proxy class (a class that is extending the Proxy one) for each of the Array. I choose to a Proxy class for each Array class as it is easier to understand.

Let’s see a bit of code.

The Singleton Content class

Actionscript:
  1. package com.soundstep.data {
  2.  
  3.     /**
  4.      * <b>Author:</b> Romuald Quantin - <a href="http://www.soundstep.com/" target="_blank">www.soundstep.com</a><br />
  5.      * <b>Class version:</b> 1.0<br />
  6.      * <b>Actionscript version:</b> 3.0<br />
  7.      * <b>Copyright:</b> Free to use and change (except to include in a framework), an notification email will be welcome for a commercial use (just for information).<br />
  8.      * <b>Date:</b> 05-2008<br />
  9.      * <b>Usage:</b> Manage a Section
  10.      * @example
  11.      * <listing version="3.0">
  12.        
  13.      * </listing>
  14.      */
  15.    
  16.     public class Content {
  17.        
  18.         //------------------------------------
  19.         // private properties
  20.         //------------------------------------
  21.        
  22.         private static var content:Content = new Content();
  23.         private static var _data:Data;
  24.        
  25.         //------------------------------------
  26.         // public properties
  27.         //------------------------------------
  28.        
  29.        
  30.        
  31.         //------------------------------------
  32.         // constructor
  33.         //------------------------------------
  34.        
  35.         public function Content() {
  36.             if (content) throw new Error("Content is Singleton and can only be accessed through Content.data");
  37.             if (_data == null) buildData();
  38.         }
  39.        
  40.         //
  41.         // PRIVATE, INTERNAL
  42.         //________________________________________________________________________________________________
  43.        
  44.         private function buildData():void {
  45.             _data = new Data();
  46.            
  47.         }
  48.        
  49.         //
  50.         // PUBLIC
  51.         //________________________________________________________________________________________________
  52.        
  53.         public static function get data():Data {
  54.             return _data;
  55.         }
  56.        
  57.     }
  58.    
  59. }

The Data and DataArray class

The DataArray is extending the Array class. To be able to extend the Array class you need the dynamic keyword before the class.

dynamic public class DataArray extends Array {

We have a private property type Class used to control the Data we will push in our extended Array.

private var dataType:Class;

To control the type pushed we have to overwrite 4 functions: push, concat, splice and unshift, as it is nicely explained in the AS3 documentation.

Here is the code:

Actionscript:
  1. package com.soundstep.data {
  2.  
  3.     /**
  4.      * <b>Author:</b> Romuald Quantin - <a href="http://www.soundstep.com/" target="_blank">www.soundstep.com</a><br />
  5.      * <b>Class version:</b> 1.0<br />
  6.      * <b>Actionscript version:</b> 3.0<br />
  7.      * <b>Copyright:</b> Free to use and change (except to include in a framework), an notification email will be welcome for a commercial use (just for information).<br />
  8.      * <b>Date:</b> 05-2008<br />
  9.      * <b>Usage:</b> Manage a Section
  10.      * @example
  11.      * <listing version="3.0">
  12.        
  13.      * </listing>
  14.      */
  15.    
  16.     dynamic public class DataArray extends Array {
  17.        
  18.         //------------------------------------
  19.         // private properties
  20.         //------------------------------------
  21.        
  22.         private var dataType:Class;
  23.  
  24.         //------------------------------------
  25.         // public properties
  26.         //------------------------------------
  27.                
  28.         //------------------------------------
  29.         // constructor
  30.         //------------------------------------
  31.        
  32.         public function DataArray(...args) {
  33.             dataType = Country;
  34.             for (var i:int=0; i<args.length; i++) this.push(args[i]);
  35.             length = length;
  36.         }
  37.        
  38.         //
  39.         // PRIVATE, INTERNAL
  40.         //________________________________________________________________________________________________
  41.        
  42.         //
  43.         // PUBLIC
  44.         //________________________________________________________________________________________________
  45.        
  46.         AS3 override function push(...args):uint {
  47.             for (var i:* in args) {
  48.                 if (!(args[i] is dataType)) {
  49.                     trace("Error: you must push an Object type Country");
  50.                     args.splice(i,1);
  51.                 }
  52.             }
  53.             return super.push.apply(this, args);
  54.         }
  55.         
  56.         AS3 override function concat(...args):Array {
  57.             var passArgs:DataArray = new DataArray();
  58.             for (var i:* in args) passArgs.push(args[i]);
  59.             return super.concat.apply(this, passArgs);
  60.         }
  61.        
  62.         AS3 override function splice(...args):* {
  63.             if (args.length> 2) {
  64.                 for (var i:int=2; i<args.length; i++) {
  65.                     if (!(args[i] is dataType)) args.splice(i,1);
  66.                 }
  67.             }
  68.             return super.splice.apply(this, args);
  69.         }
  70.         
  71.         AS3 override function unshift(...args):uint {
  72.             for (var i:* in args) {
  73.                 if (!(args[i] is dataType)) args.splice(i,1);
  74.             }
  75.             return super.unshift.apply(this, args);
  76.         }
  77.        
  78.     }
  79.    
  80. }

To create a new DataArray instance, we actually don’t use the DataArray class directly but his Proxy, that will handle the dynamic properties.

I named the class Data, it is what you get with Content.data.

To extend the Proxy class you need to import the class itself and its namespace:

import flash.utils.Proxy;
import flash.utils.flash_proxy;

Proxy is also a dynamic class:

dynamic public class Data extends Proxy {

We have our private var that will be our DataArray instance:

private var _item:DataArray;

To control the properties and method called through our Proxy, we need to override 3 methods (with the namespace flash_proxy):

override flash_proxy function callProperty(methodName:*, ... args):* {
override flash_proxy function getProperty(name:*):* {
override flash_proxy function setProperty(name:*, value:*):void {

When you will call an unknown method, the Proxy class invoke callProperty, and when you will call or set a property (like Content.data.France), the Proxy class invoke getProperty and setProperty.

In my example I trace an Error if you try to set your own property, this is our control. When you get a property, I loop through the DataArray instance to see if I’ve got an item with that name. We could do it with the id or any property of your choice (that is in the DataArray class), and if yes I return it. This is the instance you get by using Content.data.France.

So in brief, when I call Content.data.France, I’m going through the Proxy that is basically managing the dynamic properties added at run-time. The DataArray class is extending the Array class to control the properties and data type.

Here is the code of the Data class:

Actionscript:
  1. package com.soundstep.data {
  2.  
  3.     /**
  4.      * <b>Author:</b> Romuald Quantin - <a href="http://www.soundstep.com/" target="_blank">www.soundstep.com</a><br />
  5.      * <b>Class version:</b> 1.0<br />
  6.      * <b>Actionscript version:</b> 3.0<br />
  7.      * <b>Copyright:</b> Free to use and change (except to include in a framework), an notification email will be welcome for a commercial use (just for information).<br />
  8.      * <b>Date:</b> 05-2008<br />
  9.      * <b>Usage:</b> Manage a Section
  10.      * @example
  11.      * <listing version="3.0">
  12.        
  13.      * </listing>
  14.      */
  15.  
  16.     import flash.utils.Proxy;
  17.     import flash.utils.flash_proxy;
  18.    
  19.     dynamic public class Data extends Proxy {
  20.        
  21.         //------------------------------------
  22.         // private properties
  23.         //------------------------------------
  24.        
  25.         private var _item:DataArray;
  26.        
  27.         //------------------------------------
  28.         // public properties
  29.         //------------------------------------
  30.                
  31.         //------------------------------------
  32.         // constructor
  33.         //------------------------------------
  34.        
  35.         public function Data(...args) {
  36.             _item = new DataArray();
  37.             for (var i:int=0; i<args.length; i++) _item.push(args[i]);
  38.         }
  39.        
  40.         //
  41.         // PRIVATE, INTERNAL
  42.         //________________________________________________________________________________________________
  43.        
  44.         private function getString():String {
  45.             var s:String = "";
  46.             for (var i:uint=0; i<_item.length; i++) {
  47.                 s += "index:" + i + ", id:" + _item[i].id + ", name:" + _item[i].name;
  48.                 if (i <_item.length-1) s += "\n";
  49.             }
  50.             if (_item.length == 0) return _item.name + " is empty";
  51.             else return s;
  52.         }
  53.        
  54.         //
  55.         // PUBLIC
  56.         //________________________________________________________________________________________________
  57.        
  58.         override flash_proxy function callProperty(methodName:*, ... args):* {
  59.             var res:*;
  60.             switch (methodName.toString()) {
  61.                 case 'clear':
  62.                     _item = new DataArray();
  63.                     break;
  64.                 case 'list':
  65.                     trace(getString());
  66.                     break;
  67.                 default:
  68.                     res = _item[methodName].apply(_item, args);
  69.                     break;
  70.             }
  71.             return res;
  72.         }
  73.  
  74.         override flash_proxy function getProperty(name:*):* {
  75.             for each (var i:* in _item) {
  76.                 if (name == i.name) {
  77.                     return i;
  78.                     break;
  79.                 }
  80.             }
  81.             return _item[name];
  82.             throw new Error("ERROR: Property " + name + " not found!");
  83.         }
  84.  
  85.         override flash_proxy function setProperty(name:*, value:*):void {
  86.             trace("ERROR: You can't set your own property!");
  87.         }
  88.        
  89.         public function toString():String {
  90.             return getString();
  91.         }
  92.     }
  93. }

Basically the cities and countries classes are doing the same, the dataType and properties are different, a country is asking a City type and the a city is asking a People type.

For example the CountryArray class asks an id and name to create the array, you have to use a syntax like:

var france:Country = new Country(0, "France");

As it is an Array extended you can still pass more arguments (but they have to be the right type), the type here is City, that is also an Array extended but a city instance is asking an id, a name and weather as parameters:

var france:Country = new Country(0, "France", new City(0, "Paris", "As bad as London!"), new City(1, "Marseille", "More sun than Paris"));

Here is how I fill the Content with some examples:

Actionscript:
  1. //country
  2. var france:Country = new Country(0, "France");
  3. Content.data.push(france);
  4. var uk:Country = new Country(1, "UK");
  5. Content.data.push(uk);
  6.  
  7. // city
  8. var paris:City = new City(0, "Paris", "As bad as London!");
  9. france.push(paris);
  10. france.myvar = "qwe";
  11. var marseille:City = new City(1, "Marseille", "More sun than Paris");
  12. france.push(marseille);
  13. var london:City = new City(0, "London", "Quite bad!");
  14. uk.push(london);
  15. var liverpool:City = new City(1, "Liverpool", "Even worst than London");
  16. uk.push(liverpool);
  17.  
  18. // people
  19. var franck:People = new People(0, "Franck", "Dupont", 29);
  20. paris.push(franck);
  21. var stephane:People = new People(1, "Stephane", "Durand", 42);
  22. paris.push(stephane);
  23. var john:People = new People(0, "John", "Doe", 35);
  24. london.push(john);
  25. var david:People = new People(0, "David", "Doe", 37);
  26. london.push(david);

And finally here is some example to access to your data:

Actionscript:
  1. Content.data.length
  2. Content.data.France.length
  3. Content.data[0].name
  4. Content.data.France.name
  5. Content.data.France[0].name
  6. Content.data.France.Paris.name
  7. Content.data.France.Paris.Franck.name
  8. Content.data[0][0][0].name

I didn’t optimize/clean the classes and as I said, I’m not saying that it is a good way of accessing data in Flash, but it shows you how to control data type, how to extend an Array, how to extend the Proxy class and how to handle properties and methods of a class at low-level.

Download the source.

Vote in HexoSearch

Comments No Comments »

Back to the line drawing I started in this post.

I wanted to get a snake-like line and I had a try with Papervision3D. It made me able to handle the vertices and then delete the end of the lines.

Draw 1 (demo)

I started from an excellent work from Xero (the.fontvir.us) on the Papervision3D mailing list but instead of using a Lorenz attractor, I used the Tweener Bezier property as I did on the 2D versions.

I set a number of vertices, that is giving me the length of the line. Here is the code:

Actionscript:
  1. /*
  2. * Lines3D1
  3. *
  4. * Copyright info: Free to use and change, an notification email will be welcome for a commercial use
  5. * Actionscript: built for actionscript 3.0
  6. * 05-2008
  7. *
  8. * @author      Romuald Quantin - romu@soundstep.com - www.soundstep.com
  9. * @version    1.0
  10. * @usage       
  11. *
  12. */
  13.  
  14. package {
  15.    
  16.     import org.papervision3d.core.geom.renderables.*;
  17.     import org.papervision3d.materials.special.*;
  18.     import org.papervision3d.core.geom.*;
  19.     import org.papervision3d.objects.*;
  20.     import org.papervision3d.cameras.*;
  21.     import caurina.transitions.Tweener;
  22.     import caurina.transitions.properties.CurveModifiers;
  23.     import flash.events.*;
  24.  
  25.     public class Lines3D1 extends BaseP3D {
  26.        
  27.         //------------------------------------
  28.         // private properties
  29.         //------------------------------------
  30.        
  31.         private var sight:DisplayObject3D;
  32.         private var lineMaterial:LineMaterial;
  33.         private var arrLines:Array = [];
  34.         private var _objArray:Array = [];
  35.         private var _linesNum:int = 5;
  36.         private var _maxRadius:int = 200;
  37.         private var _pointNum:uint = 80;
  38.         private var _verticesNum:uint = 50;
  39.         
  40.         //------------------------------------
  41.         // public properties
  42.         //------------------------------------
  43.        
  44.         //------------------------------------
  45.         // constructor
  46.         //------------------------------------
  47.         
  48.         public function Lines3D1() {
  49.             stage.frameRate = 81;
  50.             CurveModifiers.init();
  51.             super(600, 600);
  52.             b.addEventListener(MouseEvent.CLICK, reload);
  53.             addChild(b);
  54.         }
  55.        
  56.         //
  57.         // PRIVATE, PROTECTED
  58.         //________________________________________________________________________________________________
  59.        
  60.         override protected function init2D():void {
  61.             for (var u:int=0; u<_linesNum; u++) {
  62.                 var obj:Object = {};
  63.                 var newPos:Object = getRandomPos();
  64.                 obj['prevX'] = obj['x'] = newPos['x'];
  65.                 obj['prevY'] = obj['y'] = newPos['y'];
  66.                 obj['prevZ'] = obj['z'] = newPos['z'];
  67.                 obj['color'] = Math.random() * 0xFFFFFF;
  68.                 _objArray.push(obj);
  69.                 randomTween(getRandomData(obj));
  70.             }
  71.         }
  72.  
  73.         override protected function init3D():void {
  74.             camera.zoom = 5;
  75.             camera.z = -200;
  76.             sight = new DisplayObject3D();
  77.             camera.target = sight;
  78.             lineMaterial = new LineMaterial(Math.random()* 0xFFFFFF);
  79.             for (var f:int=0; f<_linesNum; f++) {
  80.                 var line:Lines3D = new Lines3D(lineMaterial, "line");
  81.                 arrLines.push(line);
  82.                 scene.addChild(line, "line");
  83.             }
  84.         }
  85.        
  86.         override protected function processFrame():void {
  87.             for (var h:int=0; h<_linesNum; h++) {
  88.                 arrLines[h].addLine(new Line3D(arrLines[h], new LineMaterial(_objArray[h]['color'], 1), 3, new Vertex3D(_objArray[h]['prevX'],_objArray[h]['prevY'],_objArray[h]['prevZ']), new Vertex3D(_objArray[h]['x'],_objArray[h]['y'],_objArray[h]['z'])));
  89.                 _objArray[h]['prevX'] = _objArray[h]['x'];
  90.                 _objArray[h]['prevY'] = _objArray[h]['y'];
  91.                 _objArray[h]['prevZ'] = _objArray[h]['z'];
  92.                 if (arrLines[h].lines.length> _verticesNum) arrLines[h].lines.shift();
  93.                 camera.x += (((mouseX -(stage.stageWidth*.5))*3)-camera.x)*.01;
  94.                 camera.y += (((mouseY-(stage.stageHeight*.5))*3)-camera.y)*.01;
  95.             }
  96.         }
  97.        
  98.         private function randomTween(o:Object):void {
  99.             Tweener.addTween(o, {x:o['x1'], y:o['y1'], z:o['z1'], _bezier:o['bezier'], time :o ['time'], transition:"linear", onComplete:
  100.                 function():void {
  101.                     randomTween(getRandomData(o));
  102.                 }
  103.             });
  104.         }
  105.        
  106.         private function getRandomData(o:Object):Object {
  107.             o['time'] = Math.random() * (_pointNum*.5) + (_pointNum*.25);
  108.             var newPos:Object = getRandomPos();
  109.             o['x1'] = newPos['x'];
  110.             o['y1'] = newPos['y'];
  111.             o['z1'] = newPos['z'];
  112.             o['bezier'] = [];
  113.             for (var i:int=0; i<_pointNum; i++) {
  114.                 var newBezierPos:Object = getRandomPos();
  115.                 o['bezier'].push({
  116.                     x:newBezierPos['x'],
  117.                     y:newBezierPos['y'],
  118.                     z:newBezierPos['z']
  119.                 });
  120.             }
  121.             return o;
  122.         }
  123.        
  124.         private function getRandomPos():Object {
  125.             var angleY:Number = Math.random() * 2 * Math.PI;
  126.             var angleXZ:Number = Math.random() * 2 * Math.PI;
  127.             var o:Object = {};
  128.             o['x'] = Math.cos(angleY) * Math.sin(angleXZ) * _maxRadius;
  129.             o['y'] = Math.sin(angleY) * Math.sin(angleXZ) * _maxRadius;
  130.             o['z'] = Math.cos(angleXZ) * _maxRadius;
  131.             return o;
  132.         }
  133.        
  134.         private function reload(e:MouseEvent = null):void {
  135.             Tweener.removeAllTweens();
  136.             for (var r:int=0; r<_linesNum; r++) {
  137.                 scene.removeChild(arrLines[r]);
  138.             }
  139.             _objArray = [];
  140.             arrLines = [];
  141.             init3D();
  142.             init2D();
  143.         }
  144.        
  145.         //
  146.         // PUBLIC
  147.         //________________________________________________________________________________________________
  148.        
  149.     }
  150.    
  151. }

Draw 2 (demo)

And a bit of fun with the Bitmap layer, the ColorMatrixFilter and the BlurFilter.

Actionscript:
  1. /*
  2. * Lines3D2
  3. *
  4. * Copyright info: Free to use and change, an notification email will be welcome for a commercial use
  5. * Actionscript: built for actionscript 3.0
  6. * 05-2008
  7. *
  8. * @author      Romuald Quantin - romu@soundstep.com - www.soundstep.com
  9. * @version    1.0
  10. * @usage       
  11. *
  12. */
  13.  
  14. package {
  15.    
  16.     import flash.geom.Point;   
  17.     import flash.display.Bitmap;   
  18.     import flash.display.BitmapData;   
  19.     import flash.filters.BlurFilter;   
  20.     import flash.filters.ColorMatrixFilter
  21.     import org.papervision3d.core.geom.renderables.*;
  22.     import org.papervision3d.materials.special.*;
  23.     import org.papervision3d.core.geom.*;
  24.     import org.papervision3d.objects.*;
  25.     import org.papervision3d.cameras.*;
  26.     import caurina.transitions.Tweener;
  27.     import caurina.transitions.properties.CurveModifiers;
  28.     import flash.events.*;
  29.    
  30.     public class Lines3D2 extends BaseP3D {
  31.        
  32.         //------------------------------------
  33.         // private properties
  34.         //------------------------------------
  35.        
  36.         private var sight:DisplayObject3D;
  37.         private var lineMaterial:LineMaterial;
  38.         private var arrLines:Array = [];
  39.         private var _objArray:Array = [];
  40.         private var _linesNum:int = 5;
  41.         private var _maxRadius:int = 200;
  42.         private var _pointNum:uint = 80;
  43.         private var _verticesNum:uint = 30;
  44.         private var _cmf:ColorMatrixFilter;
  45.         private var _bf:BlurFilter;
  46.         private var _bmd:BitmapData;
  47.         private var _bm:Bitmap;
  48.        
  49.         //------------------------------------
  50.         // public properties
  51.         //------------------------------------
  52.        
  53.         //------------------------------------
  54.         // constructor
  55.         //------------------------------------
  56.        
  57.         public function Lines3D2() {
  58.             stage.frameRate = 81;
  59.             CurveModifiers.init();
  60.             super(600, 600);
  61.             b.addEventListener(MouseEvent.CLICK, reload);
  62.             addChild(b);
  63.         }
  64.        
  65.         //
  66.         // PRIVATE, PROTECTED
  67.         //________________________________________________________________________________________________
  68.        
  69.         override protected function init2D():void {
  70.             _cmf = new ColorMatrixFilter([1.05,0,0,0,0,
  71.                                           0,1.05,0,0,0,
  72.                                           0,0,1.05,0,0,
  73.                                           0,0,0,.54,0]);
  74.             _bf = new BlurFilter(5, 5, 2);
  75.             createCanvas();
  76.             for (var u:int=0; u<_linesNum; u++) {
  77.                 var obj:Object = {};
  78.                 var newPos:Object = getRandomPos();
  79.                 obj['prevX'] = obj['x'] = newPos['x'];
  80.                 obj['prevY'] = obj['y'] = newPos['y'];
  81.                 obj['prevZ'] = obj['z'] = newPos['z'];
  82.                 obj['color'] = Math.random() * 0xFFFFFF;
  83.                 _objArray.push(obj);
  84.                 randomTween(getRandomData(obj));
  85.             }
  86.         }
  87.        
  88.         override protected function init3D():void {
  89.             camera.zoom = 5;
  90.             camera.z = -200;
  91.             sight = new DisplayObject3D();
  92.             camera.target = sight;
  93.             lineMaterial = new LineMaterial(Math.random()* 0xFFFFFF);
  94.             for (var f:int=0; f<_linesNum; f++) {
  95.                 var line:Lines3D = new Lines3D(lineMaterial, "line");
  96.                 arrLines.push(line);
  97.                 scene.addChild(line, "line");
  98.             }
  99.         }
  100.        
  101.         private function createCanvas():void {
  102.             _bmd = new BitmapData(600, 600, true, 0x000000);
  103.             _bm = new Bitmap(_bmd);
  104.             addChild(_bm);
  105.         }
  106.  
  107.         override protected function processFrame():void {
  108.             for (var h:int=0; h<_linesNum; h++) {
  109.                 arrLines[h].addLine(new Line3D(arrLines[h], new LineMaterial(_objArray[h]['color'], 1), 3, new Vertex3D(_objArray[h]['prevX'],_objArray[h]['prevY'],_objArray[h]['prevZ']), new Vertex3D(_objArray[h]['x'],_objArray[h]['y'],_objArray[h]['z'])));
  110.                 _objArray[h]['prevX'] = _objArray[h]['x'];
  111.                 _objArray[h]['prevY'] = _objArray[h]['y'];
  112.                 _objArray[h]['prevZ'] = _objArray[h]['z'];
  113.                 if (arrLines[h].lines.length> _verticesNum) arrLines[h].lines.shift();
  114.                 camera.x += (((mouseX -(stage.stageWidth*.5))*3)-camera.x)*.01;
  115.                 camera.y += (((mouseY-(stage.stageHeight*.5))*3)-camera.y)*.01;
  116.             }
  117.             _bmd.applyFilter(_bmd, _bmd.rect, new Point(0, 0), _cmf);
  118.             _bmd.applyFilter(_bmd, _bmd.rect, new Point(0, 0), _bf);
  119.             _bmd.draw(this);
  120.         }
  121.        
  122.         private function randomTween(o:Object):void {
  123.             Tweener.addTween(o, {x:o['x1'], y:o['y1'], z:o['z1'], _bezier:o['bezier'], time :o ['time'], transition:"linear", onComplete:
  124.                 function():void {
  125.                     randomTween(getRandomData(o));
  126.                 }
  127.             });
  128.         }
  129.        
  130.         private function getRandomData(o:Object):Object {
  131.             o['time'] = Math.random() * (_pointNum*.5) + (_pointNum*.25);
  132.             var newPos:Object = getRandomPos();
  133.             o['x1'] = newPos['x'];
  134.             o['y1'] = newPos['y'];
  135.             o['z1'] = newPos['z'];
  136.             o['bezier'] = [];
  137.             for (var i:int=0; i<_pointNum; i++) {
  138.                 var newBezierPos:Object = getRandomPos();
  139.                 o['bezier'].push({
  140.                     x:newBezierPos['x'],
  141.                     y:newBezierPos['y'],
  142.                     z:newBezierPos['z']
  143.                 });
  144.             }
  145.             return o;
  146.         }
  147.        
  148.         private function getRandomPos():Object {
  149.             var angleY:Number = Math.random() * 2 * Math.PI;
  150.             var angleXZ:Number = Math.random() * 2 * Math.PI;
  151.             var o:Object = {};
  152.             o['x'] = Math.cos(angleY) * Math.sin(angleXZ) * _maxRadius;
  153.             o['y'] = Math.sin(angleY) * Math.sin(angleXZ) * _maxRadius;
  154.             o['z'] = Math.cos(angleXZ) * _maxRadius;
  155.             return o;
  156.         }
  157.        
  158.         private function reload(e:MouseEvent = null):void {
  159.             Tweener.removeAllTweens();
  160.             for (var r:int=0; r<_linesNum; r++) {
  161.                 scene.removeChild(arrLines[r]);
  162.             }
  163.             removeChild(_bm);
  164.             _objArray = [];
  165.             arrLines = [];
  166.             init3D();
  167.             init2D();
  168.         }
  169.        
  170.         //
  171.         // PUBLIC
  172.         //________________________________________________________________________________________________
  173.        
  174.     }
  175.    
  176. }

Get a random point in a sphere

maxRadius = 200
angleY = Math.random() * 2 * Math.PI
angleXZ = Math.random() * 2 * Math.PI
x = Math.cos(angleY) * Math.sin(angleXZ) * maxRadius
y = Math.sin(angleY) * Math.sin(angleXZ) * maxRadius
z = Math.cos(angleXZ) * maxRadius

Get the source here.

Vote in HexoSearch

Comments 3 Comments »