forked from: MyFirstBitmapData

by mitien forked from MyFirstBitmapData (diff: 1)
♥0 | Line 220 | Modified 2010-12-09 16:52:29 | MIT License
play

ActionScript3 source code

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

// forked from kamibana's MyFirstBitmapData
package 
{
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.Sprite;
    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
    import flash.events.MouseEvent;
    import flash.events.TimerEvent;
    import flash.text.TextField;
    import flash.text.TextFieldAutoSize;
    import flash.text.TextFormat;
    import flash.utils.Timer;

    /**
     * ...
     * @author kiyo
     */
    public class Main extends Sprite
    {
        private var canvas:BitmapData;
        private var particleArr:Vector.<ParticleObj>;
        private var numParticle:uint;
        private var render:Timer;
        private var offsetX:Number;
        private var offsetY:Number;
        private var count:int = 0;
        
        private var textCanvas:BitmapData;
        
        
        private var isClick:Boolean;
        
        public function Main() 
        {
            stage.scaleMode = StageScaleMode.NO_SCALE;
            stage.align = StageAlign.TOP_LEFT;
            initialize();
        }
        
        private function initialize():void
        {
            Property.windX = 0;
            Property.windY = 0;
            
            numParticle = 0;
            particleArr = new Vector.<ParticleObj>();
            canvas = new BitmapData(stage.stageWidth, stage.stageHeight, false, 0x000000);
            addChild(new Bitmap(canvas));
            stage.addEventListener(MouseEvent.CLICK, clickHandler);
            
            setBitmapText();
            
            render = new Timer(Property.TIME_DERAY);
            render.addEventListener(TimerEvent.TIMER, rendering);
            render.start();
        }
        
        private function setBitmapText():void
        {
            var textInfo:TextInformation = new TextInformation();
            textInfo.displayText = "MyFirstBitmapData";
            textInfo.fontSize = 40;
            textInfo.color = 0xffffff;
            textCanvas = GetBitmapTextData.getText(textInfo);
            createText();
        }
        
        private function createText():void
        {
            offsetX = stage.stageWidth / 2 - textCanvas.width / 2;
            offsetY = stage.stageHeight / 2 - textCanvas.height / 2;
            
            //textCanvasを走査して、黒以外のピクセルデータを持ったところにパーティクルの座標をセットする。
            for (var i:int = 0; i < textCanvas.width; i++) 
            {
                for (var j:int = 0; j < textCanvas.height; j++) 
                {
                    var color:uint = textCanvas.getPixel(i, j);
                    if (color != 0x000000) {
                        createParticle(offsetX + i, offsetY + j, color);
                    }    
                }
            }
        }
        
        private function createParticle(i:int, j:int, color:uint):void
        {
            var particle:ParticleObj = new ParticleObj();
            //テキストのあるところにターゲット座標をセット
            particle.tx = i;
            particle.ty = j;    
            particle.color = color;
            initParticles(particle);
            particleArr.push(particle);
        }
        
        //particleの初期位置の設定。
        private function initParticles(particle:ParticleObj):void
        {
            particle.x = stage.stageWidth * Math.random();
            particle.y = (stage.stageHeight - stage.stageHeight * 0.7) * Math.random();
        }
        private function rendering(e:TimerEvent):void 
        {
            canvas.lock();
            canvas.fillRect(canvas.rect, 0x000000);
            updateValue();
            for (var i:int = 0; i < numParticle; i++) 
            {
                var particle:ParticleObj = particleArr[i];
                canvas.setPixel(particle.x, particle.y, particle.color);
            }
            var len:int = particleArr.length;
            numParticle = (numParticle + Property.RENDERING_PIXEL < len)?numParticle + Property.RENDERING_PIXEL:len;
            canvas.unlock();
        }
        
        private function updateValue():void
        {
            if (!isClick) {
                outMotion();
            }else {
                inMotion();
            }        
        }

        private function outMotion():void
        {
            //for (var i:int = 0; i < numParticle; i++){//一気に飛び散らせる
            for (var i:int = 0; i < count; i++) {//徐々に飛び散らせる
            
                var particle:ParticleObj = particleArr[i];
                particle.vx = (particle.vx + Property.windX) * Property.FRICTION;
                particle.vy = (particle.vy + Property.GRAVITY + Property.windY) * Property.FRICTION;
                particle.x += particle.vx;
                particle.y += particle.vy;
            }
            count += 50;
            if (count > numParticle) {
                count = numParticle;
            }
        }
        
        private function inMotion():void
        {
            for (var i:int = 0; i < numParticle; i++) 
            {
                var particle:ParticleObj = particleArr[i];
                if(Math.abs(particle.tx - particle.x) < 0.5 && Math.abs(particle.ty - particle.y) < 0.5){
                    //スナップ処理
                    particle.x = particle.tx;
                    particle.y = particle.ty;
                }else {
                    particle.x += (particle.tx - particle.x) * Math.random() * 0.25;
                    particle.y += (particle.ty - particle.y) * Math.random() * 0.25;
                }
            }
        }
        
        private function clickHandler(e:MouseEvent):void 
        {
            isClick = !isClick;
            var len:int = particleArr.length;
            
            if (isClick) {
                for (var i:int = 0; i < len; i++) 
                {
                    var particle:ParticleObj = particleArr[i];                    
                    //初速の設定
                    particle.vx = Math.random() * Property.VX0 * 2 - Property.VX0 + Math.random() * 4;
                    particle.vy = Math.random() * Property.VY0 * 2 - Property.VY0 + Math.random() * 4;
                    Property.windX = Math.random() * 0.8 - 0.4;
                    Property.windY = Math.random() * 0.7 - 0.35;
                }
            }
            count = 0;
        }        
    }

}  
  
  
  
  
  
  
  
    class ParticleObj
    {
        
        public var x:Number;
        public var y:Number;
        public var vx:Number;
        public var vy:Number;
        public var tx:Number;
        public var ty:Number;
        public var color:int;
    
        public function ParticleObj(){
            x = 0;
            y = 0;
            vx = 0;
            vy = 0;
            tx = 0;
            ty = 0;
            color = 0;
        }
        
    }
    
    import flash.display.BitmapData;
    import flash.text.TextField;
    import flash.text.TextFieldAutoSize;
    import flash.text.TextFormat;
    /**
     * ...
     * @author kiyo
     */
    class GetBitmapTextData
    {
        
        public static function getText(textInfo:TextInformation):BitmapData
        {
            var textCanvas:BitmapData;
            var tf:TextField = new TextField();
            var tfFormat:TextFormat = new TextFormat();
            tfFormat.font = textInfo.font;
            tfFormat.size = textInfo.fontSize;
            tfFormat.color = textInfo.color;
            tf.defaultTextFormat = tfFormat;
            tf.autoSize = textInfo.autosize;
            tf.text = textInfo.displayText;
            //addChild(tf);
            textCanvas = new BitmapData(tf.textWidth, tf.textHeight, false, 0x000000);
            textCanvas.draw(tf);
            
            return textCanvas;
        }
        
    }
    
    class Property
    {
        //パーティクルの初速
        public static const VX0:Number = 10;
        public static const VY0:Number = 10;
        
        public static const FRICTION:Number = 0.99;//空気抵抗
        public static const GRAVITY:Number = 0.3;//パーティクルに与える重力
        public static const TIME_DERAY:Number = 33;//描画を更新する間隔
        public static const MAX_DISTANCE:Number = 1000;//パーティクルの初期位置の最大値
        
        //風をシミュレーションする。
        public static var windX:Number = 0.4;
        public static var windY:Number = 0.2;
        
        public static const RENDERING_PIXEL:Number = 60;//TIME_DERAY毎にレンダリングするピクセル数
    }
    
    class TextInformation
    {
        public var displayText:String;
        public var fontSize:Number;
        public var font:String;
        public var color:uint;
        public var autosize:String;
        
        public function TextInformation() 
        {
            displayText = "default";
            fontSize = 12;
            font = "Helvetica";
            color = 0xff0000;
            autosize = TextFieldAutoSize.LEFT;
        }
        
    }