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;
- 1 Comments



update
Hi!
I have updated the class. Some improvements, inlining math functions. Usage of Object replaced with the Layer class. State pattern added to control the movement of the focus.
michael