forked from: はじける時計

by aiz
♥0 | Line 342 | Modified 2014-01-31 22:50:41 | MIT License
play

ActionScript3 source code

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

// forked from shuff's はじける時計
package
{
    import flash.display.BitmapData;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.events.TimerEvent;
    import flash.geom.Point;
    import flash.text.TextField;
    import flash.ui.Keyboard;
    import flash.utils.Timer;
    import flash.utils.setTimeout;
    
    import frocessing.color.ColorHSV;
    
    import org.osmf.events.TimeEvent;
    import org.osmf.net.SwitchingRuleBase;

    [SWF(backgroundColor=0x0,frameRate=60)]
    public class Clock2 extends Sprite
    {
        private var date:Date;
        private var year:Number;
        private var month:Number;
        private var day:Number;
        private var hours:Number;
        private var minutes:Number;
        private var seconds:Number;
        private var textfield:TextField = new TextField();
        private var timer:Timer = new Timer(1000);
        private var delay:uint = 1500;
        private var v:Number = 0;
        private var pX:Vector.<Number> = new Vector.<Number>();
        private var pY:Vector.<Number> = new Vector.<Number>();
        
        private var array1:Vector.<Ball2> = new Vector.<Ball2>();
        private var array2:Vector.<int> = new Vector.<int>();
        private var array3:Vector.<int> = new Vector.<int>();
        private var count:uint = 0;
        private var count2:uint = 0;
        private var flag:Boolean = true;
        private var flag2:Boolean = false;
        private var flag3:Boolean = false;
        private var sp:Ball2;
        private var bd:BitmapData;
        private var tf:TextField = new TextField();
        private var hsv:ColorHSV = new ColorHSV();
        
        private var bounce:Number = -1.0;
        private var centerX:Number = stage.stageWidth/2;
        private var centerY:Number = stage.stageHeight/2;
        
        public function Clock2()
        {
            stage.addEventListener(MouseEvent.CLICK, init);
            timer.addEventListener(TimerEvent.TIMER, now);
            timer.start();
        }
        private function init(e:MouseEvent):void{
            if(flag){
            flag = false;
            timer.stop();
            addEventListener(Event.ENTER_FRAME, onEnterFrame);
            
            var timer2:Timer = new Timer(8000);
            timer2.addEventListener(TimerEvent.TIMER,function():void{
                if(count%3==0){////初期処理1
                    if(count2%2==1){
                        pX.length=0;
                        pY.length=0;
                        triangle();
                        count2++;
                    }else{
                        flag2 = false;
                        count2++;
                    }
                    
                    removeEventListener(Event.ENTER_FRAME,onEnterFrame);
                }
                else if(count%3==1){////初期処理2
                    removeEventListener(Event.ENTER_FRAME,burst);
                }
                else if(count%3==2){////初期処理3
                    removeEventListener(Event.ENTER_FRAME,burst);
                }
                fork();
            });
            timer2.start();
            }
        }
        private function fork():void{
            var timer3:Timer = new Timer(1500,1);
            if(count%3==2){////アニメーション3の前処理
                pX.length=0;
                pY.length=0;
                array1[0].vx = 0;
                array1[0].vy = -10;
                array1[0].mass = 15;
                array1[0].scaleX=1;
                array1[0].scaleY=1;
                pX.push(stage.stageWidth/2);
                pY.push(stage.stageHeight-10);
                for(var j:uint=1 ; j<array1.length ; j++){
                    array1[j].vx = 0;
                    array1[j].vy = 0;
                    array1[j].scaleX=1;
                    array1[j].scaleY=1;
                }
                triangle();
                if(flag3)delay=800;
            }
            
            addEventListener(Event.ENTER_FRAME,bTimer);    
            
            if(count%3==0){    ////アニメーション1    
                timer3.addEventListener(TimerEvent.TIMER,function():void{
                    for(var i:uint=0 ; i<array1.length ; i++){
                        var rad:Number = i*360/array1.length;
                        array1[i].vx = Math.cos(rad*Math.PI/180)*4;
                        array1[i].vy = Math.sin(rad*Math.PI/180)*4;
                    }
                    addEventListener(Event.ENTER_FRAME,burst);
                });
                timer3.start();
            }
            else if(count%3==1){ ////アニメーション2
                timer3.addEventListener(TimerEvent.TIMER,function():void{
                    for(var i:uint=0 ; i<Math.floor(array1.length/2) ; i++){
                        var rad:Number = i*360/(array1.length/2);
                        array1[i].vx = Math.cos(rad*Math.PI/180)*4;
                        array1[i].vy = Math.sin(rad*Math.PI/180)*4;
                        if(i%2==0){
                        array1[i].scaleX*=3;
                        array1[i].scaleY*=3;
                        }
                        else{
                            array1[i].scaleX*=1;
                            array1[i].scaleY*=1;
                        }
                    }
                    for(var j:uint=Math.floor(array1.length/2) ; j<array1.length ; j++){
                        rad = j*360/Math.floor(array1.length/2);
                        array1[j].vx = Math.cos(rad*Math.PI/180)*2.5;
                        array1[j].vy = Math.sin(rad*Math.PI/180)*2.5;
                        if(j%2==0){
                            array1[j].scaleX*=3;
                            array1[j].scaleY*=3;
                        }
                        else{
                            array1[j].scaleX*=1;
                            array1[j].scaleY*=1;
                        }
                    }
                    addEventListener(Event.ENTER_FRAME,burst);
                });
                timer3.start();
            }
            else if(count%3==2){////アニメーション3
                timer3.addEventListener(TimerEvent.TIMER,function():void{
                    flag2 = true;
                    flag3 = true;
                    var timer4:Timer = new Timer(delay,1);
                    timer4.addEventListener(TimerEvent.TIMER,function():void{
                        removeEventListener(Event.ENTER_FRAME,bTimer);
                        addEventListener(Event.ENTER_FRAME,onEnterFrame);
                    });
                    timer4.start();
                });
                timer3.start();
            }
            count++;
        }
        //ボールを三角形に並べる
        private function triangle():void{
            var num1:uint=0;
            var num2:uint=1;
            var loopCount:uint=1;
            //三角形の段数を決める
            while(1){
                if(num1>=array1.length-1)break;
                num1 += num2++;
                loopCount++;
            }
            
            //ボールを三角形に並べるための座標を決める
            for(var j:uint=0 ; j<loopCount ; j++){
                for(var i:uint=0 ; i<j+1 ; i++){
                    pX.push(stage.stageWidth/2 - 4*j + 2*4*i);
                    pY.push(stage.stageHeight/2-j*4*2);
                }
            }
        }
        private function bTimer(e:Event):void{
            if(!flag2){
                for(var i:uint=0 ; i<array1.length ; i++){
                    var ball:Ball2 = array1[i];
                    ball.x += (centerX - ball.x)/15;
                    ball.y += (centerY - ball.y)/15;
                }
            }
            else{
                for(i=0 ; i<array1.length ; i++){
                    ball = array1[i];
                    ball.x += (pX[i] - ball.x)/15;
                    ball.y += (pY[i] - ball.y)/15;
                }
            }    
        }
        private function burst(e:Event):void{
            removeEventListener(Event.ENTER_FRAME,bTimer);
            for(var i:int=0 ; i<array1.length ; i++){
                var ball:Ball2 = array1[i];
                ball.x += ball.vx;
                ball.y += ball.vy;
                checkWalls(ball);
            }
        }
        //デジタル時計
        private function now(e:TimerEvent):void{
            if(flag){
                for(var j:int=0 ; j<array1.length ; j++){
                    removeChild(array1[j]);
                }
            array1.length=0;
            array2.length=0;
            array3.length=0;
            
            date = new Date();
            year = date.fullYear;
            month = date.month+1;
            day = date.day;
            hours = date.hours;
            minutes  = date.minutes;
            seconds = date.seconds;
            
            //円で時間を表示する
            var time:TextField = new TextField();
            time.text = year+"/"+month+"/"+day+"\n    "+hours+":"+minutes+":"+seconds+"\n";
            
            bd = new BitmapData(time.width, time.height, false, 0xFFFFFF);
            bd.draw(time);
            
            for(var x:int = 0; x < bd.width; x++){
                for(var y:int = 0; y < bd.height; y++){
                    if(bd.getPixel(x, y) < 0xff0000){
                        array2.push(x);
                        array3.push(y);
                    }
                }
            }
            for(j = 0; j < array2.length; j++){
                hsv.h = j*360/array2.length;
                var color:uint = hsv.toRGB().value;
                
                //速度の調節
                if(seconds<=25)seconds=25;
                else if(seconds>=45)seconds=45;
                sp = new Ball2(color,(seconds*Math.random())/10,(seconds*Math.random())/10);
                array1.push(sp);
                addChild(sp);
                sp.x = array2[j]*8;
                sp.y = array3[j]*8;
            }
            }
        }


        //フレームの処理
        private function onEnterFrame(e:Event):void{
            for(var i:uint=0 ; i<array1.length ; i++){
                var ball:Ball2 = array1[i];
                ball.x += ball.vx;
                ball.y += ball.vy;
                
                checkWalls(ball);
            }
            for(i=0 ; i<array1.length-1 ; i++){
                var ballA:Ball2 = array1[i];
                for(var j:Number=i+1 ; j<array1.length ; j++){
                    var ballB:Ball2 = array1[j];
                    checkCollision(ballA,ballB);
                }    
            }
        }
        //壁に当たった時の処理
        private function checkWalls(ball:Ball2):void{
            if(ball.x + ball.radius > stage.stageWidth){
                ball.x = stage.stageWidth - ball.radius;
                ball.vx *= bounce;
            }else if(ball.x - ball.radius < 0){
                ball.x = ball.radius;
                ball.vx *= bounce;
            }
            if(ball.y + ball.radius > stage.stageHeight){
                ball.y = stage.stageHeight - ball.radius;
                ball.vy *= bounce;
            }else if(ball.y - ball.radius < 0){
                ball.y = ball.radius;
                ball.vy *= bounce;
            }
        }
        //衝突の処理
        private function checkCollision(ball0:Ball2, ball1:Ball2):void{
            var dx:Number = ball1.x - ball0.x;
            var dy:Number = ball1.y - ball0.y;
            var dist:Number = Math.sqrt(dx*dx + dy*dy);
            if(dist < ball0.radius + ball1.radius){
                var angle:Number = Math.atan2(dy,dx);
                var sin:Number = Math.sin(angle);
                var cos:Number = Math.cos(angle);
                
                var pos0:Point = new Point(0,0);
                var pos1:Point = rotate(dx,dy,sin,cos,true);
                var vel0:Point = rotate(ball0.vx,ball0.vy,sin,cos,true);
                var vel1:Point = rotate(ball1.vx,ball1.vy, sin,cos,true);
                
                var vxTotal:Number = vel0.x - vel1.x;
                vel0.x = ((ball0.mass - ball1.mass)*vel0.x + 
                    2*ball1.mass*vel1.x)/
                    (ball0.mass + ball1.mass);
                vel1.x = vxTotal + vel0.x;
                
                pos0.x += vel0.x;
                pos1.x += vel1.x;
                
                var pos0F:Object = rotate(pos0.x,pos0.y,sin,cos,false);
                var pos1F:Object = rotate(pos1.x, pos1.y,sin,cos,false);
                
                ball1.x = ball0.x + pos1F.x;
                ball1.y = ball0.y + pos1F.y;
                ball0.x = ball0.x + pos0F.x;
                ball0.y = ball0.y + pos0F.y;
                
                var vel0F:Object = rotate(vel0.x,vel0.y,sin,cos,false);
                var vel1F:Object = rotate(vel1.x,vel1.y,sin,cos,false);
                
                ball0.vx = vel0F.x;
                ball0.vy = vel0F.y;
                ball1.vx = vel1F.x;
                ball1.vy = vel1F.y;
            }
        }
        
        private function rotate(x:Number,y:Number,sin:Number,cos:Number,reverse:Boolean):Point{
            var result:Point = new Point();
            if(reverse){
                result.x = x*cos+y*sin;
                result.y = y*cos-x*sin;
            }else{
                result.x = x*cos-y*sin;
                result.y = y*cos+x*sin;
            }
            return result;
        }
    }
}

//ボールの描画とパラメータの設定
import flash.display.Sprite;
class Ball2 extends Sprite
{
    public var radius:Number;
    private var color:uint;
    public var vx:Number;
    public var vy:Number;
    public var mass:Number = 1;
    
    public function Ball2(color:uint,vvx:Number,vvy:Number)
    {
        this.radius = 4;
        this.color=color;
        this.vx = vvx;
        this.vy = vvy;
        init();
    }
    
    private function init():void{
        graphics.beginFill(color);
        graphics.drawCircle(0,0,radius);
        graphics.endFill();
    }
}