clock & timer
3つのモードになります。
・デジタル時計
・ラーメンタイマー
・アナログ時計
trick7さんのTeraClockをお借りしました。
http://www.libspark.org/wiki/trick7/TeraClock
/**
* Copyright itkr ( http://wonderfl.net/user/itkr )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/vRHR
*/
package {
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.text.TextField;
import flash.text.TextFormat;
//import com.trick7.utils.TeraClock;
import caurina.transitions.Tweener;
import flash.display.Bitmap;
public class Main extends Sprite{
//TeraClockオブジェクト
private var _clock:TeraClock;
//時間を文字列で格納する
private var modeTitle:TextField = new TextField();
//デジタル時計全体を現す配列
private var digitalClock:Array = new Array();
//モード記憶用カウンタ
private var modeClazz:int = 0;
//汎用カウンタ
private var count:int = 0;
//初期MovieClip情報記憶用(ArrayList<HashMap>)
private var firstMetaData:Array = new Array();
//アナログ時計の針
private var hour:Sprite;
private var minute:Sprite;
private var second:Sprite;
//ステージ情報
private const STAGE:Object = {stageWidth:460,stageHeight:460};
/* ************************
* コンストラクタ
************************ */
public function Main(){
var digital:Sprite;
var digitalList:Array;
//デジタルクロックの枠組みの作成(二重配列)
for (var i:int=0; i<6; i++){
digitalList = new Array();
//数字ひとつを作成(配列)
for (var j:int=0; j<7; j++){
digital = new Sprite();
digital.graphics.beginFill(0x000000);
digital.graphics.drawRect(0,0,40,5);
digital.graphics.endFill();
digital.name = "d_" + i.toString() + "_" + j.toString();
if(i==0){
//デジタルクロック全体のx位置を中央に
digital.x = (STAGE.stageWidth - (digital.width * 6 + digital.height * 6 + 10 * 6)) / 2 -40;
//デジタルクロック全体のy位置を中央に
digital.y = (STAGE.stageHeight - (digital.height + digital.width * 2)) / 2;
}else{
//一つ前の数字を元に数字の位置を決める
digital.x = digital.width + digitalClock[i-1][0].x + 25;
//時・分・秒の間のスペースを空ける ★20110611追加
if(i==2 || i==4){
digital.x = digital.x + 20;
}
digital.y = digitalClock[i-1][0].y;
}
switch (j){
case 0 :
addChild(digital);
break;
case 1 :
digital.rotation = 90;
digital.x = digitalList[0].x + digitalList[0].width + 1;
digital.y = digitalList[0].y + 2;
break;
case 2 :
digital.rotation = 90;
digital.x = digitalList[0].x - 2;
digital.y = digitalList[0].y + 2;
break;
case 3 :
digital.rotation = 0;
digital.x = digitalList[0].x;
digital.y = digitalList[0].y + digitalList[0].width + 3;
break;
case 4 :
digital.rotation = 90;
digital.x = digitalList[0].x - 2;
digital.y = digitalList[0].y + digitalList[0].width + 5;
break;
case 5 :
digital.rotation = 90;
digital.x = digitalList[0].x + digitalList[0].width + 1;
digital.y = digitalList[0].y + digitalList[0].width + 5;
break;
case 6 :
digital.rotation = 0;
digital.x = digitalList[0].x;
digital.y = digitalList[0].y + digitalList[0].width * 2 + 6;
break;
}
addChild(digital);
digitalList.push(digital);
firstMetaData.push({name:digital.name,x:digital.x,y:digital.y,rotation:digital.rotation});
}
digitalClock.push(digitalList);
}
hour = digitalClock[3][1];
minute = digitalClock[1][1];
second = digitalClock[5][1];
_clock = new TeraClock();
var textFormat:TextFormat = new TextFormat();
textFormat.size = 20;
textFormat.underline = true;
//var button:ChangeButton = new ChangeButton();
var button:TextField = new TextField();
button.text = "mode change";
button.width =120;
button.x= (STAGE.stageWidth - button.width)/2;
button.y= STAGE.stageHeight - button.height-30;
button.setTextFormat(textFormat);
addChild(button);
button.addEventListener(MouseEvent.CLICK,onClick);
//button.buttonMode = true;
//初期モードをデジタル時計にする
initDigitalClockMode();
//モード名を表示する
addChild(modeTitle);
}
/* ************************
* クリックしたときの動作
************************ */
private function onClick(e:MouseEvent):void{
_clock.removeEventListener(TeraClock.HOURS_CHANGED, hoursListener);
_clock.removeEventListener(TeraClock.MINUTES_CHANGED, minutesListener);
_clock.removeEventListener(TeraClock.SECONDS_CHANGED, secondsListener);
_clock.removeEventListener(TeraClock.SECONDS_CHANGED, noodlesTimer);
_clock.removeEventListener(TeraClock.SECONDS_CHANGED, timeComplete);
_clock.removeEventListener(TeraClock.SECONDS_CHANGED, analogSecondsListener);
_clock.removeEventListener(TeraClock.MINUTES_CHANGED, analogMinutesListener);
_clock.removeEventListener(TeraClock.HOURS_CHANGED, analogHoursListener);
Tweener.removeAllTweens();
switch(modeClazz){
case 0:
initnoodlesTimerMode();
break;
case 1:
initAnalogClockMode();
break;
default:
initDigitalClockMode();
modeClazz = -1;
}
modeClazz++;
}
/* ************************
* ラーメンタイマーモードが選択されたとき
************************ */
private function initnoodlesTimerMode():void{
modeTitle.text = "noodle timer";
//タイマー用カウンタ(3分)
count = 60 * 3 + 1;
//全部"0"にする
for(var i:int=0;i<6;i++){changeNumber(i,"0");}
//分2桁目を"3"にする
changeNumber(3,"3");
_clock.addEventListener(TeraClock.SECONDS_CHANGED, noodlesTimer);
}
/* ************************
* デジタル時計モードが選択されたとき
************************ */
private function initDigitalClockMode():void{
modeTitle.text = "digital clock";
var i:int = 0;
//デジタル時計の位置を初期状態に戻す。
for each(var digitalList:Array in digitalClock){
for each(var digital:Sprite in digitalList){
Tweener.addTween(digital,{transition:"easeInOutBack",time:1,delay:0,x:firstMetaData[i].x,y:firstMetaData[i].y,rotation:firstMetaData[i].rotation,scaleX:1,scaleY:1});
i++;
}
}
changeNumber(0,_clock.hours2.charAt(0));
changeNumber(1,_clock.hours2.charAt(1));
changeNumber(2,_clock.minutes2.charAt(0));
changeNumber(3,_clock.minutes2.charAt(1));
changeNumber(4,_clock.seconds2.charAt(0));
changeNumber(5,_clock.seconds2.charAt(1));
_clock.addEventListener(TeraClock.SECONDS_CHANGED, secondsListener);
_clock.addEventListener(TeraClock.MINUTES_CHANGED, minutesListener);
_clock.addEventListener(TeraClock.HOURS_CHANGED, hoursListener);
}
/* ************************
* アナログ時計モードが選択されたとき
************************ */
private function initAnalogClockMode():void{
modeTitle.text = "analog clock";
var centerX:Number = (STAGE.stageWidth-digitalClock[0][0].width)/2+digitalClock[0][0].width/2;
var centerY:Number = (STAGE.stageWidth-digitalClock[0][0].height)/2;
for each(var digitalList:Array in digitalClock){
for each(var digital:Sprite in digitalList){
if(digital!=hour && digital!=minute && digital!=second){
Tweener.addTween(digital,{transition:"easeInOutBack",time:1,delay:0,alpha:0});
}
}
}
Tweener.addTween(hour,{transition:"easeInOutBack",time:1,delay:0,x:centerX,y:centerY,scaleX:2,rotation:_clock.hoursDegree-90});
hour.alpha = 1;
Tweener.addTween(minute,{transition:"easeInOutBack",time:1,delay:0,x:centerX,y:centerY,scaleX:3,rotation:_clock.minutesDegree-90});
minute.alpha = 1;
Tweener.addTween(second,{transition:"easeInOutBack",time:1,delay:0,x:centerX,y:centerY,scaleX:3,scaleY:1/4,rotation:_clock.secondsDegree-90});
second.alpha = 1;
_clock.addEventListener(TeraClock.SECONDS_CHANGED, analogSecondsListener);
_clock.addEventListener(TeraClock.MINUTES_CHANGED, analogMinutesListener);
_clock.addEventListener(TeraClock.HOURS_CHANGED, analogHoursListener);
}
/* ************************
* 時が変わったときの動作(デジタル時計モード)
************************ */
private function hoursListener(e:Event):void{
changeNumber(0,_clock.hours2.charAt(0));
changeNumber(1,_clock.hours2.charAt(1));
}
/* ************************
* 分が変わったときの動作(デジタル時計モード)
************************ */
private function minutesListener(e:Event):void{
changeNumber(2,_clock.minutes2.charAt(0));
changeNumber(3,_clock.minutes2.charAt(1));
}
/* ************************
* 秒が変わったときの動作(デジタル時計モード)
************************ */
private function secondsListener(e:Event):void{
changeNumber(4,_clock.seconds2.charAt(0));
changeNumber(5,_clock.seconds2.charAt(1));
}
/* ************************
* 秒が変わったとき(ラーメンタイマーモード)
************************ */
private function noodlesTimer(e:Event):void{
if(count>0){
count--;
}
//3分以上
if(count/60 >= 3){
changeNumber(3,"3");
}
//2:00から2:59
else if(count/60 >= 2 && count/60 < 3){
changeNumber(3,"2");
if(count-120>=10){
changeNumber(4,(count-60*2).toString().charAt(0));
changeNumber(5,(count-60*2).toString().charAt(1));
}else{
changeNumber(4,"0");
changeNumber(5,(count-60*2).toString().charAt(0));
}
}
//1:00から1:59
else if(count/60 >= 1 && count/60 < 2){
changeNumber(3,"1");
if(count-60>=10){
changeNumber(4,(count-60).toString().charAt(0));
changeNumber(5,(count-60).toString().charAt(1));
}else{
changeNumber(4,"0");
changeNumber(5,(count-60).toString().charAt(0));
}
}
//0:01から0:59
else if(count/60 > 0 && count/60 < 1){
changeNumber(3,"0");
if(count>=10){
changeNumber(4,count.toString().charAt(0));
changeNumber(5,count.toString().charAt(1));
}else{
changeNumber(4,"0");
changeNumber(5,count.toString().charAt(0));
}
}
//0:00
else if(count<=0){
_clock.removeEventListener(TeraClock.SECONDS_CHANGED, noodlesTimer);
changeNumber(5,"0");
for each(var digitalList:Array in digitalClock){
for each(var digital:Sprite in digitalList){
if(digital.rotation==0){
digital.x = digital.x + 25;
digital.y = digital.y - 25;
}
Tweener.addTween(digital,{time:1,delay:0,rotation:90});
}
}
_clock.addEventListener(TeraClock.SECONDS_CHANGED, timeComplete);
}
}
/* ************************
* 秒が変わったとき(タイマー完了)
************************ */
private function timeComplete(e:Event):void{
var i:int = 0;
for each(var digitalList:Array in digitalClock){
for each(var digital:Sprite in digitalList){
Tweener.addTween(digital,{time:0.1,delay:i*0.1,alpha:0});
Tweener.addTween(digital,{time:0.1,delay:i*0.1+0.1,alpha:1});
i++;
}
}
}
/* ************************
* 時が変わったときの動作(アナログ時計モード)
************************ */
private function analogHoursListener(e:Event):void{
hour.rotation = _clock.hoursDegree-90;
}
/* ************************
* 分が変わったときの動作(アナログ時計モード)
************************ */
private function analogMinutesListener(e:Event):void{
minute.rotation = _clock.minutesDegree-90;
}
/* ************************
* 秒が変わったときの動作(アナログ時計モード)
************************ */
private function analogSecondsListener(e:Event):void{
second.rotation = _clock.secondsDegree-90;
}
/* ************************
* 数字を変える
************************ */
private function changeNumber(pos:int,num:String):void{
for(var i:int=0;i<7;i++){
if(TimerUtil.number(num)[i]){
digitalClock[pos][i].alpha = 1;
}else{
digitalClock[pos][i].alpha = 0;
}
}
}
}
}
class TimerUtil {
//各数字をあらわす配列
private static const N0:Array = new Array(true,true,true,false,true,true,true);
private static const N1:Array = new Array(false,true,false,false,false,true,false);
private static const N2:Array = new Array(true,true,false,true,true,false,true);
private static const N3:Array = new Array(true,true,false,true,false,true,true);
private static const N4:Array = new Array(false,true,true,true,false,true,false);
private static const N5:Array = new Array(true,false,true,true,false,true,true);
private static const N6:Array = new Array(true,false,true,true,true,true,true);
private static const N7:Array = new Array(true,true,true,false,false,true,false);
private static const N8:Array = new Array(true,true,true,true,true,true,true);
private static const N9:Array = new Array(true,true,true,true,false,true,true);
//数字のデータを格納するハッシュ
private static var numberList:Object = {0:N0,1:N1,2:N2,3:N3,4:N4,5:N5,6:N6,7:N7,8:N8,9:N9};
//数値を表す配列を返す
public static function number(num:String):Array{
return numberList[num];
}
}
import flash.display.Sprite;
import flash.events.Event;
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]};
}
}