[Box2D]いちおう時計 inippo forked:0favorite:15lines:234license : MIT License modified : 2010-11-26 02:28:47 Embed Tweet /** * 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]}; } } Code Fullscreen Preview Fullscreen hacker_4z534.. publicroots postnum applicott andrewexex88.. skn chrisp kt3k djankey meika_kouri Emre.Alper tripot_ken : Box2D時計 k0rin : かわいい nikolajy : ckock hi4sandy : shohoku_col20100920 Box2D,Clock shohoku_col20100920 時計 time getUTCMilliseconds Date dispatchEvent getUTCHours hours date b2World kerning getUTCMinutes String getUTCSeconds userData b2PolygonDef CreateBody b2Vec2 friction restitution milliseconds m_bodyList