「AS3による数学・物理学表現[入門編]」のプログラムをASファイルのみで記述5

Case04 3次元空間で回転するデジタルクロック

bmpで数字のインスタンスを作るのに苦戦しました。
hour, minute, secondは冗長すぎたのでクラスとか作ってみた。もっと短くできると思う。

package
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Sprite;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.events.Event;
	import flash.events.TimerEvent;
	import flash.text.TextField;
	import flash.text.TextFormat;
	import flash.utils.Timer;
	
	public class math04clock_1 extends Sprite
	{
		private var base:Sprite;
		private var timer:Timer;
		
		private var hour:Array;
		private var minute:Array;
		private var second:Array;
		
		private var hourX:Array, hourY:Array, hourZ:Array, hourSize:Array;
		private var minuteX:Array, minuteY:Array, minuteZ:Array, minuteSize:Array;
		private var secondX:Array, secondY:Array, secondZ:Array, secondSize:Array;
		
		private const radius:Number = 500;
		private const screenZ:Number = 400;
		private const centerZ:Number = 950;
		
		
		//コンストラクタ
		public function math04clock_1()
		{
			stage.scaleMode = StageScaleMode.NO_SCALE;
			stage.align = StageAlign.TOP_LEFT;
			
			base = new Sprite();
			base.x = stage.stageWidth/2;
			base.y = stage.stageHeight/2;
			addChild(base);
			
			makeObject();
			
			timer = new Timer(33);
			timer.addEventListener(TimerEvent.TIMER, loop);
			timer.start();
			
		}
		
		private function makeObject():void{
			hour = new Array();
			minute = new Array();
			second = new Array();
			
			var sp:timerSymbol;
			
			for(var i:int=0 ; i<24 ; i++){
				if(i<10) sp = new timerSymbol("0"+String(i), -300);
				else    sp = new timerSymbol(String(i), -300);				
				hour.push(sp);
				base.addChild(sp);
			}
			
			for(i = 0 ; i<60 ; i++){
				if(i<10) sp = new timerSymbol("0"+String(i),0);
				else    sp = new timerSymbol(String(i),0);
				minute.push(sp);
				base.addChild(sp);
			}
			
			for(i = 0 ; i<60 ; i++){
				if(i<10) sp = new timerSymbol("0"+String(i),300);
				else    sp = new timerSymbol(String(i),300);
				second.push(sp);
				base.addChild(sp);
			}			
		}
		
		
		private function loop(e:TimerEvent):void{
			var date:Date = new Date();	
			var hours:Number = date.getHours();
			var minutes:Number = date.getMinutes();
			var seconds:Number = date.getSeconds();
			
			for(var i:Number = 0 ; i<24 ; i++){
				
				var angle:Number = (-hours/24*Math.PI*2 + i/24*Math.PI*2);
				var yy:Number = radius*Math.sin(angle);
				var zz:Number = centerZ - radius*Math.cos(angle);
				
				hour[i].yy += (yy - hour[i].yy)/4;
				hour[i].zz += (zz - hour[i].zz)/4;
				
				if(i == hours) hour[i].size += (0.9-hour[i].size)/4;
				else           hour[i].size += (0.2-hour[i].size)/4;
				
				hour[i].x = hour[i].xx * screenZ/hour[i].zz;
				hour[i].y = hour[i].yy * screenZ/hour[i].zz;
				hour[i].scaleX = hour[i].scaleY = hour[i].size * screenZ/hour[i].zz;
			}
			
			for(i = 0 ; i<60 ; i++){
				
				angle = (-minutes/60*Math.PI*2 + i/60*Math.PI*2);
				yy = radius*Math.sin(angle);
				zz = centerZ - radius*Math.cos(angle);
				
				minute[i].yy += (yy - minute[i].yy)/4;
				minute[i].zz += (zz - minute[i].zz)/4;
				
				if(i == minutes) minute[i].size += (0.9-minute[i].size)/4;
				else            minute[i].size += (0.2-minute[i].size)/4;
				
				minute[i].x = minute[i].xx * screenZ/minute[i].zz;
				minute[i].y = minute[i].yy * screenZ/minute[i].zz;
				minute[i].scaleX = minute[i].scaleY = minute[i].size * screenZ/minute[i].zz;
			}
			
			for(i = 0 ; i<60 ; i++){
				
				angle = (-seconds/60*Math.PI*2 + i/60*Math.PI*2);
				yy = radius*Math.sin(angle);
				zz = centerZ - radius*Math.cos(angle);
				
				second[i].yy += (yy - second[i].yy)/4;
				second[i].zz += (zz - second[i].zz)/4;
				
				if(i == seconds) second[i].size += (0.9-second[i].size)/4;
				else             second[i].size += (0.2-second[i].size)/4;
				
				second[i].x = second[i].xx * screenZ/second[i].zz;
				second[i].y = second[i].yy * screenZ/second[i].zz;
				second[i].scaleX = second[i].scaleY = second[i].size * screenZ/second[i].zz;
				
			}
			
		}
	}
}
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Sprite;
import flash.geom.Matrix;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.text.TextFormat;
	
	
class timerSymbol extends Sprite{
	private var _xx:Number;
	private var _yy:Number;
	private var _zz:Number;
	private var _size:Number;
		
	public function get xx():Number{ return _xx;}
	public function get yy():Number{ return _yy;}
	public function get zz():Number{ return _zz;}
	public function get size():Number{ return _size;}
	
	public function set xx(x:Number):void{ this._xx = x;}
	public function set yy(y:Number):void{ this._yy = y;}
	public function set zz(z:Number):void{ this._zz = z;}
	public function set size(size:Number):void{ this._size = size;}
		
	public function timerSymbol(s:String="", x:Number=0, y:Number=0, z:Number=0, size:Number=1):void{
		
		this._xx = x;
		this._yy = y;
		this._zz = z;
		this._size = size;
		
		//spriteの中心がbmpの中心になるように位置を調整してます
		var text:TextField = new TextField();
		text.defaultTextFormat = new TextFormat("Arial", 200, 0x000000, true);
		text.autoSize = TextFieldAutoSize.LEFT;
		text.text=s;
		
		var bmpd:BitmapData = new BitmapData(text.width, text.height, true, 0);
		bmpd.draw(text);
		var bmp:Bitmap = new Bitmap(bmpd);
		addChild(bmp);
		bmp.x -= bmpd.width/2;
		bmp.y -= bmpd.height/2;
	}
}