forked from: Crystallization

by fukt forked from Crystallization (diff: 2)
♥0 | Line 275 | Modified 2013-02-27 21:57:17 | MIT License
play

ActionScript3 source code

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

// forked from GreekFellows's Crystallization
package {
    import flash.geom.Matrix;
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.geom.Vector3D;
    import flash.events.Event;
    import flash.display.Sprite;
    import net.hires.debug.Stats;
    public class Crystallization extends Sprite {
        public var array:Array;
        public var boxes:Array;
        public var sorted:Array;
        
        public var bitmapData:BitmapData;
        public var bitmap:Bitmap;
        public var sprite:Sprite;
        
        public var core:Sprite;
        
        public const radius:int = 20;
        public const pers:int = 500;
        
        public function Crystallization() {
            stage.quality = "low";
            
            this.x = 465 / 2;
            this.y = 465 / 2;
            this.z = 0;
            
            array = [];
            boxes = [];
            sorted = [];
            
            bitmapData = new BitmapData(465, 465);
            bitmap = new Bitmap(bitmapData);
            bitmap.x = -465 / 2;
            bitmap.y = -465 / 2;
            this.addChild(bitmap);
            
            sprite = new Sprite();
            sprite.x = -465 / 2;
            sprite.y = -465 / 2;
            
            core = new Sprite();
            core.x = 0;
            core.y = 0;
            core.z = 0;
            
            box(0, 0, 0);
            
            var st:Stats = new Stats();
            st.x = -465 / 2;
            st.y = -465 / 2;
            this.addChild(st);
            
            this.addEventListener(Event.ENTER_FRAME, crystallization);
        }
        
        public function crystallization(e:Event):void {
            animation();
            render();
            spin();
            
            crystallize();
        }
        
        public function crystallize():void {
            for (var cri:int = 0; cri < boxes.length; cri++) {
                if (Math.floor(Math.random() * 10) == 0 && boxes.length < 50 && boxes[cri].stopped) {
                    /*
                    if (Math.floor(Math.random() * 10) == 0) box(boxes[cri].vc.x, boxes[cri].vc.y, boxes[cri].vc.z - radius * 2, boxes[cri].vc.x, boxes[cri].vc.y, boxes[cri].vc.z);
                    if (Math.floor(Math.random() * 10) == 0) box(boxes[cri].vc.x, boxes[cri].vc.y, boxes[cri].vc.z + radius * 2, boxes[cri].vc.x, boxes[cri].vc.y, boxes[cri].vc.z);
                    if (Math.floor(Math.random() * 10) == 0) box(boxes[cri].vc.x - radius * 2, boxes[cri].vc.y, boxes[cri].vc.z, boxes[cri].vc.x, boxes[cri].vc.y, boxes[cri].vc.z);
                    if (Math.floor(Math.random() * 10) == 0) box(boxes[cri].vc.x + radius * 2, boxes[cri].vc.y, boxes[cri].vc.z, boxes[cri].vc.x, boxes[cri].vc.y, boxes[cri].vc.z);
                    if (Math.floor(Math.random() * 10) == 0) box(boxes[cri].vc.x, boxes[cri].vc.y - radius * 2, boxes[cri].vc.z, boxes[cri].vc.x, boxes[cri].vc.y, boxes[cri].vc.z);
                    if (Math.floor(Math.random() * 10) == 0) box(boxes[cri].vc.x, boxes[cri].vc.y + radius * 2, boxes[cri].vc.z, boxes[cri].vc.x, boxes[cri].vc.y, boxes[cri].vc.z);
                    */
                    switch (Math.floor(Math.random() *4)) {
                        case 0:
                        box(boxes[cri].vc.x, boxes[cri].vc.y, boxes[cri].vc.z - radius * 2, boxes[cri].vc.x, boxes[cri].vc.y, boxes[cri].vc.z);
                        break;
                        
                        case 1:
                        box(boxes[cri].vc.x, boxes[cri].vc.y, boxes[cri].vc.z + radius * 2, boxes[cri].vc.x, boxes[cri].vc.y, boxes[cri].vc.z);
                        break;
                        
                        case 2:
                        box(boxes[cri].vc.x - radius * 2, boxes[cri].vc.y, boxes[cri].vc.z, boxes[cri].vc.x, boxes[cri].vc.y, boxes[cri].vc.z);
                        break;
                        
                        case 3:
                        box(boxes[cri].vc.x + radius * 2, boxes[cri].vc.y, boxes[cri].vc.z, boxes[cri].vc.x, boxes[cri].vc.y, boxes[cri].vc.z);
                        break;
                        
                        case 4:
                        box(boxes[cri].vc.x, boxes[cri].vc.y - radius * 2, boxes[cri].vc.z, boxes[cri].vc.x, boxes[cri].vc.y, boxes[cri].vc.z);
                        break;
                        
                        case 5:
                        box(boxes[cri].vc.x, boxes[cri].vc.y + radius * 2, boxes[cri].vc.z, boxes[cri].vc.x, boxes[cri].vc.y, boxes[cri].vc.z);
                        break;
                    }
                }
            }
        }
        
        public function animation():void {
            for (var ai:int = 0; ai < boxes.length; ai++) {
                if (!boxes[ai].stopped) {
                    boxes[ai].alpha += (1 - boxes[ai].alpha) / 10;
                    boxes[ai].cv.x += (boxes[ai].vc.x - boxes[ai].cv.x) / 10;
                    boxes[ai].cv.y += (boxes[ai].vc.y - boxes[ai].cv.y) / 10;
                    boxes[ai].cv.z += (boxes[ai].vc.z - boxes[ai].cv.z) / 10;
                    
                    array[ai * 6 + 0].vc = new Vector3D(boxes[ai].cv.x, boxes[ai].cv.y, boxes[ai].cv.z - radius);
                    array[ai * 6 + 1].vc = new Vector3D(boxes[ai].cv.x, boxes[ai].cv.y, boxes[ai].cv.z + radius);
                    array[ai * 6 + 2].vc = new Vector3D(boxes[ai].cv.x - radius, boxes[ai].cv.y, boxes[ai].cv.z);
                    array[ai * 6 + 3].vc = new Vector3D(boxes[ai].cv.x + radius, boxes[ai].cv.y, boxes[ai].cv.z);
                    array[ai * 6 + 4].vc = new Vector3D(boxes[ai].cv.x, boxes[ai].cv.y - radius, boxes[ai].cv.z);
                    array[ai * 6 + 5].vc = new Vector3D(boxes[ai].cv.x, boxes[ai].cv.y + radius, boxes[ai].cv.z);
                    
                    if (boxes[ai].cv.nearEquals(boxes[ai].vc, 2)) {
                        boxes[ai].stopped = true;
                        boxes[ai].alpha = 1;
                        
                        array[ai * 6 + 0].vc = new Vector3D(boxes[ai].vc.x, boxes[ai].vc.y, boxes[ai].vc.z - radius);
                        array[ai * 6 + 1].vc = new Vector3D(boxes[ai].vc.x, boxes[ai].vc.y, boxes[ai].vc.z + radius);
                        array[ai * 6 + 2].vc = new Vector3D(boxes[ai].vc.x - radius, boxes[ai].vc.y, boxes[ai].vc.z);
                        array[ai * 6 + 3].vc = new Vector3D(boxes[ai].vc.x + radius, boxes[ai].vc.y, boxes[ai].vc.z);
                        array[ai * 6 + 4].vc = new Vector3D(boxes[ai].vc.x, boxes[ai].vc.y - radius, boxes[ai].vc.z);
                        array[ai * 6 + 5].vc = new Vector3D(boxes[ai].vc.x, boxes[ai].vc.y + radius, boxes[ai].vc.z);
                    }
                }
            }
        }
        
        public function spin():void {
            core.rotationX += mouseY / 50;
            core.rotationY += mouseX / 50;
        }
        
        public function render():void {
            sorted = [];
            
            sprite.graphics.clear();
            
            for (var i:int = 0; i < array.length; i++) {
                sorted.push({vc:array[i].vc, type:array[i].type, color:array[i].color, alpha:boxes[array[i].bi].alpha, z:core.transform.matrix3D.transformVector(array[i].vc).z});
            }
            
            sorted.sortOn("z", Array.NUMERIC|Array.DESCENDING);
            
            sprite.graphics.beginFill(0xffffff, 1);
            sprite.graphics.drawRect(0, 0, 465, 465);
            sprite.graphics.endFill();
            
            drawfaces();
            
            drawfaces(true);
            
            bitmapData.draw(sprite);
        }
        
        public function drawfaces(shadeMode:Boolean = true):void {
            for (var j:int = 0; j < sorted.length; j++) {
                sprite.graphics.beginFill(sorted[j].color, sorted[j].alpha);
                                
                var v1:Vector3D = new Vector3D();
                var v2:Vector3D = new Vector3D();
                var v3:Vector3D = new Vector3D();
                var v4:Vector3D = new Vector3D();
                
                switch (sorted[j].type) {
                    case "front":
                    
                    case "back":
                    v1 = core.transform.matrix3D.transformVector(new Vector3D(sorted[j].vc.x - radius, sorted[j].vc.y - radius, sorted[j].vc.z));
                    v2 = core.transform.matrix3D.transformVector(new Vector3D(sorted[j].vc.x + radius, sorted[j].vc.y - radius, sorted[j].vc.z));
                    v3 = core.transform.matrix3D.transformVector(new Vector3D(sorted[j].vc.x + radius, sorted[j].vc.y + radius, sorted[j].vc.z));
                    v4 = core.transform.matrix3D.transformVector(new Vector3D(sorted[j].vc.x - radius, sorted[j].vc.y + radius, sorted[j].vc.z));
                    
                    v1.w = (v1.z + pers) / pers;
                    v2.w = (v2.z + pers) / pers;
                    v3.w = (v3.z + pers) / pers;
                    v4.w = (v4.z + pers) / pers;
                    
                    v1.project();
                    v2.project();
                    v3.project();
                    v4.project();
                    
                    sprite.graphics.moveTo(v1.x + 465 / 2, v1.y + 465 / 2);
                    sprite.graphics.lineTo(v2.x + 465 / 2, v2.y + 465 / 2);
                    sprite.graphics.lineTo(v3.x + 465 / 2, v3.y + 465 / 2);
                    sprite.graphics.lineTo(v4.x + 465 / 2, v4.y + 465 / 2);
                    sprite.graphics.lineTo(v1.x + 465 / 2, v1.y + 465 / 2);
                    break;
                    
                    case "left":
                    
                    case "right":
                    v1 = core.transform.matrix3D.transformVector(new Vector3D(sorted[j].vc.x, sorted[j].vc.y - radius, sorted[j].vc.z - radius));
                    v2 = core.transform.matrix3D.transformVector(new Vector3D(sorted[j].vc.x, sorted[j].vc.y - radius, sorted[j].vc.z + radius));
                    v3 = core.transform.matrix3D.transformVector(new Vector3D(sorted[j].vc.x, sorted[j].vc.y + radius, sorted[j].vc.z + radius));
                    v4 = core.transform.matrix3D.transformVector(new Vector3D(sorted[j].vc.x, sorted[j].vc.y + radius, sorted[j].vc.z - radius));
                    
                    v1.w = (v1.z + pers) / pers;
                    v2.w = (v2.z + pers) / pers;
                    v3.w = (v3.z + pers) / pers;
                    v4.w = (v4.z + pers) / pers;
                    
                    v1.project();
                    v2.project();
                    v3.project();
                    v4.project();
                    
                    sprite.graphics.moveTo(v1.x + 465 / 2, v1.y + 465 / 2);
                    sprite.graphics.lineTo(v2.x + 465 / 2, v2.y + 465 / 2);
                    sprite.graphics.lineTo(v3.x + 465 / 2, v3.y + 465 / 2);
                    sprite.graphics.lineTo(v4.x + 465 / 2, v4.y + 465 / 2);
                    sprite.graphics.lineTo(v1.x + 465 / 2, v1.y + 465 / 2);
                    break;
                    
                    case "up":
                    
                    case "down":
                    v1 = core.transform.matrix3D.transformVector(new Vector3D(sorted[j].vc.x - radius, sorted[j].vc.y, sorted[j].vc.z - radius));
                    v2 = core.transform.matrix3D.transformVector(new Vector3D(sorted[j].vc.x - radius, sorted[j].vc.y, sorted[j].vc.z + radius));
                    v3 = core.transform.matrix3D.transformVector(new Vector3D(sorted[j].vc.x + radius, sorted[j].vc.y, sorted[j].vc.z + radius));
                    v4 = core.transform.matrix3D.transformVector(new Vector3D(sorted[j].vc.x + radius, sorted[j].vc.y, sorted[j].vc.z - radius));
                    
                    v1.w = (v1.z + pers) / pers;
                    v2.w = (v2.z + pers) / pers;
                    v3.w = (v3.z + pers) / pers;
                    v4.w = (v4.z + pers) / pers;
                    
                    v1.project();
                    v2.project();
                    v3.project();
                    v4.project();
                    
                    sprite.graphics.moveTo(v1.x + 465 / 2, v1.y + 465 / 2);
                    sprite.graphics.lineTo(v2.x + 465 / 2, v2.y + 465 / 2);
                    sprite.graphics.lineTo(v3.x + 465 / 2, v3.y + 465 / 2);
                    sprite.graphics.lineTo(v4.x + 465 / 2, v4.y + 465 / 2);
                    sprite.graphics.lineTo(v1.x + 465 / 2, v1.y + 465 / 2);
                    break;
                }
                
                sprite.graphics.beginFill(0x000000, (sorted[j].z + 100) / 200 * sorted[j].alpha);
                
                switch (sorted[j].type) {
                    case "front":
                    
                    case "back":
                    v1 = core.transform.matrix3D.transformVector(new Vector3D(sorted[j].vc.x - radius, sorted[j].vc.y - radius, sorted[j].vc.z));
                    v2 = core.transform.matrix3D.transformVector(new Vector3D(sorted[j].vc.x + radius, sorted[j].vc.y - radius, sorted[j].vc.z));
                    v3 = core.transform.matrix3D.transformVector(new Vector3D(sorted[j].vc.x + radius, sorted[j].vc.y + radius, sorted[j].vc.z));
                    v4 = core.transform.matrix3D.transformVector(new Vector3D(sorted[j].vc.x - radius, sorted[j].vc.y + radius, sorted[j].vc.z));
                    
                    v1.w = (v1.z + pers) / pers;
                    v2.w = (v2.z + pers) / pers;
                    v3.w = (v3.z + pers) / pers;
                    v4.w = (v4.z + pers) / pers;
                    
                    v1.project();
                    v2.project();
                    v3.project();
                    v4.project();
                    
                    sprite.graphics.moveTo(v1.x + 465 / 2, v1.y + 465 / 2);
                    sprite.graphics.lineTo(v2.x + 465 / 2, v2.y + 465 / 2);
                    sprite.graphics.lineTo(v3.x + 465 / 2, v3.y + 465 / 2);
                    sprite.graphics.lineTo(v4.x + 465 / 2, v4.y + 465 / 2);
                    sprite.graphics.lineTo(v1.x + 465 / 2, v1.y + 465 / 2);
                    break;
                    
                    case "left":
                    
                    case "right":
                    v1 = core.transform.matrix3D.transformVector(new Vector3D(sorted[j].vc.x, sorted[j].vc.y - radius, sorted[j].vc.z - radius));
                    v2 = core.transform.matrix3D.transformVector(new Vector3D(sorted[j].vc.x, sorted[j].vc.y - radius, sorted[j].vc.z + radius));
                    v3 = core.transform.matrix3D.transformVector(new Vector3D(sorted[j].vc.x, sorted[j].vc.y + radius, sorted[j].vc.z + radius));
                    v4 = core.transform.matrix3D.transformVector(new Vector3D(sorted[j].vc.x, sorted[j].vc.y + radius, sorted[j].vc.z - radius));
                    
                    v1.w = (v1.z + pers) / pers;
                    v2.w = (v2.z + pers) / pers;
                    v3.w = (v3.z + pers) / pers;
                    v4.w = (v4.z + pers) / pers;
                    
                    v1.project();
                    v2.project();
                    v3.project();
                    v4.project();
                    
                    sprite.graphics.moveTo(v1.x + 465 / 2, v1.y + 465 / 2);
                    sprite.graphics.lineTo(v2.x + 465 / 2, v2.y + 465 / 2);
                    sprite.graphics.lineTo(v3.x + 465 / 2, v3.y + 465 / 2);
                    sprite.graphics.lineTo(v4.x + 465 / 2, v4.y + 465 / 2);
                    sprite.graphics.lineTo(v1.x + 465 / 2, v1.y + 465 / 2);
                    break;
                    
                    case "up":
                    
                    case "down":
                    v1 = core.transform.matrix3D.transformVector(new Vector3D(sorted[j].vc.x - radius, sorted[j].vc.y, sorted[j].vc.z - radius));
                    v2 = core.transform.matrix3D.transformVector(new Vector3D(sorted[j].vc.x - radius, sorted[j].vc.y, sorted[j].vc.z + radius));
                    v3 = core.transform.matrix3D.transformVector(new Vector3D(sorted[j].vc.x + radius, sorted[j].vc.y, sorted[j].vc.z + radius));
                    v4 = core.transform.matrix3D.transformVector(new Vector3D(sorted[j].vc.x + radius, sorted[j].vc.y, sorted[j].vc.z - radius));
                    
                    v1.w = (v1.z + pers) / pers;
                    v2.w = (v2.z + pers) / pers;
                    v3.w = (v3.z + pers) / pers;
                    v4.w = (v4.z + pers) / pers;
                    
                    v1.project();
                    v2.project();
                    v3.project();
                    v4.project();
                    
                    sprite.graphics.moveTo(v1.x + 465 / 2, v1.y + 465 / 2);
                    sprite.graphics.lineTo(v2.x + 465 / 2, v2.y + 465 / 2);
                    sprite.graphics.lineTo(v3.x + 465 / 2, v3.y + 465 / 2);
                    sprite.graphics.lineTo(v4.x + 465 / 2, v4.y + 465 / 2);
                    sprite.graphics.lineTo(v1.x + 465 / 2, v1.y + 465 / 2);
                    break;
                }
            } 
        }
        
        public function box(x:Number, y:Number, z:Number, cx:Number = 0, cy:Number = 0, cz:Number = 0):void {
            var donotbuild:Boolean = false;
            
            for (var ci:int = 0; ci < boxes.length; ci++) {
                if (boxes[ci].vc.equals(new Vector3D(x, y, z))) {
                    donotbuild = true;
                }
            }
            
            if (!donotbuild) {
                var color:uint = Math.random() * 0xffffff;
                
                array.push({vc:new Vector3D(x, y, z - radius), type:"front", color:color, bi:boxes.length});
                array.push({vc:new Vector3D(x, y, z + radius), type:"back", color:color, bi:boxes.length});
                array.push({vc:new Vector3D(x - radius, y, z), type:"left", color:color, bi:boxes.length});
                array.push({vc:new Vector3D(x + radius, y, z), type:"right", color:color, bi:boxes.length});
                array.push({vc:new Vector3D(x, y - radius, z), type:"up", color:color, bi:boxes.length});
                array.push({vc:new Vector3D(x, y + radius, z), type:"down", color:color, bi:boxes.length});
                
                boxes.push({vc:new Vector3D(x, y, z), stopped:false, destroying:false, cv:new Vector3D(cx, cy, cz), alpha:0});
            }
        }

    }
}