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

Heaven Condition Particles

Stage3DでBitmapData.draw()気分。
Get Adobe Flash player
by o8que 21 Aug 2012
/**
 * Copyright o8que ( http://wonderfl.net/user/o8que )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/juiw
 */

package {
    import flash.display.BitmapData;
    import flash.display.Graphics;
    import flash.display.Sprite;
    import flash.display.Stage3D;
    import flash.events.Event;
    import flash.filters.BlurFilter;
    import flash.filters.GlowFilter;
    import flash.geom.Rectangle;
    import flash.text.TextField;
    import net.hires.debug.Stats;
/*    import ore.orelib.commons.Key;
    import ore.orelib.commons.Labeler;
*/    
    [SWF(width = "465", height = "465", frameRate = "60", backgroundColor = "0x000000")]
    public class Main extends Sprite {
        private var _ore2D:Ore2D;
        private var _particles:Vector.<Particle>;
        private var _particlePool:Vector.<Particle>;
        private var _numParticlesLabel:TextField;
        
        public function Main() {
            var stage3D:Stage3D = stage.stage3Ds[0];
            stage3D.addEventListener(Event.CONTEXT3D_CREATE, init);
            stage3D.requestContext3D();
        }
        
        private function init(event:Event):void {
            event.currentTarget.removeEventListener(event.type, arguments.callee);
            
            _ore2D = new Ore2D(stage, 0, 233, 233, createImage());
            _ore2D.registerSprites(new Rectangle(0, 0, 32, 32), 1, 1);
            
            _particles = new Vector.<Particle>();
            _particlePool = new Vector.<Particle>();
            
            addChild(_numParticlesLabel = new Labeler()
                .align(Labeler.BOTTOM_RIGHT).filters([new GlowFilter(0x000000, 1, 4, 4)])
                .fontColor(0xFFFFFF).pos(365, 0).size(100, 20).build("0")
            );
            addChild(new Stats());
            
            Key.init(this);
            addEventListener(Event.ENTER_FRAME, update);
        }
        
        private function createImage():BitmapData {
            var result:BitmapData = new BitmapData(32, 32, true, 0x00FFFFFF);
            var sp:Sprite = new Sprite();
            var g:Graphics = sp.graphics;
            g.beginFill(0xFFFFFF); g.moveTo(20, 12); g.lineTo(4, 16); g.lineTo(20, 20); g.curveTo(28, 16, 20, 12); g.endFill();
            sp.filters = [new BlurFilter(2, 2)];
            result.draw(sp);
            return result;
        }
        
        private function update(event:Event):void {
            if (Key.isDown(Key.MOUSE_LEFT)) { emitParticles(stage.mouseX, stage.mouseY); }
            
            for (var i:int = _particles.length - 1; i >= 0; i--) {
                var particle:Particle = _particles[i];
                particle.update();
                
                if ( -16 < particle.pos.x && particle.pos.x < 481 && -16 < particle.pos.y && particle.pos.y < 481) {
                    _ore2D.draw(0, particle.matrix, particle.colorTransform);
                } else {
                    _particles.splice(i, 1);
                    _particlePool.push(particle);
                }
            }
            
            _numParticlesLabel.text = _particles.length.toString();
        }
        
        private function emitParticles(x:Number, y:Number):void {
            for (var i:int = 0; i < 360; i++) {
                var particle:Particle = (_particlePool.length) ? _particlePool.pop() : new Particle();
                var rad:Number = i * Math.PI / 180;
                particle.init(x, y, 10 * Math.cos(rad), 10 * Math.sin(rad), rad);
                _particles.push(particle);
            }
        }
    }
}
//package {
    import com.adobe.utils.AGALMiniAssembler;
    import flash.display.BitmapData;
    import flash.display.Stage;
    import flash.display.Stage3D;
    import flash.display3D.Context3D;
    import flash.display3D.Context3DBlendFactor;
    import flash.display3D.Context3DProgramType;
    import flash.display3D.Context3DTextureFormat;
    import flash.display3D.Context3DVertexBufferFormat;
    import flash.display3D.IndexBuffer3D;
    import flash.display3D.Program3D;
    import flash.display3D.textures.Texture;
    import flash.display3D.VertexBuffer3D;
    import flash.events.Event;
    import flash.geom.ColorTransform;
    import flash.geom.Matrix;
    import flash.geom.Matrix3D;
    import flash.geom.Point;
    import flash.geom.Rectangle;
    import flash.utils.ByteArray;
    
    //public 
    class Ore2D {
        private var _context3D:Context3D;
        private var _screenHalfSize:Point;
        private var _spriteSheet:BitmapData;
        private var _spriteDataList:Vector.<Vector.<Number>>;
        
        private var _vertexData:Vector.<Number>;
        private var _vertexBuffer:VertexBuffer3D;
        private var _indexData:Vector.<uint>;
        private var _indexBuffer:IndexBuffer3D;
        private var _vertexProgram:ByteArray;
        private var _fragmentProgram:ByteArray;
        
        private var _numBatches:int;
        private var _vertexDataIndex:int;
        
        public function Ore2D(stage:Stage, stage3DIndex:int, halfWidth:int, halfHeight:int, spriteSheet:BitmapData) {
            var stage3D:Stage3D = stage.stage3Ds[stage3DIndex];
            _context3D = stage3D.context3D;
            _screenHalfSize = new Point(halfWidth, halfHeight);
            _spriteSheet = spriteSheet;
            _spriteDataList = new Vector.<Vector.<Number>>();
            
            _vertexData = new Vector.<Number>(4 * 12 * 16380, true);
            _indexData = new Vector.<uint>(6 * 16380, true);
            for (var n:int = 0, i:int = 0, v:int = 0; n < 16380; n++, i += 6, v += 4) {
                _indexData[i] = v;
                _indexData[i + 1] = v + 1;
                _indexData[i + 2] = v + 2;
                _indexData[i + 3] = v + 3;
                _indexData[i + 4] = v + 2;
                _indexData[i + 5] = v + 1;
            }
            
            var assembler:AGALMiniAssembler = new AGALMiniAssembler();
            _vertexProgram = assembler.assemble(Context3DProgramType.VERTEX, [
                "m44 op, va0, vc0",
                "mov v0, va1",
                "mov v1, va2",
                "mul v2, va3, vc4"
            ].join("\n"));
            _fragmentProgram = assembler.assemble(Context3DProgramType.FRAGMENT, [
                "tex ft0, v0, fs0<2d, clamp, linear, nomip>",
                "mul ft0, ft0, v1",
                "add oc, ft0, v2"
            ].join("\n"));
            
            _numBatches = _vertexDataIndex = 0;
            
            onContext3DCreated();
            stage3D.addEventListener(Event.CONTEXT3D_CREATE, onContext3DCreated);
            stage.addEventListener(Event.EXIT_FRAME, present);
        }
        
        private function onContext3DCreated(event:Event = null):void {
            if (event) { _context3D = event.currentTarget.context3D; }
            // screen
            _context3D.configureBackBuffer(_screenHalfSize.x * 2, _screenHalfSize.y * 2, 0, false);
            var screenMatrix:Matrix3D = new Matrix3D();
            screenMatrix.appendScale(1 / _screenHalfSize.x, 1 / _screenHalfSize.y, 1);
            screenMatrix.appendTranslation( -1, 1, 0);
            _context3D.setProgramConstantsFromMatrix(Context3DProgramType.VERTEX, 0, screenMatrix, true);
            // texture
            var texture:Texture = _context3D.createTexture(_spriteSheet.width, _spriteSheet.height, Context3DTextureFormat.BGRA, false);
            texture.uploadFromBitmapData(_spriteSheet);
            _context3D.setTextureAt(0, texture);
            // vertex
            _vertexBuffer = _context3D.createVertexBuffer(4 * 16380, 12);
            var colorOffsetFactor:Vector.<Number> = new <Number>[1 / 255, 1 / 255, 1 / 255, 1 / 255];
            _context3D.setProgramConstantsFromVector(Context3DProgramType.VERTEX, 4, colorOffsetFactor);
            // index
            _indexBuffer = _context3D.createIndexBuffer(6 * 16380);
            _indexBuffer.uploadFromVector(_indexData, 0, 6 * 16380);
            // program
            var program3D:Program3D = _context3D.createProgram();
            program3D.upload(_vertexProgram, _fragmentProgram);
            _context3D.setProgram(program3D);
            // blend
            _context3D.setBlendFactors(Context3DBlendFactor.ONE, Context3DBlendFactor.ONE_MINUS_SOURCE_ALPHA);
        }
        
        private function present(event:Event):void {
            _vertexBuffer.uploadFromVector(_vertexData, 0, 65520);
            _context3D.setVertexBufferAt(0, _vertexBuffer, 0, Context3DVertexBufferFormat.FLOAT_2); // position
            _context3D.setVertexBufferAt(1, _vertexBuffer, 2, Context3DVertexBufferFormat.FLOAT_2); // uv
            _context3D.setVertexBufferAt(2, _vertexBuffer, 4, Context3DVertexBufferFormat.FLOAT_4); // colorMultiplier
            _context3D.setVertexBufferAt(3, _vertexBuffer, 8, Context3DVertexBufferFormat.FLOAT_4); // colorOffset
            
            _context3D.clear();
            _context3D.drawTriangles(_indexBuffer, 0, _numBatches << 1);
            _context3D.present();
            
            _numBatches = _vertexDataIndex = 0;
        }
        
        public function registerSprites(first:Rectangle, cols:int, rows:int):void {
            for (var row:int = 0; row < rows; row++) {
                for (var col:int = 0; col < cols; col++) {
                    var spriteData:Vector.<Number> = new Vector.<Number>(6, true);
                    spriteData[0] = first.width; // width
                    spriteData[1] = first.height; // height
                    var left:Number = first.x + first.width * col;
                    var top:Number = first.y + first.height * row;
                    spriteData[2] = (left + 0.5) / _spriteSheet.width; // uvLeft
                    spriteData[3] = (top + 0.5) / _spriteSheet.height; // uvTop
                    spriteData[4] = (left + first.width - 0.5) / _spriteSheet.width; // uvRight
                    spriteData[5] = (top + first.height - 0.5) / _spriteSheet.height; // uvBottom
                    
                    _spriteDataList.push(spriteData);
                }
            }
        }
        
        public function draw(spriteIndex:int, matrix:Matrix, colorTransform:ColorTransform):void {
            if (_numBatches >= 16380 || spriteIndex >= _spriteDataList.length) { return; }
            
            var i:int = _vertexDataIndex;
            var spriteData:Vector.<Number> = _spriteDataList[spriteIndex];
            
            var width:Number = spriteData[0];
            var height:Number = spriteData[1];
            var aw:Number = matrix.a * width;
            var bw:Number = matrix.b * width;
            var ch:Number = matrix.c * height;
            var dh:Number = matrix.d * height;
            var tx:Number = matrix.tx;
            var ty:Number = matrix.ty;
            
            _vertexData[i] = tx;
            _vertexData[i + 1] = -ty;
            _vertexData[i + 12] = aw + tx;
            _vertexData[i + 13] = -(bw + ty);
            _vertexData[i + 24] = ch + tx;
            _vertexData[i + 25] = -(dh + ty);
            _vertexData[i + 36] = aw + ch + tx;
            _vertexData[i + 37] = -(bw + dh + ty);
            
            var uvLeft:Number = spriteData[2];
            var uvTop:Number = spriteData[3];
            var uvRight:Number = spriteData[4];
            var uvBottom:Number = spriteData[5];
            
            _vertexData[i + 2] = _vertexData[i + 26] = uvLeft;
            _vertexData[i + 3] = _vertexData[i + 15] = uvTop;
            _vertexData[i + 14] = _vertexData[i + 38] = uvRight;
            _vertexData[i + 27] = _vertexData[i + 39] = uvBottom;
            
            var rm:Number = colorTransform.redMultiplier;
            var gm:Number = colorTransform.greenMultiplier;
            var bm:Number = colorTransform.blueMultiplier;
            var am:Number = colorTransform.alphaMultiplier;
            var ro:Number = colorTransform.redOffset;
            var go:Number = colorTransform.greenOffset;
            var bo:Number = colorTransform.blueOffset;
            var ao:Number = colorTransform.alphaOffset;
            
            _vertexData[i + 4] = _vertexData[i + 16] = _vertexData[i + 28] = _vertexData[i + 40] = rm;
            _vertexData[i + 5] = _vertexData[i + 17] = _vertexData[i + 29] = _vertexData[i + 41] = gm;
            _vertexData[i + 6] = _vertexData[i + 18] = _vertexData[i + 30] = _vertexData[i + 42] = bm;
            _vertexData[i + 7] = _vertexData[i + 19] = _vertexData[i + 31] = _vertexData[i + 43] = am;
            _vertexData[i + 8] = _vertexData[i + 20] = _vertexData[i + 32] = _vertexData[i + 44] = ro;
            _vertexData[i + 9] = _vertexData[i + 21] = _vertexData[i + 33] = _vertexData[i + 45] = go;
            _vertexData[i + 10] = _vertexData[i + 22] = _vertexData[i + 34] = _vertexData[i + 46] = bo;
            _vertexData[i + 11] = _vertexData[i + 23] = _vertexData[i + 35] = _vertexData[i + 47] = ao;
            
            _numBatches++;
            _vertexDataIndex += 48;
        }
    }
//}
//package {
    import flash.geom.ColorTransform;
    import flash.geom.Matrix;
    import flash.geom.Point;
    
    //public 
    class Particle {
        private var _position:Point;
        private var _velocity:Point;
        private var _angle:Number;
        
        private var _matrix:Matrix;
        private var _colorTransform:ColorTransform;
        
        public function Particle() {
            _position = new Point();
            _velocity = new Point();
            _angle = 0;
            
            _matrix = new Matrix();
            _colorTransform = new ColorTransform();
        }
        
        public function init(x:Number, y:Number, vx:Number, vy:Number, angle:Number):void {
            _position.setTo(x, y);
            _velocity.setTo(vx, vy);
            _angle = angle;
            
            _colorTransform.redMultiplier = (Math.random() < 0.5) ? 1 : 0.5;
            _colorTransform.greenMultiplier = (Math.random() < 0.5) ? 1 : 0.5;
            _colorTransform.blueMultiplier = (Math.random() < 0.5) ? 1 : 0.5;
        }
        
        public function update():void {
            _position.offset(_velocity.x, _velocity.y);
            
            _matrix.identity();
            _matrix.translate( -16, -16);
            _matrix.rotate(_angle);
            _matrix.translate(_position.x, _position.y);
        }
        
        public function get pos():Point { return _position; }
        public function get matrix():Matrix { return _matrix; }
        public function get colorTransform():ColorTransform { return _colorTransform; }
    }
//}
//package ore.orelib.commons {
    import flash.display.Sprite;
    import flash.display.Stage;
    import flash.events.ContextMenuEvent;
    import flash.events.Event;
    import flash.events.KeyboardEvent;
    import flash.events.MouseEvent;
    import flash.ui.ContextMenu;
    
    //public 
    class Key {
        private static var _stage:Stage;
        private static var _currentStates:Vector.<Boolean>;
        private static var _previousStates:Vector.<Boolean>;
        
        public static const MOUSE_LEFT:uint = 0;
        public static const MOUSE_RIGHT:uint = 255;
        
        public static function init(documentClass:Sprite):void {
            _stage = documentClass.stage;
            _currentStates = new Vector.<Boolean>(256, true);
            _previousStates = new Vector.<Boolean>(256, true);
            
            _stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
            _stage.addEventListener(KeyboardEvent.KEY_UP, keyUpHandler);
            _stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
            _stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
            _stage.addEventListener(Event.EXIT_FRAME, update);
            _stage.addEventListener(Event.DEACTIVATE, clear);
            
            var contextMenu:ContextMenu = new ContextMenu();
            contextMenu.hideBuiltInItems();
            contextMenu.addEventListener(ContextMenuEvent.MENU_SELECT, clear);
            documentClass.contextMenu = contextMenu;
        }
        
        private static function keyDownHandler(event:KeyboardEvent):void { _currentStates[event.keyCode] = true; }
        private static function keyUpHandler(event:KeyboardEvent):void { _currentStates[event.keyCode] = false; }
        private static function mouseDownHandler(event:MouseEvent):void { _currentStates[Key.MOUSE_LEFT] = true; }
        private static function mouseUpHandler(event:MouseEvent):void { _currentStates[Key.MOUSE_LEFT] = false; }
        
        private static function update(event:Event):void {
            for (var i:int = 0; i < 256; i++) {
                _previousStates[i] = _currentStates[i];
            }
        }
        
        private static function clear(event:Event):void {
            for (var i:int = 0; i < 256; i++) {
                _currentStates[i] = false;
            }
        }
        
        public static function isDown(keyCode:uint):Boolean { return _stage.focus == null && _currentStates[keyCode]; }
        public static function pressed(keyCode:uint):Boolean { return Key.isDown(keyCode) && !_previousStates[keyCode]; }
    }
//}
//package ore.orelib.commons {
    import flash.geom.Point;
    import flash.text.AntiAliasType;
    import flash.text.GridFitType;
    import flash.text.TextField;
    import flash.text.TextFieldAutoSize;
    import flash.text.TextFormat;
    import flash.text.TextFormatAlign;
    
    //public 
    class Labeler {
        private var _hAlign:String;
        private var _autoSize:String;
        private var _vAlign:String;
        private var _background:Boolean;
        private var _backgroundColor:uint;
        private var _filters:Array;
        private var _fontName:String;
        private var _sharpness:Number;
        private var _thickness:Number;
        private var _fontColor:uint;
        private var _fontSize:int;
        private var _position:Point;
        private var _selectable:Boolean;
        private var _size:Point;
        private var _wordWrap:Boolean;
        
        public static const NONE:String = "none";
        public static const TOP_LEFT:String = "top_left";
        public static const MIDDLE_CENTER:String = "middle_center";
        public static const BOTTOM_RIGHT:String = "bottom_right";
        
        public function Labeler() {
            _hAlign = TextFormatAlign.LEFT;
            _autoSize = TextFieldAutoSize.NONE;
            _vAlign = Labeler.TOP_LEFT;
            _background = false;
            _backgroundColor = 0xFFFFFF;
            _filters = [];
            _fontName = "_sans";
            _sharpness = _thickness = 0;
            _fontColor = 0x000000;
            _fontSize = 12;
            _position = new Point(0, 0);
            _size = new Point(100, 100);
            _selectable = _wordWrap = false;
        }
        
        public function align(value:String = Labeler.TOP_LEFT):Labeler {
            switch(value) {
                case Labeler.MIDDLE_CENTER: { _hAlign = TextFormatAlign.CENTER; break; }
                case Labeler.BOTTOM_RIGHT: { _hAlign = TextFormatAlign.RIGHT; break; }
                case Labeler.TOP_LEFT: default: { _hAlign = TextFormatAlign.LEFT; break; }
            }
            return this;
        }
        
        public function autoSize(horizontal:String = Labeler.NONE, vertical:String = Labeler.TOP_LEFT):Labeler {
            switch(horizontal) {
                case Labeler.TOP_LEFT: { _autoSize = TextFieldAutoSize.LEFT; break; }
                case Labeler.MIDDLE_CENTER: { _autoSize = TextFieldAutoSize.CENTER; break; }
                case Labeler.BOTTOM_RIGHT: { _autoSize = TextFieldAutoSize.RIGHT; break; }
                case Labeler.NONE: default: { _autoSize = TextFieldAutoSize.NONE; break; }
            }
            _vAlign = vertical;
            return this;
        }
        
        public function background(enabled:Boolean = true, color:uint = 0xFF0000):Labeler { _background = enabled; _backgroundColor = color; return this; }
        public function filters(value:Array):Labeler { _filters = value; return this; }
        public function font(name:String, sharpness:Number = 0, thickness:Number = 0):Labeler { _fontName = name; _sharpness = sharpness; _thickness = thickness; return this; }
        public function fontColor(value:uint):Labeler { _fontColor = value; return this; }
        public function fontSize(value:int):Labeler { _fontSize = value; return this; }
        public function offset(x:Number, y:Number):Labeler { _position.offset(x, y); return this; }
        public function pos(x:Number, y:Number):Labeler { _position.setTo(x, y); return this; }
        public function selectable(enabled:Boolean = true):Labeler { _selectable = enabled; return this; }
        public function size(width:Number, height:Number):Labeler { _size.setTo(width, height); return this; }
        public function wordWrap(enabled:Boolean = true):Labeler { _wordWrap = enabled; return this; }
        
        public function build(text:String):TextField {
            var result:TextField = new TextField();
            result.x = _position.x; result.width = _size.x; result.height = _size.y;
            result.autoSize = _autoSize;
            result.background = _background; result.backgroundColor = _backgroundColor;
            result.filters = _filters;
            result.mouseEnabled = result.selectable = _selectable;
            result.wordWrap = _wordWrap;
            result.defaultTextFormat = new TextFormat(_fontName, _fontSize, _fontColor, null, null, null, null, null, _hAlign);
            if (_fontName != "_sans") {
                result.embedFonts = true;
                result.antiAliasType = AntiAliasType.ADVANCED;
                result.gridFitType = (_hAlign == TextFormatAlign.LEFT) ? GridFitType.PIXEL : GridFitType.SUBPIXEL;
                result.sharpness = _sharpness; result.thickness = _thickness;
            }
            result.text = text;
            switch(_vAlign) {
                case Labeler.MIDDLE_CENTER: { result.y = _position.y + (_size.y - result.height) / 2; break; }
                case Labeler.BOTTOM_RIGHT: { result.y = _position.y + (_size.y - result.height); break; }
                case Labeler.TOP_LEFT: default: { result.y = _position.y; break; }
            }
            return result;
        }
    }
//}