Fl015.as (Main)

/**
 * @date    30/10/2008
 * @version 1.1
 * @author    borealkiss    
 * @see     http://blog.boreal-kiss.com/
 * 
 * Note the original source comes from 
 * "OldSchool Tunnel-class for Flash 10" by Petri Leskinen.
 * @see http://pixelero.wordpress.com/ 
 */
package {
    import flash.display.Sprite;
    import flash.events.Event;
    import com.borealkiss.display.Tunnel;
    import com.borealkiss.display.CheckPattern;

    public class Fl015 extends Sprite{
        private var _tunnel:Tunnel;
        private var _count:Number;
        
        public function Fl015(){
            _tunnel = new Tunnel(new CheckPattern(400,400,25,25,0x00FFFF,0xFF00FF));
            _tunnel.x = stage.stageWidth/2;
            _tunnel.y = stage.stageHeight/2;
            addChild(_tunnel);
            addEventListener(Event.ENTER_FRAME,onEnterFrame);
            _count = 0;
        }
        
        private function onEnterFrame(e:Event):void{
            _count += 0.03;
            
            var sin:Number = Math.sin(_count);
            _tunnel.xBending = 0.02*(sin - Math.cos(2.5*_count));
            _tunnel.yBending = 0.01*(Math.sin(2.5*_count) + sin);
            _tunnel.update();
        }
    }
}

com.borealkis.display.Tunnel.as

/**
 * @date    30/10/2008
 * @version 1.1
 * @author    borealkiss    
 * @see     http://blog.boreal-kiss.com/
 * 
 * Note the original source comes from 
 * "OldSchool Tunnel-class for Flash 10" by Petri Leskinen.
 * @see http://pixelero.wordpress.com/ 
 */
package com.borealkiss.display{
    import flash.events.Event;
    import flash.display.Sprite;
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.TriangleCulling;
    import flash.geom.Point;
    import flash.geom.Matrix3D;
    import flash.geom.Vector3D;
    import flash.geom.Utils3D;
    import flash.geom.PerspectiveProjection;    
    import com.borealkiss.display.primitives.Cone;
    import com.borealkiss.display.primitives.Primitive;
    
    public class Tunnel extends Sprite{
        private var _texture:BitmapData;
        private var _primitive:Primitive;
        private var _verts:Vector.<Number>;
         private var _uvtData:Vector.<Number>;
         private var _indices:Vector.<int>;
        private var _projectedVerts:Vector.<Number>;
        private var _projectionMatrix:Matrix3D;
        private var _bendedVerts:Vector.<Number>;
        private var _xBending:Number;
        private var _yBending:Number;
        
        //Corresponds to the primitive's nMax parameter. Must be tuned.
        private const MAGIC_NUMBER:Number = 20;
        
        /**
         * Constructor
         */ 
        public function Tunnel(sourceBitmapData:BitmapData=null){
            this.texture = sourceBitmapData;
            this.xBending = 0;
            this.yBending = 0;
            init();
        }
        
        private function init():void{            
            _primitive = new Cone();
            _verts = _primitive.verts;
            _uvtData = _primitive.uvtData;
            _indices = _primitive.indices;
            
            var pp:PerspectiveProjection= new PerspectiveProjection();
            pp.fieldOfView = 60;
            _projectionMatrix = pp.toMatrix3D();
        }
        
        public function update():void{
            //Must be initialized at each update event.
            _projectedVerts = new Vector.<Number>();
            _bendedVerts = new Vector.<Number>();
            
            doBend();
            doMove(0.01,0.01);
            Utils3D.projectVectors(_projectionMatrix,_bendedVerts,_projectedVerts,_uvtData);
            draw();
        }
        
        //Bend the cone
        private function doBend():void{
            var iMax:int = _verts.length;
            for (var i:int=0; i<iMax; i+=3){
                var x:Number = _verts[i];
                var y:Number = _verts[i+1];
                var z:Number = _verts[i+2];
                var fz:Number = (z - 1)*(z - MAGIC_NUMBER);
                
                _bendedVerts[i]     = x + _xBending*fz;
                _bendedVerts[i+1]     = y + _yBending*fz;
                _bendedVerts[i+2]     = z;
            }
        }
        
        //Shift the texture's uvt-data.
        private function doMove(amountX:Number=0,amountY:Number=0):void {
            var iMax:int = _uvtData.length;
            for (var i:int=0; i<iMax; i+=3) {
                _uvtData[i] += amountX;        //X-component in uvt-data.
                _uvtData[i+1] += amountY;    //Y-component in uvt-data.
            }
        }
        
        //Draw the primitive without indices.
        private function draw():void{
            this.graphics.clear();
            this.graphics.beginBitmapFill(_texture);
            this.graphics.drawTriangles(_projectedVerts,null,_uvtData,TriangleCulling.NEGATIVE);
            this.graphics.endFill();
        }
        
        public function set xBending(value:Number):void{
            _xBending = value;
        }
        
        public function set yBending(value:Number):void{
            _yBending = value;
        }
        
        public function set texture(sourceBitmapData:BitmapData):void{
            _texture = sourceBitmapData;
        }
        
        public function get texture():BitmapData{
            return _texture;
        }
    }
}

com.borealkis.display.primitives.Primitive.as (Abstract)

package com.borealkiss.display.primitives{
    /**
     * Abstract class
     */ 
    public class Primitive{
        protected var _verts:Vector.<Number>;
        protected var _uvtData:Vector.<Number>;
        protected var _indices:Vector.<int>;
        
        /**
         * Constructor
         */     
        public function Primitive(){
            _verts = new Vector.<Number>();
            _uvtData = new Vector.<Number>();
            _indices = new Vector.<int>();
            init();
        }
        
        protected function init():void{
            //Must be overridden in a subclass.
        }
        
        public function get verts():Vector.<Number>{
            return _verts;
        }
        
        public function get indices():Vector.<int>{
            return _indices;
        }
        
        public function get uvtData():Vector.<Number>{
            return _uvtData;
        }
    }
}

com.borealkis.display.primitives.Cone.as

package com.borealkiss.display.primitives{
    import com.borealkiss.display.primitives.Primitive;
    
    public class Cone extends Primitive{
        private var _radius:Number;
        private var _nMax:int;
        private var _mMax:int;
        
        //For mathematical configuration. Must be tuned.
        private const Z_AMPLITUDE:Number = 1;
        private const Z_OFFSET:Number = 20;
        private const DECAY:Number = 5;
        
        /**
         * Constructor
         * 
         * @param radius Maximum radius of the primitive.
         * @param nMax Maximum partition mumber of polygon along radial angle.
         * @param nMax Maximum partition mumber of polygon along z-axis.
         */ 
        public function Cone(radius:Number=20, nMax:int=20, mMax:int=20){
            _radius = radius;
            _nMax = nMax;
            _mMax = mMax;
            super();
        }
        
        override protected function init():void{
            for (var n:int=_nMax; n>0; n--){
                for (var m:int=0; m<_mMax; m++){
                    var r0:Number = radius(n);
                    var r1:Number = radius(n-1);
                    var theta0:Number = 2*Math.PI*m/_mMax;
                    var theta1:Number = 2*Math.PI*(m+1)/_mMax;
                    
                    var x0:Number = r0*Math.cos(theta0);
                    var y0:Number = r0*Math.sin(theta0);
                    var z0:Number = n*Z_AMPLITUDE + Z_OFFSET;
                    var uvtX0:Number = m/_mMax;
                    var uvtY0:Number = n/_nMax;
                    
                    var x1:Number = r1*Math.cos(theta0);
                    var y1:Number = r1*Math.sin(theta0);
                    var z1:Number = (n-1)*Z_AMPLITUDE + Z_OFFSET;
                    var uvtX1:Number = m/_mMax;
                    var uvtY1:Number = (n-1)/_nMax;
                    
                    var x2:Number = r1*Math.cos(theta1);
                    var y2:Number = r1*Math.sin(theta1);
                    var z2:Number = (n-1)*Z_AMPLITUDE + Z_OFFSET;
                    var uvtX2:Number = (m+1)/_mMax;
                    var uvtY2:Number = (n-1)/_nMax;
                    
                    var x3:Number = r0*Math.cos(theta1);
                    var y3:Number = r0*Math.sin(theta1);
                    var z3:Number = n*Z_AMPLITUDE + Z_OFFSET;
                    var uvtX3:Number = (m+1)/_mMax;
                    var uvtY3:Number = n/_nMax;
                    
                    super._verts.push(x0,y0,z0, x1,y1,z1, x2,y2,z2, x0,y0,z0, x2,y2,z2, x3,y3,z3);
                    
                    //T-value is also assigned for the usage of Utils3D.projectVectors()
                    super._uvtData.push(uvtX0,uvtY0,0, uvtX1,uvtY1,0, 
                                  uvtX2,uvtY2,0, uvtX0,uvtY0,0, uvtX2,uvtY2,0, uvtX3,uvtY3,0);
                }
            }
        }
        
        //Radius of the cone decreases exponentially toward its top.
        private function radius(z:Number):Number{
            return _radius*Math.exp(-z*DECAY/_nMax);
        }    
    }
}

com.borealkis.display.CheckPattern.as

/**
 * @date    28/10/2008
 * @version 1.0
 * @author    borealkiss    
 * @link     http://blog.boreal-kiss.com/
 */
package com.borealkiss.display{
    import flash.display.BitmapData;
    import flash.geom.Rectangle;
    
    /**
     * Makes a check-pattern in a BitmapData class.
     */ 
    public class CheckPattern extends BitmapData{
        private var _width:int;
        private var _height:int;
        private var _rectWidth:int;
        private var _rectHeight:int;
        private var _fillColorFront:uint;
        private var _fillColorBack:uint;
        
        /**
         * Constructor
         * 
         * @param width Width of the BitmapData.
         * @param height Height of the BitmapData.
         * @param rectWidth Width of each rectangle block in the pattern.
         * @param rectHeight Height of each rectangle block in the pattern.
         * @param fillColorFront Foreground color in the pattern.
         * @param fillColorBack Background color in the pattern.
         */ 
        public function CheckPattern(width:int,height:int,rectWidth:int,rectHeight:int,
                                     fillColorFront:uint=0x000000,fillColorBack:uint=0xFFFFFF){
            _width = width;
            _height = height;
            _rectWidth = rectWidth;
            _rectHeight = rectHeight;
            _fillColorFront = fillColorFront;
            _fillColorBack = fillColorBack;
            super(_width,_height,false,_fillColorBack);
            init();
        }
        
        private function init():void{
            super.fillRect(this.rect,_fillColorBack);
            
            var iMax:int = int(_width / _rectWidth);
            var jMax:int = int(_height / _rectHeight);
            
            for (var i:int=0; i<=iMax; i++){
                for (var j:int=0; j<=jMax; j++){
                    var rect:Rectangle = new Rectangle(i*_rectWidth,j*_rectHeight,_rectWidth,_rectHeight);
                    if (isEven(i) && isEven(j) || !isEven(i) && !isEven(j)){
                        super.fillRect(rect,_fillColorFront);
                    }
                }
            }
        }
        
        private function isEven(number:int):Boolean{
            if (number % 2 == 0){
                return true;
            }
            else {
                return false;
            }
        }
        
        public function set rectWidth(value:Number):void{
            _rectWidth = value;
            init();
        }
        
        public function set rectHeight(value:Number):void{
            _rectHeight = value;
            init();
        }
        
        public function set fillColorFront(color:uint):void{
            _fillColorFront = color;
            init();
        }
        
        public function set fillColorBack(color:uint):void{
            _fillColorBack = color;
            init();
        }
    }
}
Powered by blog Boreal Kiss 2008.