In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

Inspiracion - Midian

Así como esta fuente de chispas emana, asi has sido para muchas personas. Una fuente de inspiración sin fin. Animo miau miau..
Get Adobe Flash player
by vlad.el.rojo 13 Aug 2011
/**
 * Copyright vlad.el.rojo ( http://wonderfl.net/user/vlad.el.rojo )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/zFj6
 */

// Inspiracion - Midian . VLadimir Israel Ramírez D{iaz. VLD.
package {
    import flash.display.*;
    import flash.events.*;
    import flash.filters.*;
    import flash.geom.*;
    import flash.text.*;
    import flash.utils.*;

    [SWF(width="465", height="465", frameRate="40")]
    public class InspiracionMidian extends Sprite
    {
        // Posicion de los vectores
        private var position:Vector.<Number> = new Vector.<Number>();
        private var velocity:Vector.<Number> = new Vector.<Number>();
        private var diameters:Vector.<Number> = new Vector.<Number>();
        private var sparkNumber:Number = 0;
        
        private var projectedPosition:Vector.<Number> = new Vector.<Number>();
        private var uvts:Vector.<Number> = new Vector.<Number>();
        
        private var sparkBitmapDatas:Vector.<BitmapData> = new Vector.<BitmapData>();
        private var sparkBitmapDataRectangles:Vector.<Rectangle> = new Vector.<Rectangle>();
        private var sparkColor:uint = 0;
        
        private const GRAVITY:Number = 0.02;
        private const AIR_RESISTANCE:Number = 0.999;
        
        // NÚMERO DE CHISPAS
        private const EMIT_SPARK_NUMBER:int = 5;
        
        // rEFLEXIONES
        private var reflectionBitmapData:BitmapData;
        private var reflectionColor:uint = uint( Math.random() * 16777215 );
;
        private const REFLECTION_RADIUS:Number = 20;
        
        // bUFFER
        private var displayBuffer:BitmapData = new BitmapData(stage.stageWidth, stage.stageHeight, false);
        private var splitBuffer:BitmapData = new BitmapData(stage.stageWidth, stage.stageHeight, false);
        private const NUMBER_OF_SPLIT_FRAME:int = 5;
        
        private var perspective:PerspectiveProjection = new PerspectiveProjection();
        private var projectionMatrix:Matrix3D = new Matrix3D();
        
        private var viewRotationY:Number = 5;
        private var viewRotationX:Number = 5;
        
        private const CENTER_X:Number = stage.stageWidth / 2;
        private const CENTER_Y:Number = stage.stageHeight * 0.65;
        
        private var stats:TextField = new TextField();
        
        public function InspiracionMidian()
        {
            addChild(new Bitmap(displayBuffer));

            stats.x = 0;
            stats.y = 0;
            stats.autoSize = TextFieldAutoSize.LEFT;
            stats.textColor = 0xFFFFFF;
            addChild(stats);
            
            var shape:Shape = new Shape();
            var g:Graphics = shape.graphics;
                        
            
            var bitmapData:BitmapData = new BitmapData(1, 1, true, sparkColor);
            sparkBitmapDatas.push(bitmapData);
            sparkBitmapDataRectangles.push(bitmapData.rect);
            
            for (var diameter:int = 1; diameter <= 32; diameter++) {
                              sparkColor = uint( Math.random() * 16777215 );
                bitmapData = new BitmapData(diameter, diameter, true, 0);
                g.clear();
                g.beginFill(sparkColor);
                var radius:Number = diameter / 2;
                g.drawCircle(radius, radius, Math.random() * radius );
                g.endFill();
                bitmapData.draw(shape);
                
                sparkBitmapDatas.push(bitmapData);
                sparkBitmapDataRectangles.push(bitmapData.rect);
                
            }

            //Reflexiones
            reflectionBitmapData = new BitmapData(REFLECTION_RADIUS * 2, REFLECTION_RADIUS * 2, true, 0);
            g.clear();
            var matrix:Matrix = new Matrix();
            matrix.createGradientBox(REFLECTION_RADIUS * 2, REFLECTION_RADIUS * 2, 0, 0, 0);
            g.beginGradientFill(GradientType.RADIAL    , [ reflectionColor, reflectionColor ], [ 1, 0 ], [ 0, 255 ], matrix);
            g.drawCircle(REFLECTION_RADIUS, REFLECTION_RADIUS, REFLECTION_RADIUS);
            g.endFill();
            reflectionBitmapData.draw(shape);
            createFireworkModel();
            
            addEventListener(Event.ENTER_FRAME, enterFrameHandler);
        }

        private function enterFrameHandler(e:Event):void
        {
            displayBuffer.fillRect(displayBuffer.rect, 0);
            
            setupProjectionMatrix();
            
            var startTime:uint = getTimer();
            renderFloor();
            var floorRenderingTime:uint = getTimer() - startTime;
            
            startTime = getTimer();
            for (var i:int = 0; i < NUMBER_OF_SPLIT_FRAME; i++) {
                const FACTOR:Number = 0.06;
                viewRotationY += (getTimer() * 0.01 + (-(CENTER_X - mouseX) * 0.4) - viewRotationY) * FACTOR;
                viewRotationX += ((0 + (CENTER_Y - mouseY) * 0.6 ) - viewRotationX) * FACTOR;
                
                setupProjectionMatrix();
                
                for (var j:int = 0; j < EMIT_SPARK_NUMBER; j++) {
                    emitSpark();
                }
                updateSparks();
                renderSparks();
            }
            var sparksRenderingTime:uint = getTimer() - startTime;
            
            stats.text = '';
                
        }
        
        private function setupProjectionMatrix():void
        {
            perspective.fieldOfView = 60;
            
            projectionMatrix.identity();
            projectionMatrix.appendRotation(viewRotationY, Vector3D.Y_AXIS);
            projectionMatrix.appendRotation(viewRotationX, Vector3D.X_AXIS);
            projectionMatrix.appendTranslation(0, 0, perspective.focalLength);
            projectionMatrix.append(perspective.toMatrix3D());
            
            correctMatrix3DMultiplyBug(projectionMatrix);
        }
        
        private function correctMatrix3DMultiplyBug(matrix:Matrix3D):void
        {
            //Matriz en 3d
            var m1:Matrix3D = new Matrix3D(Vector.<Number>([ 0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 1, 0 ]));
            var m2:Matrix3D = new Matrix3D(Vector.<Number>([ 0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 1,  0, 0, 0, 0 ]));
            m1.append(m2);
            if (m1.rawData[15] == 20) {
                // バグ持ち!
                var rawData:Vector.<Number> = matrix.rawData;
                rawData[15] /= 20;
                matrix.rawData = rawData;
            }
        }
        
        private function createSpark(x:Number, y:Number, z:Number, vx:Number, vy:Number, vz:Number, diameter:Number):void
        {
            position.push(x, y, z);
            velocity.push(vx, vy, vz);
            diameters.push(diameter);
            sparkNumber++;
        }
        
        private function emitSpark():void
        {
            var azimuth:Number = Math.random() * 2 * Math.PI;
            var vy:Number = -(Math.random() * 0.06 + 0.94);
            var vx:Number = Math.sqrt(1 - vy * vy) * Math.cos(azimuth);
            var vz:Number = Math.sqrt(1 - vy * vy) * Math.sin(azimuth);
            
            var speed:Number = Math.random() * 2.3 + 0.7;
            vx *= speed;
            vy *= speed;
            vz *= speed;
            
            var diameter:Number = 3 + Math.random() * 3;
            createSpark(0, -FIREWORK_HEIGHT, 0, vx, vy, vz, diameter);
        }

        private function updateSparks():void
        {
            for (var i:int = 0; i < sparkNumber; ) {
                var xIndex:int = i * 3;
                var yIndex:int = xIndex + 1;
                var zIndex:int = xIndex + 2;
                
                velocity[yIndex] += GRAVITY;
                
                velocity[xIndex] *= AIR_RESISTANCE;
                velocity[yIndex] *= AIR_RESISTANCE;
                velocity[zIndex] *= AIR_RESISTANCE;
                
                if (position[yIndex] + velocity[yIndex] > 0) {
                    velocity[yIndex] = -velocity[yIndex] * 0.2;
                    
                    position[xIndex] += velocity[xIndex];
                    position[yIndex] += velocity[yIndex];
                    position[zIndex] += velocity[zIndex];
                    
                    // 小Diametro
                    const DIAMETER_MIN:Number = 2;
                    if (diameters[i] > DIAMETER_MIN) {
                        var diameterLimit:Number = diameters[i];
                        
                        while (1) {
                            var diameter:Number = Math.random() * (4 - DIAMETER_MIN) + DIAMETER_MIN;
                            diameterLimit -= diameter;
                            if (diameterLimit < 0) {
                                break;
                            }
                            var azimuth:Number = Math.random() * 2 * Math.PI;
                            var r:Number = Math.random() * 2;
                            
                            createSpark(position[xIndex], position[yIndex], position[zIndex], 
                                (velocity[xIndex] + Math.cos(azimuth) * r) * 0.5, 
                                velocity[yIndex], 
                                (velocity[zIndex] + Math.sin(azimuth) * r) * 0.5, 
                                diameter);
                        }
                    }
                    
                    //Splice

                    position[xIndex] = position[sparkNumber * 3 - 3];
                    position[yIndex] = position[sparkNumber * 3 - 2];
                    position[zIndex] = position[sparkNumber * 3 - 1];

                    velocity[xIndex] = velocity[sparkNumber * 3 - 3];
                    velocity[yIndex] = velocity[sparkNumber * 3 - 2];
                    velocity[zIndex] = velocity[sparkNumber * 3 - 1];
                    
                    diameters[i] = diameters[sparkNumber - 1];
                    
                    position.pop();
                    position.pop();
                    position.pop();

                    velocity.pop();
                    velocity.pop();
                    velocity.pop();
                    
                    diameters.pop();
                    
                    sparkNumber--;
                    continue;
                }
                position[xIndex] += velocity[xIndex];
                position[yIndex] += velocity[yIndex];
                position[zIndex] += velocity[zIndex];
                
                i++;
            }
        }
        
        private function renderSparks():void
        {
            splitBuffer.fillRect(splitBuffer.rect, 0x000000);
            
            Utils3D.projectVectors(projectionMatrix, position, projectedPosition, uvts);
            
            // Puntero
            var p:Point = new Point();
            var focalLength:Number = perspective.focalLength;
            
            for (var i:int = 0; i < sparkNumber; i++) {
                //Focales de diametro
                var diameter:int = uvts[i * 3 + 2] * focalLength * diameters[i] + 0.5;
                // (i * 2) => (i << 1)で10%ほど高速化
                p.x = CENTER_X + projectedPosition[(i << 1)    ] - diameter / 2;
                p.y = CENTER_Y + projectedPosition[(i << 1) + 1] - diameter / 2;
                splitBuffer.copyPixels(sparkBitmapDatas[diameter], sparkBitmapDataRectangles[diameter], p);
            }
            
            displayBuffer.draw(splitBuffer, null, null, BlendMode.ADD);
        }
        
        private const FLOOR_SIZE:Number = 800;
        private const FLOOR_HALFSIZE:Number = FLOOR_SIZE / 2;
        private const FLOOR_VERTICES:Vector.<Number> = Vector.<Number>([
             FLOOR_HALFSIZE, 0,  FLOOR_HALFSIZE, 
            -FLOOR_HALFSIZE, 0,  FLOOR_HALFSIZE, 
            -FLOOR_HALFSIZE, 0, -FLOOR_HALFSIZE, 
             FLOOR_HALFSIZE, 0, -FLOOR_HALFSIZE, 
             
             FLOOR_HALFSIZE, 0,               0, 
            -FLOOR_HALFSIZE, 0,               0, 
                          0, 0,  FLOOR_HALFSIZE, 
                          0, 0, -FLOOR_HALFSIZE, 
        ]);
        private const FLOOR_VERTEX_NUMBER:int = FLOOR_VERTICES.length / 3;
        
        private var floorProjectedVertices:Vector.<Number> = new Vector.<Number>();
        private var floorIndices:Vector.<int> = Vector.<int>([
            0, 1, 2,  2, 3, 0
        ]);
        private var floorUvts:Vector.<Number> = Vector.<Number>([
            1, 0, 0,  0, 0, 0,  0, 1, 0,  1, 1, 0,  
            0, 0, 0,  0, 0, 0,  0, 0, 0,  0, 0, 0
        ]);
        
        private const TEXTURE_SIZE:int = 400;
        private var floorTexture:BitmapData = new BitmapData(TEXTURE_SIZE, TEXTURE_SIZE, false);
        
        private const WIREFRAME_COLOR:uint = 0x555566;
        
        private var sprite:Sprite = new Sprite();
        
        private function renderFloor():void
        {
            //Piso
            const THRESHOLD_Y:Number = 50;
            
            var matrix:Matrix = new Matrix();
            var colorTransform:ColorTransform = new ColorTransform();
            
            floorTexture.fillRect(floorTexture.rect, 0x180C00);
            
            for (var i:int = 0; i < sparkNumber; i++) {
                var yIndex:int = i * 3 + 1;
                
                if (position[yIndex] > -THRESHOLD_Y) {
                    var xIndex:int = i * 3;
                    var zIndex:int = i * 3 + 2;
                    
                    matrix.identity();
                    var scale:Number = (0.2 - (position[yIndex] / THRESHOLD_Y) * 0.8) * diameters[i];
                    matrix.scale(scale, scale);
                    matrix.translate(FLOOR_HALFSIZE + position[xIndex] - REFLECTION_RADIUS * scale, FLOOR_HALFSIZE - position[zIndex] - REFLECTION_RADIUS * scale);
                    matrix.scale(TEXTURE_SIZE / FLOOR_SIZE, TEXTURE_SIZE / FLOOR_SIZE);
                    
                    colorTransform.alphaMultiplier = 1 + position[yIndex] / THRESHOLD_Y;
                    floorTexture.draw(reflectionBitmapData, matrix, colorTransform, BlendMode.ADD);
                }
            }
            
            Utils3D.projectVectors(projectionMatrix, FLOOR_VERTICES, floorProjectedVertices, floorUvts);
            for (i = 0; i < FLOOR_VERTEX_NUMBER; i++) {
                floorProjectedVertices[(i << 1)    ] += CENTER_X;
                floorProjectedVertices[(i << 1) + 1] += CENTER_Y;
            }
            
            Utils3D.projectVectors(projectionMatrix, fireworkVertices, fireworkProjectedVertices, fireworkUvts);
            for (i = 0; i < fireworkProjectedVertices.length / 2; i++) {
                fireworkProjectedVertices[(i << 1)    ] += CENTER_X;
                fireworkProjectedVertices[(i << 1) + 1] += CENTER_Y;
            }
            
            var g:Graphics = sprite.graphics;
            g.clear();
            g.beginBitmapFill(floorTexture);
            g.drawTriangles(floorProjectedVertices, floorIndices, floorUvts);
            g.endFill();
            displayBuffer.draw(sprite);
            
            g.clear();
            g.lineStyle(1, WIREFRAME_COLOR);
            g.moveTo(floorProjectedVertices[0], floorProjectedVertices[1]);
            g.lineTo(floorProjectedVertices[2], floorProjectedVertices[3]);
            g.lineTo(floorProjectedVertices[4], floorProjectedVertices[5]);
            g.lineTo(floorProjectedVertices[6], floorProjectedVertices[7]);
            g.lineTo(floorProjectedVertices[0], floorProjectedVertices[1]);
            
            g.moveTo(floorProjectedVertices[8], floorProjectedVertices[9]);
            g.lineTo(floorProjectedVertices[10], floorProjectedVertices[11]);
            g.moveTo(floorProjectedVertices[12], floorProjectedVertices[13]);
            g.lineTo(floorProjectedVertices[14], floorProjectedVertices[15]);
            displayBuffer.draw(sprite, null, null, BlendMode.ADD);
            
            g.clear();
            g.beginFill(FIREWORK_COLOR);
            g.drawTriangles(fireworkProjectedVertices, fireworkIndices);
            g.endFill();
            displayBuffer.draw(sprite);
        }
        
        private const FIREWORK_RADIUS:Number = 8;
        private const FIREWORK_HEIGHT:Number = 40;
        private const FIREWORK_COLOR:uint = 0xAACCFF;
        
        private var fireworkVertices:Vector.<Number> = new Vector.<Number>();
        private var fireworkIndices:Vector.<int> = new Vector.<int>();
        private var fireworkProjectedVertices:Vector.<Number> = new Vector.<Number>();
        private var fireworkUvts:Vector.<Number> = new Vector.<Number>();
        
        private function createFireworkModel():void
        {
            const SEGMENT:int = 8;
            for (var i:int = 0; i < SEGMENT; i++) {
                var x:Number = Math.cos(2 * Math.PI * i / SEGMENT) * FIREWORK_RADIUS;
                var z:Number = Math.sin(2 * Math.PI * i / SEGMENT) * FIREWORK_RADIUS;
                fireworkVertices.push(x, -FIREWORK_HEIGHT, z);
                fireworkVertices.push(x, 0, z);
                
                var i0:int = (i * 2    ) % (SEGMENT * 2);
                var i1:int = (i * 2 + 1) % (SEGMENT * 2);
                var i2:int = (i * 2 + 2) % (SEGMENT * 2);
                var i3:int = (i * 2 + 3) % (SEGMENT * 2);
                fireworkIndices.push(i2, i0, i1);
                fireworkIndices.push(i1, i3, i2);
            }
        }
    }
}