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

[Box2D]いちおう時計

Get Adobe Flash player
by inippo 25 Nov 2010
/**
 * Copyright inippo ( http://wonderfl.net/user/inippo )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/e3jo
 */

/**
 * Box2DClock
 * Box2Dを使って時計もどき
 * 
 * trick7さんのTeraClockをお借りしました。
 * http://www.libspark.org/wiki/trick7/TeraClock
 * 
 * */
package {
    import Box2D.Collision.b2AABB;
    import Box2D.Collision.Shapes.b2CircleDef;
    import Box2D.Collision.Shapes.b2PolygonDef;
    import Box2D.Common.Math.b2Vec2;
    import Box2D.Dynamics.b2Body;
    import Box2D.Dynamics.b2BodyDef;
    import Box2D.Dynamics.b2DebugDraw;
    import Box2D.Dynamics.b2World;
    import flash.display.*;
    import flash.events.*;
    import flash.filters.*;
    import flash.geom.*;
    import flash.text.*;
    import flash.utils.*;
    
    [SWF(width = 465, height = 465, frameRate = 60 , backgroundColor = "#F6f6f6")]  
    public class Box2DClock extends Sprite {
        
        public var tf:TextField;
        public var tfm:TextFormat;
        
        public var world:b2World;
        public var body:b2Body;
        public var worldAABB:b2AABB;
        public var floorBodyDef:b2BodyDef;
        public var clock:TeraClock;
        
        public const FONT:String = "Arial Black";
        public const H_FONT_SIZE:int = 50;
        public const M_FONT_SIZE:int = 30;
        public const S_FONT_SIZE:int = 15;
        public const H_FONT_COLOR:uint = 0xcc0000;
        public const M_FONT_COLOR:uint = 0xcc0000;
        public const S_FONT_COLOR:uint = 0xcc0000;
        
        public const FLOOR_WIDTH:int = 300;
        public const FLOOR_HEIGHT:int = 20;
        public const FLOOR_ANGLE:int = 0;
        public const FLOOR_COLOR:uint = 0x666666;
        
        public const GRAVITY:int = 10;
        
        public function Box2DClock() {
            
            // Box2Dの初期設定
            setb2d();
            
            // 時計の設定
            setClock();
            
            // コピー元のテキストを作成
            tf = new TextField();
            tf.autoSize = TextFieldAutoSize.LEFT;
            
            // タイマーで監視
            var t:Timer = new Timer(33, 0);
            t.addEventListener(TimerEvent.TIMER, update);
            t.start();
            
            
            // 初回表示
            minutesListener(null);
            hoursListener(null);
            
        }
        
        /**
         * 秒の更新
         */
        public function secondsListener(e:Event):void
        {    
            var str:String = clock.seconds2.charAt(1);
            var sp:Sprite = createTexture(S_FONT_SIZE,str,S_FONT_COLOR);
            createB2Object(sp,60, clock.seconds)
        }
        
        /**
         * 分の更新
         */
        public function minutesListener(e:Event):void
        {
            var sp:Sprite = createTexture(M_FONT_SIZE,clock.minutes.toString(),M_FONT_COLOR);
            createB2Object(sp, 60,clock.minutes);
        }
        
        /**
         * 時の更新(毎分オブジェクト作成)
         */
        public function hoursListener(e:Event):void
        {
            var sp:Sprite = createTexture(H_FONT_SIZE,clock.hours.toString(),M_FONT_COLOR);
            createB2Object(sp,24,clock.hours)
        }
        
        /**
         * オブジェクト作成
         */
        public function createB2Object(texture:Sprite, length:int, time:int):void
        {
            var bodyDef:b2BodyDef = new b2BodyDef();
            bodyDef.position.Set(((FLOOR_WIDTH / length) * time) / 100 + (stage.stageWidth - FLOOR_WIDTH) / 2 / 100, 0); 
            bodyDef.angle = Math.PI / 2 * Math.random();
            bodyDef.userData = texture;
            bodyDef.userData.width = texture.width;
            bodyDef.userData.height = texture.height;

            body = world.CreateBody(bodyDef);
            
            var bodyShape:b2CircleDef = new b2CircleDef();
            bodyShape.radius = texture.width / 2 / 100;
            bodyShape.density = 0.5;
            bodyShape.friction = 10;
            bodyShape.restitution = 0.2;
            
            body.CreateShape(bodyShape);
            body.SetMassFromShapes();
        }
        
        
        /**
         * 文字列作成
         */
        public function createTexture(fontsize:uint,str:String,col:uint):Sprite
        {
            tf.text = str;
            tfm = new TextFormat(FONT, fontsize, col);
            tfm.kerning = true;
            //if(str.length > 1) tfm.letterSpacing = -7;
            tf.setTextFormat(tfm);
            var bmd:BitmapData = new BitmapData(tf.width, tf.height,true, 0x00000000);
            bmd.draw(tf);
            
            var bmp:Bitmap = new Bitmap(bmd);
            var sp:Sprite = new Sprite();
            sp.y = -150;
            sp.addChild(bmp);
            addChild(sp);
            bmp.smoothing = true;
            bmp.x = -(bmp.width / 2);
            bmp.y = -(bmp.height / 2);
            
            return sp;
        }
        
        /**
         * 時計の作成
         */
        public function setClock():void
        {
            clock = new TeraClock();
            clock.addEventListener(TeraClock.SECONDS_CHANGED, secondsListener);
            clock.addEventListener(TeraClock.MINUTES_CHANGED, minutesListener);
            clock.addEventListener(TeraClock.MINUTES_CHANGED, hoursListener);
        }
        
        /**
         * Box2Dの初期設定
         */
        public function setb2d():void
        {
            //外枠の定義
            worldAABB = new b2AABB();
            worldAABB.lowerBound.Set(-100, -100);
            worldAABB.upperBound.Set(100, 100);
            
            //重力の定義
            var g:b2Vec2 = new b2Vec2(0, GRAVITY);
            
            //エンジンのセットアップ
            world = new b2World(worldAABB, g, true);
            
            //床の定義
            var sp:Sprite = new Sprite();
            sp.graphics.beginFill(FLOOR_COLOR);
            sp.graphics.drawRect(-FLOOR_WIDTH / 2, -FLOOR_HEIGHT / 2, FLOOR_WIDTH, FLOOR_HEIGHT);
            sp.graphics.endFill();
            
            floorBodyDef = new b2BodyDef();
            floorBodyDef.position.Set(stage.stageWidth / 2 / 100, stage.stageHeight / 100 * 0.8);
            floorBodyDef.angle = FLOOR_ANGLE; // 床の角度
            floorBodyDef.userData = sp;
            
            //床の形の定義
            var floorShapeDef:b2PolygonDef = new b2PolygonDef();
            floorShapeDef.SetAsBox(1.5, 0.1);
            floorShapeDef.friction = 2;
            floorShapeDef.density = 0;
            
            //オブジェクトを作る
            var floor:b2Body = world.CreateBody(floorBodyDef);
            floor.CreateShape(floorShapeDef);
            addChild(floor.GetUserData());
        }
        
        
        /**
         * 描画の更新
         */
        public function update(e:TimerEvent = null):void
        {
            //trace("update")
            world.Step(1 / 24, 10); 
            for (var bb:b2Body = world.m_bodyList; bb; bb = bb.m_next){
                if (bb.m_userData is Sprite){
                    bb.m_userData.x = bb.GetPosition().x*100;
                    bb.m_userData.y = bb.GetPosition().y*100;
                    bb.m_userData.rotation = bb.GetAngle() * (180 / Math.PI);                    
                }
            }
        }
        
    }
}




import flash.display.*;
import flash.events.Event;
import flash.events.EventDispatcher;    

class TeraClock extends Sprite {
    public static const HOURS_CHANGED:String = "hoursChanged";
    public static const MINUTES_CHANGED:String = "minutesChanged";
    public static const SECONDS_CHANGED:String = "secondsChanged";
    private var _hours:int;
    private var _minutes:int;
    private var _seconds:int;
    private var _preSeconds:int;
    private var _gmt:int;
    // コンストラクタ関数。引数でタイムゾーンを設定できる。デフォルトは+9:00(日本)
    public function TeraClock(GMT:int = 9) {
        _gmt = GMT%24;
        this.enterFrameListener(null);
        addEventListener(Event.ENTER_FRAME, enterFrameListener);
    }
    
    private function enterFrameListener(e:Event):void {
        var date:Date = new Date();
        if(_gmt>=0){
            _hours = (date.getUTCHours() + _gmt) % 24;
        }else {
            _hours = (24+(date.getUTCHours() + _gmt)) % 24;
        }
        _minutes = date.getUTCMinutes();
        _seconds = date.getUTCSeconds();
        if (_seconds != _preSeconds) {
            //trace(_hours + ":" + _minutes + ":" + _seconds);
            dispatchEvent(new Event(SECONDS_CHANGED));
            if (_seconds == 0) {
                dispatchEvent(new Event(MINUTES_CHANGED));
                if (_minutes == 0) {
                    dispatchEvent(new Event(HOURS_CHANGED));
                }
            }
        }
        _preSeconds = _seconds;
    }
    // 外部から値を取得するためのゲッター。セッターはとりあえずいらないや。
    public function get hours():int { return _hours; }
    public function get minutes():int { return _minutes; }
    public function get seconds():int { return _seconds; }
    public function get milliseconds():int { return (new Date()).getUTCMilliseconds(); }
    // 上位1桁返す
    public function get hoursUpper():int { return _hours / 10; }
    public function get minutesUpper():int { return _minutes / 10; }
    public function get secondsUpper():int { return _seconds / 10; }
    // 下位1桁返す
    public function get hoursLower():int { return _hours % 10; }
    public function get minutesLower():int  { return _minutes % 10; }
    public function get secondsLower():int { return _seconds % 10; }
    // 1桁の数の時を2桁にする。返り値は String 型になる。
    public function get hours2():String { return niketa(_hours); }
    public function get minutes2():String { return niketa(_minutes); }
    public function get seconds2():String { return niketa(_seconds); }
    // 1の位を切り捨てて2桁にする。返り値は String 型になる。
    public function get milliseconds2():String { return niketa((new Date()).getUTCMilliseconds() / 10); }
    // 3桁になるように接頭に0を付けくわえる。返り値は String 型になる。
    public function get milliseconds3():String { return keta((new Date()).getUTCMilliseconds(), 3); }
    // 2桁にして返す関数
    private function niketa(num:int):String {
        if (num < 10) {
            return String("0"+num);
        }else {
            return String(num);
        }
    }
    // 指定桁数にして返す関数
    private function keta(num:int, keta:int):String {
        var str:String = String(num);
        while(str.length < keta) str = "0" + str;
        return str;
    }
    //アナログ時計にした時の針の角度を返す。
    public function get hoursDegree():Number {
        return ((_hours % 12) * 30) + (_minutes / 2) + (_seconds/120);
    }
    public function get minutesDegree():Number {
        return (_minutes * 6) + (_seconds / 10);
    }
    public function get secondsDegree():Number {
        return _seconds * 6;
    }
    //現時刻からh時m分s秒だけずらした時間を取得する(戻り値のdateは元の時刻を0日としたときの差分)
    public function getDifferenceTime(s:int, m:int, h:int):Object {
        var time:Array = [_seconds, _minutes, _hours, 0];
        var dt:Array   = [s, m, h];
        var cap:Array  = [60, 60, 24];
        for(var i:int = 0; i < 3; ++i) {
            time[i] += dt[i];
            if(time[i] < 0) {
                time[i + 1] += Math.floor(time[i] / cap[i]);
                time[i] = time[i] % cap[i] + cap[i];
                continue;
            }
            if(time[i] >= cap[i]) {
                time[i + 1] += Math.floor(time[i] / cap[i]);
                time[i] = time[i] % cap[i];
                continue;
            }
        }
        return {seconds:time[0], minutes:time[1], hours:time[2], date:time[3]};
    }
}