Freelance programming services.

Brighton, London & the South East.

PHP, MySQL, JavaScript, WebGL, JQuery, Processing.js, Three.js,
ActionScript, Flash, Flex, AIR, Away3d,
Processing, OpenFrameworks, C++, OpenCV, OpenNI, OpenKinect, Android, iOS, PhoneGap, HTML5, Unity.

Technical project management.
Consultancy.
Cross platform device strategies.
Creative coding.

Please for current availability.

Covering Brighton, London & the South East

Please for current availability

Fractals in ActionScript 3 – A Flash Tutorial

This tutorial will talk you through the basics of producing effects like the one above using ActionScript 3.

What are Fractals?

Fractals are shapes or patterns that repeat at many levels. They are fascinating because they occur throughout the natural world, yet are rather counter-intuitive to programming environments because they involve infinite recursion. The leaf of a fern is a good example, where the fronds of the leaf are the shape of the leaf itself, and the subdivisions of the frond are the same shape again, and on, and on to beyond the limits of the human eye.

They are fun to play with in Flash because they are a quick way of producing complex, unpredictable results from very basic algorithms. The only trick is getting your head around the concept of infinite recursion, where a child and a parent are one and the same object. But as soon as you’ve mastered that, there’s nothing to it.

Unfortunately, most clients don’t like the words complex and unpredictable, so I’ve never found it particularly easy to slip fractals into my work. Although I persevere.

The Tree

First of all lets outline a base class that’s going to build and control our fractal. I’m going to call this the “tree”, and each of the fractal elements a “branch”. Even though our finished work will likely look nothing like a tree, they are constructed in a similar way. Trees, whose branches divide into ever-smaller branches, are another less obvious example of fractals in the natural world.

The Tree class needs to define two key things – the number of children each branch can have, and the number of levels it is allowed to go down to. If we don’t define these, or our branches don’t know these limits, we’ll very quickly get into infinite loops and things will start crashing.

For starters, we’ll give the values CHILDREN and MAXLEVEL low numbers so we can see what’s going on while we’re building. We can up the numbers once we’re finished. Bear in mind though that increases are exponential, so anything above 5 is going to start pushing the limits of the processor.

package com.zenbullets.fractals.tutorial
{
import flash.display.MovieClip;
import flash.display.Sprite;

public class Tree extends MovieClip {

   // number of children each branch can have
   private static const CHILDREN:Number = 3;

   // depth to recurse down to
   private static const MAXLEVEL:Number = 5;

   // the seed sprite to our fractal
   private var _trunk:Sprite;

   //====== constructor

   public function Tree () {
      _trunk = new Branch(this, 1);
      _trunk.x = 200;
      _trunk.y = 200;
      addChild(_trunk);
   }

   //====== getters/setters

   public function get children():String { return CHILDREN; }
   public function get maxlevel():String { return MAXLEVEL; }

   }

}

The only action this class performs so far is to create the _trunk object and position it somewhere we can see it.

_trunk = new Branch(this, 1);
_trunk.x = 200;
_trunk.y = 200;

Keeping with our tree metaphor, the trunk of a tree is basically its first branch, and in our app it will follow the same rules as each of the other branches.

Note that we have used the new AS3 type Sprite for our branches. A Sprite is a simple visual object, like a MovieClip but without a timeline. It’s ideal for what we are doing here. To add our first branch to the display list we call:

addChild(_trunk);

The Tree class extends MovieClip, so in order to see this in action you’ll need to either associate the class with a MovieClip on the stage, or make it the document root class.

The Branches

The inevitable things in life, as we know, are death, taxes, and turning into your parents. This is why an object that is both a child and a parent shouldn’t be too foreign a concept for you to grasp.

The Branch object is going to be our fractal, it will be both parent and child. Lets start by thinking of it as just the trunk of the tree, and outline a class as follows:

package com.zenbullets.fractals.tutorial
{
import flash.display.Sprite;

public class Branch extends Sprite
{

   private var _theBoss:Tree;
   private var _level:Number;

   //====== constructor

   public function Branch (controller:Tree, l:Number) {
      _theBoss = controller;
      _level = l;

      // pick a random colour
      var myColour:Number = Math.floor(Math.random()*0xFFFFFF);

      var rad:Number = 20;
      var linelen:Number = 80;
      var lineweight:Number = 4;

      this.graphics.beginFill(myColour);
      this.graphics.drawCircle(0, 0, rad);
      this.graphics.endFill();

      this.graphics.beginFill(myColour);
      this.graphics.drawCircle(0, -linelen, rad);
      this.graphics.endFill();

      this.graphics.moveTo(0,0);
      this.graphics.lineStyle(lineweight, myColour);
      this.graphics.lineTo(0, -linelen);

      }

   }
}

The parameters we pass to the class are

_theBoss – a link back to the root Tree class

_level – the level down the tree (for the trunk this will be 1)

The rest of the constructor function then picks a random colour and draws two circles and a line between them, to create a barbell type shape. You can run you fla at this point and you should be able to see the shape you have drawn as the trunk.

Fractal Recursion

Next up, time to get recursive. Declare a private variable _children of type ‘Array’ on the Branch class,

private var _children:Array;

then add some further code to the constructor of the Branch.as class.

if (_level < _theBoss.maxlevel) {
   _children = new Array();
   for (var x:Number = 0; x<_theBoss.children; x++) {
      var childBranch:Branch = new Branch(_theBoss, _level+1);
      childBranch.x = 0;
      childBranch.y = -linelen;
      addChild(childBranch);
      _children.push(childBranch);
   }
}

To avoid infinite recursion we check with _theBoss to see if we are allowed to generate children below this level. If we have permission we loop through the number of children we are allowed to generate (again, getting this info from _theBoss), and create a new child of type Branch.

We move this to the end of the tip of the current branch (0, -linelen), add it to the array of this branch’s children, and call addChild() to add it to the display list for this branch.

Now if you publish the fla you should see a chain of 5 barbells, stretching vertically. You can’t see how many children each node has got because they are overlaying each other, so add this line (still within the Branch constructor function) to rotate each of our branches by a random amount.

this.rotation = Math.floor(Math.random() * 360) - 180;

And while you’re at it, replace the declarations of rad, linelen, and lineweight, with the following:

var rad:Number = (_theBoss.maxlevel - _level) * 5;
var linelen:Number = (_theBoss.maxlevel - _level) * 20;
var lineweight:Number = (_theBoss.maxlevel - _level);

This will cause each generation of the Branch to scale downwards in size. The complete Branch class should now read as follows:

package com.zenbullets.fractals.tutorial
{
import flash.display.Sprite;

public class Branch extends Sprite
{

   private var _theBoss:Tree;
   private var _level:Number;
   private var _children:Array;

   //====== constructor

   public function Branch (controller:Tree, l:Number) {
      _theBoss = controller;
      _level = l;

      // pick a random colour
      var myColour:Number = Math.floor(Math.random()*0xFFFFFF);

      // scale according to level
      var rad:Number = (_theBoss.maxlevel - _level) * 5;
      var linelen:Number = (_theBoss.maxlevel - _level) * 20;
      var lineweight:Number = (_theBoss.maxlevel - _level);

      // draw the barbell
      this.graphics.beginFill(myColour);
      this.graphics.drawCircle(0, 0, rad);
      this.graphics.endFill();

      this.graphics.beginFill(myColour);
      this.graphics.drawCircle(0, -linelen, rad);
      this.graphics.endFill();

      this.graphics.moveTo(0,0);
      this.graphics.lineStyle(lineweight, myColour);
      this.graphics.lineTo(0, -linelen);

      // create children
      if (_level < _theBoss.maxlevel) {
         _children = new Array();
         for (var x:Number = 0; x < _theBoss.children; x++) {
            var childBranch:Branch = new Branch(_theBoss, _level+1);
            childBranch.x = 0;
            childBranch.y = -linelen;
            addChild(childBranch);
            _children.push(childBranch);
         }
      }

      // random initial rotation
      this.rotation = Math.floor(Math.random() * 360) - 180;
      }

   }
}

Publish the fla now, and you should see something like this:

Making It Move

So far so good, now lets get it moving. Going back to the Tree class, add a timed function:

package com.zenbullets.fractals.tutorial
{

import flash.display.MovieClip;
import flash.display.Sprite;
import flash.utils.Timer;
import flash.events.TimerEvent;

public class Tree extends MovieClip {

   // number of children each branch can have
   private static const CHILDREN:Number = 3;
   // depth to recurse down to
   private static const MAXLEVEL:Number = 5;

   private var _timer:Timer;

      // the seed sprite to our fractal
      private var _trunk:Sprite;

      //====== constructor

      public function Tree () {

         _trunk = new Branch(this, 1);
         _trunk.x = 200;
         _trunk.y = 200;
         addChild(_trunk);

         _timer = new Timer(100);
         _timer.addEventListener(TimerEvent.TIMER, controlLoop);
         _timer.start();
      }

      //====== getters/setters

      public function get children():String { return CHILDREN; }
      public function get maxlevel():String { return MAXLEVEL; }

       //====== private functionality - timed loop

      private function controlLoop(event:TimerEvent):void {
        _trunk.update();
      }

   }
}

Then add the following function to Branch.as:

public function update():void {
   if (_children) {
      for each (var child in _children) { child.update(); }
   }
   this.rotation += 1;
}

Each update will rotate each branch by a degree. Note how the timed loop only updates the top (bottom?) of the tree, the rest trickles down.

The final thing I’m going to do is rig the code so it doesn’t draw the trunk:

if (_level > 1) {
  // draw the barbell
  this.graphics.beginFill(myColour);
  this.graphics.drawCircle(0, 0, rad);
  this.graphics.endFill();
  this.graphics.beginFill(myColour);
  this.graphics.drawCircle(0, -linelen, rad);
  this.graphics.endFill();
  this.graphics.moveTo(0,0);
  this.graphics.lineStyle(lineweight, myColour);
  this.graphics.lineTo(0, -linelen);
}

This isn’t strictly necessary, but it looks nice – it gives the impression your fractal has been set adrift, while still keeping it tethered by an invisible rotating string.

By now, your fla should look like this:

Onward

If you’ve made it this far, well done. This is where I’m going to leave you, because this is where it gets interesting. Now you’ve got the fractal framework, what you do with it is up to you. To instruct you any further would be to stifle your creativity.

First thing you’ll want to do is go back to the Tree class and (cautiously) up the CHILDREN and MAXLEVEL values. Then experiment with adding visual modifications to the constructor and/or the update function.

Obviously, your shape doesn’t have to be a barbell, nor does it have to branch at the end. It is not uncommon for fractals to bifurcate in the middle or along an edge. Take a look at the daddy of the fractal world, the mandelbrot set, if you need inspiration.

Returning to the example at the top of this page, it isn’t very far removed from the barbell fractal that we’ve just built. All I have done is apply some alpha, randomise the direction of rotation, and add an x and y scaling factor to the update. But you can come up with something better than that. Post your links below and let me know how you get on.

Matt Pearson – May 2007



posted May 15th, 2007





Alessio said...

Woah ! I love these kind of things !
I will try them with flash but I know it will be difficult because I am a beginner.
Thanks for this tutorial :D


Max said...

Hi,

I am very much interested in Fractals and would really like to have this animation. I am a beginner in Flash action scripting. I tried your code and there is no way I can make it work. Flash keeps giving me syntax error message. It would be nice if you could have your code available as a file to download.

Thanks


wiz said...

I’m trying to reproduce this, but I can’t seem to figure it out. I think my problem lies that I don’t know how to import the classes in the fla file.
I thought this is just plain easy by using:

import Tree;
import Branch;

but it doesn’t work. As Max asked here above: would it be possible to just upload a zip file with all the files included? That should be a big help.

btw, sorry for this noob request :)


zenbullets said...

In AS3 you don’t import scripts to the fla, you associate classes with either the document or objects in the library. When I built this demo the Tree class was the document class for the fla (which is defined in ActionScript settings). See here for more info.

Hope this helps.


Roderic Lilley said...

Why do I get this error ?

Call to a possible undefined method update through a reference with static type flash.display:Sprite

Source : _trunk.update();

Works fine till the movement part code is exactly the same as yours, would like to get this going so I can experiment with it ? Help !


rybaxs said...

wow.. so nice.. i love this blog..


Burnhard said...

Hello Mr. Pearson,
thanks for publishing this nice tutorial. It´s so inspiring, I´d love to start playing with it. Unfortunately I get the same error as Mr Lilley after adding the timed function:
Call to a possible undefined method update through a reference with static type flash.display:Sprite
Source : _trunk.update();
Please let us know if you have any idea how to get it work.


bluy brink said...

try to change

// the seed sprite to our fractal
private var _trunk:Sprite;

into
// the seed sprite to our fractal
private var _trunk:Branch;

Reboottees said...

I get these error messages in Branch.as:
Description: 1067: Implicit coercion of a value of type String to an unrelated type Number.


Mark H said...

I’m working on a similar project at the moment, but I’m, stuck on some simple( I hope) referencing issues.

I have a sprite class that draws itself then spawns a rotated copy of itself (only one copy). I want each child item to draw a line connecting to a fixed point on the boundary of the parent.

I’ve played around with passing points and using localToGobal to get the reference back I need, but no luck. Maybe I bit off too much as a first AS3 project :)


Exey said...

wiz, Roderic Lilley, Burnhard, Reboottees
Publish Setting > Settings > Uncheck “Strict Mode”


JamPS said...

// the seed sprite to our fractal needs to be:
private var _trunk:Branch;


JamPS said...

(lol where the hell did I get an outdated version of these comments and didn’t see that problem is already solved)


MikouRoux said...

Ok, I just found a little error in the code.
I don’t understand why nobody related to it before !

Here, your get variables are typed as a String.

public function get children():String { return CHILDREN; }
public function get maxlevel():String { return MAXLEVEL; }

It should be a Number :
public function get children():Number { return CHILDREN; }
public function get maxlevel():Number { return MAXLEVEL; }

I don’t understand how you made it work without correcting this thing.

Very nice tuto. THANKS ;)


admin said...

Thanks for all your comments, particularly the corrections to the code. Is it worth me going back and updating the code? Probably not. Lets just pretend they were intentional to test if you were paying attention ;)


dreamingoflions said...

Hey there,

your tutorial is absolitley gorgeous.

I have been trying to recreate it but I keep on getting this error: “5007: An Actionscript file must have at least one externally visible definition”when I try to load my Main.as in which the Branch.as and Tree.as are imported to.

I feel I am really close but can’t figure out what is causing it. Also in my script to import the “import com.zenbullets.fractals.tutorial.Branch;” Branch will not highlight blue but the directory is correct….

Any advice is really appreciated!


shyam said...

can somebody please upload a zip file with a finished source of this tutorial?? i keep getting all sorts of error codes. I have the classes imported into my fla file and when i create the first instance of the Branh i get this error.

ArgumentError: Error #2004: One of the parameters is invalid.
at flash.display::Graphics/drawRoundRect()
at flash.display::Graphics/drawCircle()
at com.fractals::Branch$iinit()
at Trees/::frame1()

and i cant make any sense of why this is happening.. any help? or a completed version would be a great help,, i love this effect and really want to see it working on my screen…




Add your comment



pingback: natureandtech: Fractals in Nature

pingback: Flash Fractals

pingback: How do I approach coding a plant growing animation? - kirupaForum

pingback: Flash CS3 Tutorial - Fractals in AS3 « Flash Enabled Blog

pingback: Blinking ( Fractals in ActionScript 3 - A Flash Tutorial )

pingback: Digg / All News, Videos, & Images / Upcoming

pingback: AS3.0 Fractals Tutorial | Beedigital

pingback: actionscripter.co.uk » Blog Archive » Flash Fractals

pingback: actionscripter.co.uk » Blog Archive » Flash Snapshot Application - an AIR/Flickr/Moo mashup

pingback: plant flash tutorial - Dogpile Web Search

pingback: iTamt.cn » Blog Archive » Fractals????????

pingback: Flash Fractals | zenbullets.com