[ff]: MicroBitmapRendering (Bresenham Line Implementation / WIP)

by bradsedito forked from Micro Bitmap Rendering: Bresenham Line Implementation (WIP) (diff: 32)
♥0 | Line 283 | Modified 2013-03-15 11:14:58 | MIT License
play

ActionScript3 source code

/**
 * Copyright bradsedito ( http://wonderfl.net/user/bradsedito )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/lpIR
 */






package 
{
    import flash.geom.Rectangle;
    import flash.events.MouseEvent;
    import flash.display.BlendMode;
    import flash.display.LoaderInfo;
    import flash.utils.ByteArray;
    import flash.events.IOErrorEvent;
    import flash.net.URLLoaderDataFormat;
    import flash.net.URLLoader;
    import flash.system.LoaderContext;
    import flash.net.URLRequest;
    import flash.geom.Point;    
    import flash.display.Bitmap;
    import flash.display.Sprite;
    import flash.display.Loader;
    import flash.events.Event;
    import flash.display.BitmapData;
    import net.hires.debug.Stats;
    import flash.external.ExternalInterface;
    import com.greensock.TweenLite;
    import com.greensock.TimelineLite;
    import com.greensock.easing.*;

    
    public class  extends Sprite 
    {       
        private var _engine:BmpEngine;
        private var _children:int  = 6;
        private var _source:Bitmap;
        private var _dots:Array;
        private var _lines:Bmp;
        
        
        public function MicroBitmapRendering() 
        {
            if(stage)     setup();
            else          addEventListener(Event.ADDED_TO_STAGE, setup);
        }
        
        
        private function setup(e:Event = null):void 
        {
            Console.init(this);
            Console.tracer = trace;
            
            load();
        }
        
        
        private function load():void 
        {
            Console.log("load()");
            
            var url:URLRequest = new URLRequest("http://www.jbraccini.com/files/bang.png");
            var loader:Loader = new Loader();
                loader.contentLoaderInfo.addEventListener(Event.COMPLETE, handleImageLoaded);
                loader.load(url, new LoaderContext(true));
        }
        
        
        private function handleImageLoaded(e:Event):void 
        {
            Console.log("handleImageLoaded()");
            _source = e.target.content as Bitmap;
            init();
        }
        
        
        private function init():void 
        {
            Console.log("init()");
            
            var c:Bmp;
            
            _engine = new BmpEngine(stage.stageWidth, 360);
            _engine.addEventListener(BmpEngine.ENTER_RENDER, handleRender);
            _engine.start();
            
            addChild(_engine);
            addChild(new Stats());
            
            stage.addEventListener(MouseEvent.CLICK, handleClick);
            
            ////////////////////////////////////////
            
            _lines = new Bmp(new BitmapData(_engine.width, _engine.height, true, 0x00000000));
            _engine.addChild(_lines);
            
            var alt:Function = function():int { return int(Math.random()*2) - 1 | 1; }
            
            _dots = [];
            for(var i:int = 0; i < _children; i++) {
                c          = new Bmp(_source.bitmapData.clone());
                c.scale    = .5 + (Math.random() * 1.5);
                c.x        = int(Math.random() * (_engine.width - c.width));
                c.y        = int(Math.random() * (_engine.height - c.height));
                
                _dots.push({    c:        c,
                                vx:       (Math.random() * 3) * alt(),
                                vy:       (Math.random() * 3) * alt()
                });
                
                _engine.addChild(c);
            }
        }
                
        private function handleRender(e:Event):void {
            var l:int = _dots.length;
            var d:Object = _dots[0];
            var limit:Rectangle;
            
            _lines.graphics.clear();
            _lines.graphics.moveTo(d.c.x + (d.c.width/2), d.c.y + (d.c.height/2));
            
            for(var i:int = 0; i < l; i++) {
                d = _dots[i];
                limit = new Rectangle(0, 0, _engine.width - d.c.width, _engine.height - d.c.height);
                
                _lines.graphics.lineTo(d.c.x + (d.c.width/2), d.c.y + (d.c.height/2), 0xff550000);
                
                if(d.c.x > limit.width || d.c.x < 0)    d.vx *= -1;
                if(d.c.y > limit.height || d.c.y < 0)   d.vy *= -1;
                
                d.c.x += d.vx;
                d.c.y += d.vy;
            }
        }
        
        private function handleClick(e:MouseEvent):void {
            _lines.graphics.clear();
        }
        
   }

}




import flash.events.EventDispatcher;
import flash.display.BlendMode;
import flash.geom.Matrix;
import flash.events.Event;
import flash.display.DisplayObjectContainer;
import flash.geom.Rectangle;
import flash.geom.Point;
import flash.display.BitmapData;
import flash.display.Bitmap;
import flash.events.TimerEvent;
import flash.utils.Timer;


///////////////////////////////////////////////////////////////////
// MICRO FRAMEWORK ////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////


class BmpContainer extends Bitmap {
    
    public var children:Array;
    
    public function BmpContainer(source:BitmapData) {
        super(source);
        children = [];
    }
    
    public function addChild(child:Bitmap):void {
        children.push(child);
    }
    
    public function removeChild(child:Bitmap):void {
        children.splice(children.indexOf(child), 1);
    }
    
}

class BmpGraphics extends EventDispatcher {
    
    private var _source:BitmapData;
    private var _o:BitmapData;
    private var _origin:Point;
    
    public function BmpGraphics(source:BitmapData) {
        _source = source;
        _o = _source.clone();
        super();
        
        init();
    }
    
    private function init():void {
        _origin = new Point();
    }
    
    // Bersenham Line Algorithm
    private function computeLine(x:int, y:int):Array {
        var points:Array = [];
        var x0:int = _origin.x;
        var y0:int = _origin.y;
        var dx:int = Math.abs(x0 - x);
        var dy:int = Math.abs(y0 - y);
        var sx:int = x0 < x ? 1 : -1;
        var sy:int = y0 < y ? 1 : -1;
        var e:int  = dx - dy;
        var e2:int;

        while(true) {
            points.push(_origin.clone());
            
            if(_origin.x == x && _origin.y == y) break;
            
            e2 = e * 2;
            if (e2 > -dx) {
                e -= dy;
                _origin.x += sx;
            }
            if (e2 < dx) {
                e += dx;
                _origin.y += sy;
            }
        }
        
        return points;
    }
    
    public function set source(value:BitmapData):void {
        _source = value;
        _o = _source.clone();
    }
    
    public function get source():BitmapData { return _source; }
    
    /////////////////////////
    
    public function moveTo(x:int, y:int):void {
        _origin = new Point(x, y);
    }
    
    public function lineTo(x:int, y:int, color:uint = 0):void {
        
        var points:Array = computeLine(x, y);
        var p:Point;
        var l:int = points.length;
        for(var i:int = 0; i < l; i++) {
            p = points[i];
            _source.setPixel32(p.x, p.y, color);
        }
    }
    
    public function clear():void {
        _source.copyPixels(_o, _o.rect, new Point());
    }

    
}


class Bmp extends BmpContainer {
    
    private var _graphics:BmpGraphics;
    private var _o:BitmapData;
    private var _scale_f:Number = 1;
    
    public function Bmp(source:BitmapData) {
        _o = source;
        super(_o);
        
        init();
    }
    
    private function init():void {
        _graphics = new BmpGraphics(_o);
    }

    public function set scale(f:Number):void {
        _scale_f = f;
        
        var w:Number       = (_o.width * f) || 1;
        var h:Number       = (_o.height * f) || 1;
        var t:Boolean      = _o.transparent;
        var r:BitmapData   = new BitmapData(w, h, true, 0);
        var m:Matrix       = new Matrix();
        
        m.scale(f, f);
        r.draw(_o, m);
        
        bitmapData         = r;
    }
    
    public function get scale():Number { return _scale_f; }
    
    public function get graphics():BmpGraphics {
        return _graphics;
    }
    
    override public function set bitmapData(source:BitmapData):void {
        super.bitmapData = _graphics.source = source;
    }

}


class BmpEngine extends Bmp {
    
    public static var ENTER_RENDER:String = "enterRender";
    
    private var _clock:Timer;
    private var _initied:Boolean = false;
    private var _source:BitmapData;
    
    public function BmpEngine(w:Number, h:Number) {
        _source = new BitmapData(w, h, false, 0);
        super(_source);
        init();
    }
    
    public function start():void {
        if(_initied) _clock.start();
    }

    public function stop():void {
       if(_initied) _clock.stop();
    }    
    
    public function forceRender():void {
        render();
    }

    
    // PRIVATE
    
    private function init():void {
        _clock = new Timer(33);
        _clock.addEventListener(TimerEvent.TIMER, handleTick);
        
        _initied = true;
    }
    
    private function render():void {
        dispatchEvent(new Event(BmpEngine.ENTER_RENDER));
        
        _source = new BitmapData(_source.width, _source.height, false, 0x000000);
        
        var child:Bitmap;
        var t:int = children.length;
        for(var i:int = 0; i < t; i++) {
            child = children[i];
            _source.copyPixels(child.bitmapData, new Rectangle(0, 0, child.width, child.height), new Point(child.x, child.y));
            bitmapData = _source;
        }
    }

    
    private function handleTick(e:TimerEvent):void {
        render();
    }

}


/////////////////////////////////////////////////////////////////
// TRACE ////////////////////////////////////////////////////////


class Console {
    public static var tracer:Function;
    public static function init(s:DisplayObjectContainer):void {
        inittrace(s);
    }

    public static function log(s:*):void {
       if(tracer != null) tracer(s); 
    }
}

class Force {}


import flash.display.Sprite;
import com.bit101.components.TextArea;
var textarea:TextArea;
function inittrace(mainRef:DisplayObjectContainer):void {
    textarea = new TextArea();
    textarea.editable = false;
    textarea.width = mainRef.stage.stageWidth;
    textarea.height = 100;
    textarea.y = mainRef.stage.stageHeight - textarea.height;
    mainRef.addChild(textarea);
}

function doTrace(...args):void {
    var s:String = "";
    for each(var field:* in args) s += field.toString()+" ";
    s+="\n";    
    textarea.text = s + (textarea.text || "");
}
var trace:Function = doTrace;