Currently the posts are filtered by: tools
Reset this filter to see all posts.
Layout management for display objects
I am working hard at the next update for www.kineticarm.com. So I didn't have much time for the blog in the last month, sorry for that.
At my latest custom project I had a complex GUI system and the whole Movie had to be resizeable. So a layout manager seemed to be a proper solution. I just wanted to have a system where I define positions and sizes of the GUI objects once and without having to care about it afterwards.
I builded a static Layoutmanager class where I register all objects and a helper class that allows me to define position and size of each object.
Values can be defined absolute and relative as in CSS and referenced to top left and bottom right border.
- all values ending with "px" are absolute
- all values ending width "%" are relative
- all values starting width "-" are referenced to bottom/right border.
- all values starting with "+" or without any sign are referenced to top/left border.
On top of that all properties can be referenced to the stage or other objects as well. So if layout gets really complex it's possible to build unvisible dummy objects to align other objects to it.Here are some Examples:
- // Created an instance from an object from the lib.
- // and adds it to the stage
- var obj1:MovieClip = new Item();
- addChild(obj1);
- // creates a layout object for the added Displayobject
- // The constructor takes the display object
- lit = new LayoutItem(obj1);
- lit.scale = false // the size isn't touched
- lit.x = "90%"; // X pos. is 90% of stage width
- lit.y = "50%"; // Y pos. is 50% of stage height
- Layouter.registerObject(lit); // registers the object to the layoutManager
- // Created an instance from an object from the lib.
- // and adds it to the stage
- var obj2:MovieClip = new Item();
- addChild(obj2);
- // creates a layout object for the added Displayobject
- // The constructor takes the display object
- lit = new LayoutItem(obj2);
- lit.reference = obj1; // values references to obj1
- lit.scale = false // the size isn't touched
- lit.x = "-100px"; // X pos. is 100 pixels left to obj1
- lit.y = "0px"; // Y pos. is obj1.y
- Layouter.registerObject(lit);
The only thing you need to do is to call the static method "arrange" of the LayoutManager everytime you want to rearrange all registered objects. This is mostly done in a function called at the stage's resize event.
Here you can download the source code with some examples.
Depth of Field in flash (DOF)
For my latest game I wanted to simulate DOF in flash. In flash we can apply filters to objects and flash provides a blur filter, this is the base of the work. What we need is a mechanism to coordinate the depths of the objects.
First We build a class that manages everything about DOF. This class needs an array which holds references to all the objects we want to use with DOF. We build a virtual space with the depths of 1 where 0 is the position of the camera and 1 is the point most faraway from the camera. Our class has a function addObject which takes the display object and a depths in our virtual space. Next our class has got a property maxBlur that defines how strong the maximum blur effect will be. And of course there is a property focus which defines the current focus.
In my game I needed the effect animated, so I added a main function which manipulates the focus and recalculates the blur effect for each object.
- package at.lueftenegger.dof {
- import at.lueftenegger.dof.operator.Operator;
- import flash.display.DisplayObject;
- import flash.filters.BlurFilter;
- public class Dof{
- public var maxBlur:Number = 5;
- private var _focus:Number = 0; // 0 -> 1
- private var last_focus:Number;
- public var operator:Operator;
- public function Dof(){
- objects = new Array();
- operator = new Operator();
- }
- protected var objects:Array;
- public function set focus(value:Number):void {
- _focus = value;
- render();
- }
- public function addLayer( object:DisplayObject, position:Number ):void {
- if (position < 0) position = 0;
- if (position > 1) position = 1;
- var l:Layer = new Layer();
- l.dispObj = object;
- l.position = position;
- objects.push(l);
- }
- public function main():void {
- _focus = operator.giveFocusValue();
- if(_focus == last_focus) return;
- render();
- last_focus = _focus;
- }
- private function render():void {
- for ( var i:String in objects) {
- var h:Number = ( (objects[i].position - _focus) < 0 ) ? -(objects[i].position - _focus) : (objects[i].position - _focus);
- var blur:Number = h * maxBlur;
- var filter:BlurFilter = new BlurFilter( blur, blur, 1 );
- var filterss:Array = [];
- filterss.push(filter);
- objects[i].dispObj.filters = filterss;
- }
- }
- }
- }
- package at.lueftenegger.dof{
- import flash.display.DisplayObject;
- public class Layer{
- public var position:Number;
- public var dispObj:DisplayObject;
- }
- }
- package at.lueftenegger.dof.operator{
- public class Operator{
- public function Operator(speed:Number = 0.15){
- }
- public function giveFocusValue():Number {
- return 0.5;
- }
- }
- }
- package at.lueftenegger.dof.operator{
- public class Sinus extends Operator{
- private var speed:Number;
- private var run:Number = 0;
- public function Sinus(speed:Number = 0.15){
- this.speed = speed;
- }
- override public function giveFocusValue():Number {
- run += speed;
- return 0.5 + Math.sin(run) * 0.5;
- }
- }
- }
How to use it
- Create a new FLA file.
- Put some MovieClips on screen and give them names.
- Add the following script.
- var dof:Dof = new Dof();
- dof.operator = new Sinus(0.1);
- dof.maxBlur = 10;
- dof.addLayer( getChildByName("object1"),0);
- dof.addLayer( getChildByName("object2"),0.2);
- dof.addLayer( getChildByName("object3"),0.4);
- dof.addLayer( getChildByName("object4"),0.6);
- dof.addLayer( getChildByName("object5"),0.8);
- dof.focus = 0.4;
exporting image sequences
If there is no reason to keep vector graphics in the swf, I normally replace them with Pngs. The flash player is faster in copying pixels than in drawing curves and lines. So, this brings mostly a better performance. But there are two drawbacks in the flash IDE.
- The export function just animates the main time line. All embedded MCs are standing on their first frame. This results in the fact that you can't export nested animations.
- If parts of the animation are controlled by Actionscript, this parts wont be exported at all.
That was exactly my problem today. And fortunately last week end I started to work with AIR. And in Air2beta you even have the possibility to exit the application after all your work is done. So the logical consequence was to write a pseudo command line tool that creates a proper image sequence of PNGs.(That's why I love to be a programmer, you simply make your solutions.) I call it a pseudo command line tool because you call it from the command line, but air apps are GUI apps, even if you don't need it like in this case.
It's really simple to use: You give it a swf file, an output folder, the size of the images and if you want a name prefix.
This is how a call looks like:
swf2imgseq.exe -if c:\temp\test.swf -of c:\temp\ -width 640 -height 480 -prefix img
I needed that tool quickly to continue with my work, so I didn't take time to implement error checkings.
That means you have:
- to give a proper file path
- the out folder has to end with an slash
- width and height has to be int values
- prefix gets a part of the file name, so your OS gives you some rules about it.
I don't know how the program behaves in case of wrong parameters.
You don't get any warranties and you use it on your own risk.
By the way: I have seen this last week end and I didn't know that. If you install an air app, it will be converted to an .exe file automatically.
download: swf2imgseq.zip
AST for AS3 (AST2)
This time i would like to show you the AS3 version of my ASToolBox. The AS3 version works a bit different than the AS2 version. I have split the whole tool into two components. There is a standalone applikation for all output data and a static class for use in your Flash file.
download: ast2.zip
You can find the installation instructions in the readme file.
To use AST you have to give it a reference to the stage.
- ...
- import at.lueftenegger.ast2.AST;
- ...
- AST.stage = stage;
- ...
- // The output and timer function are the same as in the AS2 version:
- AST.tracelocal("W");
- AST.trace("1");
- AST.clear();
- AST.trace("2");
- AST.traceStage();
- AST.var_dump(
- {
- _string:"Hello world!",
- _int:int(1),
- _uint:uint(2),
- _number:Number(3),
- _bool:Boolean(true),
- _array:[1,2,3],
- _object:{_a:"hello", _b:"world" },
- _nested:[ "a",
- "b",
- { c:"c",
- d:"d",
- e: [ 0,
- 1,
- 2
- ]
- },
- int(1),
- uint(2),
- Number(3)
- ],
- _xml: XML("<a>hello World</a>")
- }
- );
- // timer functions
- var u:Number;
- AST.timer_clear();
- var i:int = 0;
- for(i = 0; i < 10; i++){
- AST.timer_start();
- for(var x:int = 0; x < 1000000; x++)
- u = Math.sin(x)+Math.cos(i)+Math.random()/Math.cos(x);
- AST.timer_stop();
- }
- AST.timer_report();
- AST.timer_avg();
- //timer 2
- AST.timer_clear();
- for( i = 0; i < 3; i++){
- AST.timer_start();
- for( x = 0; x < 1000; x++)
- u = Math.sin(x)+Math.cos(i)+Math.random()/Math.cos(x);
- AST.timer_stop();
- }
- AST.timer_report();
- AST.timer_avg();
- // trace stage
- // this function is new to AST2
- // It gives a tree structure of the displaylist.
- AST.traceStage();
- for(i = 0; i<30; i++)
- addChild( new MovieClip() );
- AST.traceStage();
AST - ASToolBox (AS2)
This time I want to share a tool for all AS2 coders out there.
I wrote it because I needed an easy to use trace tool for my projects written with flashdevelop. At this time trace in flashdevelop wasn't an easy step and I didn't want to read all the tutorials because they simply didn't solve the problems for my installation.
ASToolBox (short ast) is a static class which offers functions for tracing, var_dump and time measurement of code segments.
Installation:
Copy the class source code below in a .as file and safe it in the folder
C:\Dokumente und Einstellungen\[USERNAME]\Lokale Einstellungen\Anwendungsdaten\Adobe\Flash CS4\de\Configuration\Classes\FP8
trace data
To trace data ast offers three functions. Firstly there is trace. It's the most common function in flash, so I think I don't need to explain it.
Secondly there we have var_dump. It takes an Object and traces an analysed string of it. It's an flash equivalent of the PHP function.
And Finally println, it works very similar as the C equivalent, but it doesn't know data types. Everything is handled as a String. Actually it doesn't output anything. It just prepares and returns a string for output.
Additionally to these output functions there is clear, which simply clears the output window.
time measurement
Sometimes you want to measure the time that is taken for a peace of code to be executed. Ast gives you some functions to make this task very simple.
- ast.trace("In europe children get their presents on 24. December in the evening.");
- ast.var_dump({a:1, b:"w", c:["hello", "world"], d:{a:1, b:2, c:3}});
- ast.trace( ast.println("In europe %0 get their presents on %1. December in the evening%2", ["children", 24, "."]) );
- ast.clear();
- var z:Number = 0;
- var finish:Number = 0;
- for( var i:Number = 0; i < 5; i++){
- finish = 1000+Math.random()*10000;
- ast.timer_start();
- for( var a:Number = 0; a < finish; a++)
- z = --z +1;
- ast.timer_stop();
- }
- ast.timer_report();
- ast.timer_avg();
- // if you don't call clear here the measurements
- // above are added to the report below.
- ast.timer_clear();
- var z:Number = 0;
- var finish:Number = 0;
- for( var i:Number = 0; i < 5; i++){
- finish = 1000+Math.random()*10000;
- var handle:Number = ast.timer_start();
- for( var a:Number = 0; a < finish; a++)
- z = --z +1;
- ast.timer_stop(handle2);
- }
- ast.timer_report();
- ast.timer_avg();
Here you can download ast.as


