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

forked from: FeliCa Flash Contest - FeliCa Search sample

複数のFeliCaを使って図形を描画します。

(一回りを勤務時間にして、休憩や作業時間のビジュアル化を試みたのですが、実用的なレベルまでになってないです。)
/*
   複数のFeliCaを使って図形を描画します。

   (一回りを勤務時間にして、休憩や作業時間のビジュアル化を試みたのですが、実用的なレベルまでになってないです。)
 */
package {
	import com.sony.jp.felica.FeliCaCloseReaderWriterRequest;
	import com.sony.jp.felica.FeliCaCloseReaderWriterResponse;
	import com.sony.jp.felica.FeliCaControl;
	import com.sony.jp.felica.FeliCaOpenReaderWriterAutoRequest;
	import com.sony.jp.felica.FeliCaOpenReaderWriterAutoResponse;
	import com.sony.jp.felica.FeliCaPollingAndGetCardInformationRequest;
	import com.sony.jp.felica.FeliCaPollingAndGetCardInformationResponse;
	import com.sony.jp.felica.FeliCaSessionRequest;
	import com.sony.jp.felica.FeliCaSessionResponse;
	import com.sony.jp.felica.error.FeliCaAccessError;
	import com.sony.jp.felica.event.FeliCaStatusEvent;
	import com.sony.jp.felica.event.OpenStatusEvent;

	import flash.display.Graphics;
	import flash.display.MovieClip;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;
	import flash.text.TextFormat;
	import flash.utils.clearInterval;
	import flash.utils.setInterval;

	[SWF(width="465", height="465", backgroundColor="#111111", frameRate="60")]
	public class FeliCaContest extends MovieClip {
		private const TIMESCALE:int = 30;
		private var txtLog:TextField = new TextField();
		private var logFormat:TextFormat = new TextFormat();

		public function FeliCaContest() {
			trace("###################");
			format.color = 0xDDDDDD;

			txtIDm.text = "txtIDm:";
			txtIDm.autoSize = TextFieldAutoSize.LEFT;
			txtIDm.defaultTextFormat = format;
			txtIDm.x = 10;
			txtIDm.y = 10;
			this.addChild(txtIDm);

			this.logFormat.color = 0x333333;
			this.logFormat.size = 9;
			txtLog.text = "";
			txtLog.autoSize = TextFieldAutoSize.LEFT;
			txtLog.defaultTextFormat = logFormat;
			txtLog.x = this.stage.stageWidth / 2;
			txtLog.y = 10;
			this.addChild(txtLog);

			graphInit();
			init();
			pollingStart();
		}
		private var counter:int = 1;

		//	エラー情報
		private var error:Object = {felica: "0", rw: "0", proxy: "0"};

		//	連続 Polling 終了フラグ
		private var exitPollingFlag:Boolean = false;
		//	FeliCaProxy との通信を行うコントロールクラス
		private var fc:FeliCaControl = new FeliCaControl();
		private var format:TextFormat = new TextFormat();
		private var g:Graphics;
		private var g2:Graphics;
		private var idm:String; //Felica製造ID
		private const r:int = 200; //半径
//		private var runFlag:Boolean = false;

		private var s:Sprite;
		private var s2:Sprite;


		//		private var textArea1:TextField = new TextField();
		private var txtIDm:TextField = new TextField();
		private var txtPMm:TextField = new TextField();

		//	連続 Polling を行なう間隔に対する一意の数値識別子(呼び出しID)
		private var waitIntervalId:uint = 0;

		//	FeliCaProxy の切断
		private function FeliCaProxyClose():void {
			if(fc.close() == true) {
				displayMessage("FeliCaProxy との接続を切断しました。");
			} else {
				displayMessage("FeliCaProxy との接続を切断に失敗しました。");
			}
			idm = null;
		}

		/**
		 * FeliCa を検出するために、Polling の実行
		 */
		private function Polling():void {
			//	[polling_and_get_card_information] コマンドを実行する為の情報の設定
			var request:FeliCaPollingAndGetCardInformationRequest = new FeliCaPollingAndGetCardInformationRequest();

			request.systemCode = "FFFF"; // ポーリングするシステムコード

			//	[polling_and_get_card_information] コマンドを実行
			fc.access(request);
		}

		//	リーダ/ライタのクローズを実行
		private function RwClose():void {
			//	[close_reader_writer] コマンドを実行
			fc.access(new FeliCaCloseReaderWriterRequest());
		}

		//	リーダ/ライタの専有を実行
		private function RwLock():void {
			//	リーダ/ライタを専有する為の情報の設定
			var request:FeliCaSessionRequest = new FeliCaSessionRequest();

			request.type = FeliCaSessionRequest.HOLD; // リーダ・ライタ専有要求
			request.lockTimeout = 10; // 専有(Lock)するまでのタイムアウト時間(秒)
			request.unlockTimeout = 60; // 専有(Lock)してから開放(Unlock)するまでの見込み時間(秒) 
			// FeliCaProxyは、このunlockTimeout時間経過した場合自動でR/W開放を行う。

			//	リーダ/ライタ専有を実行
			fc.access(request);
		}

		//	リーダ/ライタのオープンを実行
		private function RwOpen():void {
			//	[open_reader_writer_auto] コマンドを実行
			fc.access(new FeliCaOpenReaderWriterAutoRequest());
		}

		//	リーダ/ライタ専有の開放を実行
		private function RwUnlock():void {
			//	リーダ/ライタ専有を開放する為の情報の設定
			var request:FeliCaSessionRequest = new FeliCaSessionRequest();

			request.type = FeliCaSessionRequest.RELEASE; // リーダ・ライタ開放要求

			//	リーダ/ライタ専有開放を実行
			fc.access(request);
		}

		private function clickHandler(e:MouseEvent = null):void {
			trace("clickHandler");
			if(exitPollingFlag == false) {
				//	連続 Polling 終了フラグのセット
				this.exitPollingFlag = true;

			} else {
				this.txtLog.text = "";
				counter = 0;
				reStart();
				resetGraph();
			}

		}

		//	[FeliCa を検出を開始する] ボタンクリック時
		private function reStart():void {
			//	連続 Polling 終了フラグの初期化
			this.exitPollingFlag = false;


			//	連続 Polling を行なう間隔に対する一意の数値識別子の初期化
			this.waitIntervalId = 0;

			fcOpen();
		}

		//	メッセージの表示
		private function displayMessage(msg:String):void {
			trace(msg);
		}

		private function drawTriangle(x1:int, y1:int, x2:int, y2:int, x3:int, y3:int, c:uint):void {
			g.beginFill(c);
			g.moveTo(x1, y1);
			g.lineTo(x2, y2);
			g.lineTo(x3, y3);
			g.lineTo(x1, y1);
		}

		private function enterFrameHandler(e:Event):void {
			//			trace("enterFrameHandler");
			//trace(i % 180)
			if(counter % (360 * TIMESCALE) == 0) {
				//	連続 Polling 終了フラグのセット
				this.exitPollingFlag = true;

//				runFlag = false;
			}
			if(exitPollingFlag == false) {

				if(counter % 360 == 0) {
					resetGraph();
				}

				g2.lineTo(Math.cos(counter * Math.PI / 180) * r, Math.sin(counter * Math.PI / 180) * r);
				//g.moveTo(0,0);
				//g.lineTo(Math.sin(i* Math.PI / 180)*r,Math.cos(i* Math.PI / 180)*r);
				//radian = from 0 to Math.PI *2
				if(counter % TIMESCALE == 0) {
					var c:int = counter / TIMESCALE;
					var x1:int = Math.cos((c - 1) * Math.PI / 180) * r;
					var y1:int = Math.sin((c - 1) * Math.PI / 180) * r;
					var x2:int = Math.cos(c * Math.PI / 180) * r;
					var y2:int = Math.sin(c * Math.PI / 180) * r;

					if(idm != null) {
						var n:Number = Number("0x" + idm) >> 12 & 0xffffff;
						drawTriangle(0, 0, x1, y1, x2, y2, n);
					}
				}
			}
			counter++;

		}

		/**
		 * 連続 Polling 実行待ち合わせ完了時
		 */
		private function execPolling():void {
			//	指定した setInterval() 呼び出しをキャンセル
			clearInterval(this.waitIntervalId);

			//	FeliCa を検出するために、Polling の実行
			Polling();
		}

		private function graphInit():void {
//			runFlag = true;

			s = new Sprite();
			g = s.graphics;
			s2 = new Sprite();
			g2 = s2.graphics;

			s2.x = this.stage.stageWidth / 2;
			s2.y = this.stage.stageHeight / 2;
			this.addChild(s2);

			s.x = this.stage.stageWidth / 2;
			s.y = this.stage.stageHeight / 2;
			this.addChild(s);

			resetGraph();
		}

		private function init():void {
			fc.addEventListener(OpenStatusEvent.OPEN_COMPLETE, onOpenComplete);
			fc.addEventListener(OpenStatusEvent.OPEN_FAILURE, onOpenFailure);
			fc.addEventListener(FeliCaStatusEvent.FELICA_ACCESS_COMPLETE, onFeliCaAccessComplete);
			fc.addEventListener(FeliCaStatusEvent.FELICA_ACCESS_FAILURE, onFeliCaAccessFailure);
			fc.addEventListener(FeliCaStatusEvent.FELICA_ACCESS_PARAMETER_ERROR, onFeliCaAccessParameterError);
		}

		/**
		 *	次の実行処理を行なう
		 *		連続 Polling をそのまま行なうか
		 *		連続 Polling を終了してリーダ/ライタのクローズを行なう
		 */
		private function nextProcess():void {
			if(this.exitPollingFlag == true) {
				//	リーダ/ライタのクローズを実行
				RwClose();
			} else {
				//	次の Polling まで 500 ミリ秒待ち合わせる
				this.waitIntervalId = setInterval(execPolling, 500);
			}
		}

		/**
		 * FeliCa アクセス成功時
		 * @param evt
		 */
		private function onFeliCaAccessComplete(evt:FeliCaStatusEvent):void {
			this.addEventListener(Event.ENTER_FRAME, enterFrameHandler);
			this.stage.addEventListener(MouseEvent.CLICK, clickHandler);

			if(evt.object is FeliCaSessionResponse) {
				var session:FeliCaSessionResponse = evt.object as FeliCaSessionResponse;

				//	リーダ/ライタの専有
				if(session.type == FeliCaSessionResponse.HOLD) {
					displayMessage("リーダ/ライタの専有しました。");

					//	リーダ/ライタのオープンを実行
					RwOpen();
				} else {
					//	リーダ/ライタの開放
					displayMessage("リーダ/ライタの専有を開放しました。");

					//	FeliCaProxy の切断
					FeliCaProxyClose();
				}
			} else if(evt.object is FeliCaOpenReaderWriterAutoResponse) {
				displayMessage("リーダ/ライタのオープンに成功しました。");

				//	連続 Polling を終了させる関数をミリ秒単位で指定した間隔ごとに実行
				//		※ 今回は 30 秒とする
				//				this.pollingIntervalId = setInterval(exitPolling, 60*1000);

				//	FeliCa を検出するために、Polling の実行
				Polling();
			} else if(evt.object is FeliCaPollingAndGetCardInformationResponse) {
				var response:FeliCaPollingAndGetCardInformationResponse = evt.object as FeliCaPollingAndGetCardInformationResponse;

				if(idm != response.idm) {
					//	FeliCa を検出した時の画像に変更する
					//					this.imgAutoPolling.source = "./image/find.gif";

					//	検出した FeliCa の情報を表示
					idm = response.idm;
					this.txtIDm.text = response.idm;
					this.txtPMm.text = response.pmm;
					displayMessage("FeliCa を検出しました。\n" + "  idm = " + response.idm + "\n" + "  pmm = " + response.pmm);
					var d:Date = new Date();
					this.txtLog.appendText("LOGIN:" + response.idm + "(" + d.toLocaleTimeString() + ")\n");
				}

				//	エラー情報のクリア
				this.error["felica"] = response.felicaError;
				this.error["rw"] = response.rwError;
				this.error["proxy"] = response.felicaProxyError;

				//	次の実行処理を行なう
				this.nextProcess();
			} else if(evt.object is FeliCaCloseReaderWriterResponse) {
				displayMessage("リーダ/ライタのクローズに成功しました。");

				//	リーダ/ライタ専有の開放
				RwUnlock();
			}
		}

		/**
		 * FeliCa アクセス失敗時
		 * @param evt
		 */
		private function onFeliCaAccessFailure(evt:FeliCaStatusEvent):void {
			var errorMsg:String;
			if(evt.object is FeliCaAccessError) {
				var error1:FeliCaAccessError = evt.object as FeliCaAccessError;

				if(error1.rwError == 157) {
					if(error1.rwError != this.error["rw"]) {
						if(idm != null) {
							var d:Date = new Date();
							this.txtLog.appendText("LOGOUT:" + idm + "(" + d.toLocaleTimeString() + ")\n");
						}
						//	検出した FeliCa の情報を表示するテキストエリアをクリア
						idm = null;
						this.txtIDm.text = "";
						this.txtPMm.text = "";

						//	メッセージの表示
						displayMessage("FeliCa を検出できませんでした。");
					}

					//	次の実行処理を行なう
					this.nextProcess();
				} else {
					if((this.error["felica"] != error1.felicaError) || (this.error["rw"] != error1.rwError) || (this.error["proxy"] != error1.felicaProxyError)) {
						//	エラー情報の表示
						errorMsg = "   ERROR: (" + error1.errorID + ")" + error1.message + "\n" + "     FeliCa Error Code (" + error1.felicaError + ")\n" + "     RW Error Code (" + error1.rwError + ")\n" + "     FeliCaProxy Error Code (" + error1.felicaProxyError + ")";
						displayMessage("FeliCa アクセスに失敗しました\n" + errorMsg);
					}
				}

				//	エラー情報のセット
				this.error["felica"] = error1.felicaError;
				this.error["rw"] = error1.rwError;
				this.error["proxy"] = error1.felicaProxyError;
			} else if(evt.object is Error) {
				var error2:Error = evt.object as Error;

				//	エラー情報の表示
				errorMsg = "   ERROR : (" + error2.errorID + ") " + error2.message;
				displayMessage("FeliCa アクセスに失敗しました\n" + errorMsg);

				//	FeliCaProxy の切断
				FeliCaProxyClose();
			}
		}

		/**
		 * FeliCa アクセスパラメータ設定エラー発生時
		 * @param evt
		 */
		private function onFeliCaAccessParameterError(evt:FeliCaStatusEvent):void {
			var error:Error = evt.object as Error;
			displayMessage("FeliCa アクセスでパラメータエラーが発生しました。\n" + "   ERROR: (" + error.errorID + ")" + error.message);

			//	FeliCaProxy の切断
			FeliCaProxyClose();
		}

		/**
		 * FeliCaProxy との認証完了時
		 * @param evt
		 */
		private function onOpenComplete(evt:OpenStatusEvent):void {
			displayMessage("FeliCaProxy との認証に成功しました。");

			//	リーダ/ライタの専有
			RwLock();
		}

		/**
		 * FeliCaProxy との認証処理でエラー発生時
		 * @param evt
		 */
		private function onOpenFailure(evt:OpenStatusEvent):void {
			var error:Error = evt.object as Error;
			displayMessage("FeliCaProxy との相互認証に失敗しました。\n" + "   ERROR : (" + error.errorID + ") " + error.message);

		}

		//	[FeliCa を検出を開始する] ボタンクリック時
		private function pollingStart():void {
			//	連続 Polling 終了フラグの初期化
			this.exitPollingFlag = false;


			//	連続 Polling を行なう間隔に対する一意の数値識別子の初期化
			this.waitIntervalId = 0;
			fcOpen();
		}
		private function fcOpen():void{
			//	FeliCaProxy の認証
			//fc.open(10250);
			fc.open(10250, "__FELICA_STANDARD_KEY__", "");
		}
		private function resetGraph():void {
//			trace(counter);
			if(exitPollingFlag == false) {
				g2.clear();
				g2.lineStyle(1, 0xffffff);
				g2.moveTo(r, 0);
				if(counter % (TIMESCALE * 360) == 0) {
					counter = 1;
					g.clear();
					g.moveTo(r, 0);
				}
			}

		}
	}
}