Actionscript 3 – Fun with isometrics (part2 (with source))

actionscript 3, BitmapData, classes, equalizer, fun, Math

Hi there,

back again with some funny isoStuff.
Here’s an optimized and enhanced version of the previous post, and with source code explained.
It now has dynamic colors and you can choose colors and size (for hi and low values).


See it moving

Ok now some explanation:
The main trick behind this (for who didn’t noticed) is that the code simply redraw at every frame just the first line of blocks. Then simply draw() that first line into a BitmapData that scrolls of a block size… and the trick lives!

Ok, speaking about optimization… two main things:
1. Draw it without a line (just fills) and it goes 2x faster
2. Even that first line (60 pieces only) was not actually so fast…

About this second point the code involved with sine-wave and dynamic colors calculation contains some math equation, but nothing can really send your CPU @100%. The main CPU draining comes from the visual/rendering part.
One solution I implemented in this experiment (and it’s a trick can be used very often) is simply draw into a bitmap even that first line without adding to childList the vector part. With this little trick fps went from 15 to 31 =).

The second thing is simply that you dont really need to redraw every block @ every frame to achive a cool effect. You could just change its y without changing size for a poorer effect but surely faster. However remember that changing y can lead to higher fps but will not be enough if you still move a lot of vector shapes on screen. Draw everything to a bitmap is rule #1 for speed issues.
You could even use slice-9 grids to change the height of a block or use an animation build with 100 frames and simple gotoAndPlay(value) so you don’t have to draw everything programmatically.

Of course you can use this base for everything you need. Display height maps (maybe I’ll be posting a example of this), equalizers etc.

Now comes the code. First you will need the two classes involved.

The classes are not packaged and very simple. Simply extract them in the main dir or package them in some “common classes/com/oaxoa/blabla” folder
This was written very fast so no packaging, don’t expect setters/getters for every parameter or perfectly protected vars etc.

Ok you got the classes, now the main code. Just the first 30 lines are really needed. The rest is just to add and layout the sliders and colorpickers components.

import IsoField;
import com.oaxoa.components.FrameRater;
import fl.controls.ColorPicker;
import fl.controls.Slider;

var minsize:Number=10;
var maxsize:Number=10;
var spacing:Number=10;
var angle:Number=45;
var angleRadians:Number=angle/180*Math.PI;
var isofield:IsoField=new IsoField(1, 60, minsize, maxsize, spacing, angle, 0x00ffff, 0xff9900);

isofield.x=50;
isofield.y=50;

var bd:BitmapData=new BitmapData(800, 600, false, 0xffffff);
var bmp:Bitmap=new Bitmap(bd);

addChild(bmp);
addChild(isofield);

addEventListener(Event.ENTER_FRAME, onframe);

function onframe(event:Event):void {
	isofield.cycle();
	var matrix:Matrix=new Matrix();
	matrix.translate(50, 50);
	bd.draw(isofield, matrix);
	bd.scroll(spacing*Math.sin(angleRadians), -spacing*Math.cos(angleRadians));
}

// Main code end here. Stuff below is just to add sliders, labels and color pickers.

// add the frameRater
var fr:FrameRater=new FrameRater();
addChild(fr);

// add colorpickers
var cp1:ColorPicker=new ColorPicker();
cp1.x=20;
cp1.y=470;
cp1.selectedColor=0x00ffff;
addChild(cp1);
cp1.addEventListener(Event.CHANGE, oncp1);

var cp2:ColorPicker=new ColorPicker();
cp2.x=60;
cp2.y=470;
cp2.selectedColor=0xff9900;
addChild(cp2);
cp2.addEventListener(Event.CHANGE, oncp2);

function oncp1(event:Event):void {
	isofield.mincolor=cp1.selectedColor;
}

function oncp2(event:Event):void {
	isofield.maxcolor=cp2.selectedColor;
}

// add sliders

var slider1:Slider=new Slider();
slider1.minimum=4;
slider1.maximum=10;
slider1.value=10;
slider1.snapInterval=1;
slider1.liveDragging=true;
slider1.x=20;
slider1.y=510;
slider1.addEventListener(Event.CHANGE, onslider1);
addChild(slider1);

var slider2:Slider=new Slider();
slider2.minimum=4;
slider2.value=10;
slider2.maximum=10;
slider2.snapInterval=1;
slider2.liveDragging=true;
slider2.x=20;
slider2.y=540;
slider2.addEventListener(Event.CHANGE, onslider2);
addChild(slider2);

var slider3:Slider=new Slider();
slider3.minimum=-10;
slider3.value=6;
slider3.maximum=10;
slider3.snapInterval=1;
slider3.liveDragging=true;
slider3.x=20;
slider3.y=570;
slider3.addEventListener(Event.CHANGE, onslider3);
addChild(slider3);

var labelStr1:String="Minimum size: ";
var labelStr2:String="Maximum size: ";
var labelStr3:String="Wave speed: ";

function onslider1(event:Event):void {
	sliderLabel1.htmlText=labelStr1+String(slider1.value);
	isofield.minsize=slider1.value;
}

function onslider2(event:Event):void {
	sliderLabel2.htmlText=labelStr2+String(slider2.value);
	isofield.maxsize=slider2.value;
}

function onslider3(event:Event):void {
	sliderLabel3.htmlText=labelStr3+String(slider3.value);
	isofield.xfSpeed=slider3.value/1000;
}

var tf:TextFormat=new TextFormat();
tf.font="_sans";

var sliderLabel1:TextField=new TextField();
sliderLabel1.x=slider1.x+slider1.width+20;
sliderLabel1.y=slider1.y;
sliderLabel1.width=200;
sliderLabel1.selectable=false;
sliderLabel1.defaultTextFormat=tf;
sliderLabel1.htmlText=labelStr1+String(slider1.value);
addChild(sliderLabel1);

var sliderLabel2:TextField=new TextField();
sliderLabel2.x=slider2.x+slider2.width+20;
sliderLabel2.y=slider2.y;
sliderLabel2.width=200;
sliderLabel2.selectable=false;
sliderLabel2.defaultTextFormat=tf;
sliderLabel2.htmlText=labelStr2+String(slider2.value);
addChild(sliderLabel2);

var sliderLabel3:TextField=new TextField();
sliderLabel3.x=slider3.x+slider3.width+20;
sliderLabel3.y=slider3.y;
sliderLabel3.width=200;
sliderLabel3.selectable=false;
sliderLabel3.defaultTextFormat=tf;
sliderLabel3.htmlText=labelStr3+String(slider3.value);
addChild(sliderLabel3);

As usual I do like comments, so if you enjoy this (or not and want your five minutes back) -gogogo- leave one (and subscribe to my feed!) :D

4 Comments

4 Comments

  1. vitaLee  •  Aug 16, 2008 @11:52 am

    I’m glad that i found your blog yesterday. :)
    Keep your good work coming.

  2. joshspoon  •  Aug 26, 2008 @6:49 am

    the source link is broken. Nice work.

  3. Pierluigi Pesenti  •  Aug 26, 2008 @8:24 am

    Tnx for the report, now is correct.

  4. fabien  •  Sep 2, 2008 @11:07 am

    hi ! Really nice work (this one, and your other stuff too)
    Thanks for documenting and sharing your code

Leave a Reply

Allowed tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>