<?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="createEditor();" backgroundGradientColors="[0x00ff00, 0x0000ff]"> <mx:Script> <![CDATA[ // イベント概要,エントリー規約をご確認ください // http://wonderfl.net/event/felica // see http://wonderfl.net/event/felica for contest regulation, only in Japanese for now, sorry // copyright sony corp. all rights reserved. // copied from http://www.felicalauncher.com/sdk4air/#menu_02 with permission :-) 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.NFCType3TagRequest; import com.sony.jp.felica.NFCType3TagResponse; import com.sony.jp.felica.event.FeliCaStatusEvent; import com.sony.jp.felica.event.OpenStatusEvent; import flash.display.BitmapData; import flash.display.MovieClip; import flash.display.Sprite; import flash.events.MouseEvent; import flash.events.TimerEvent; import flash.utils.ByteArray; import mx.core.UIComponent; private const SIZE:uint = 16; private const MAP_X_LEN:uint = 16; private const MAP_Y_LEN:uint = 13; private var fCtrl:FeliCaControl = null; private var bmd:BitmapData = null; private var selectColor:uint = 0x000000; private var t:Timer = new Timer(300); private var readTimer:Timer = new Timer(1000 * 60); private var isFirstRead:Boolean = false; private var colorPal:Object = [ {0x000000 : "!"}, {0x0000ff : "#"}, {0x0033ff : "$"}, {0x0066ff : "%"}, {0x0099ff : "&"}, {0x00ccff : "'"}, {0x00ffff : "("}, {0x000099 : ")"}, {0x009999 : ","}, {0x00cc99 : "-"}, {0x00ff99 : "."}, {0x000099 : "/"}, {0x003399 : "0"}, {0x006699 : "1"}, {0x3300ff : "2"}, {0x3333ff : "3"}, {0x3366ff : "4"}, {0x3399ff : "5"}, {0x33ccff : "6"}, {0x33ffff : "7"}, {0x330099 : "8"}, {0x333399 : "9"}, {0x336699 : ":"}, {0x339999 : ";"}, {0x33cc99 : "<"}, {0x33ff99 : "="}, {0x330033 : ">"}, {0x333333 : "?"}, {0x336633 : "@"}, {0x339900 : "A"}, {0x33cc00 : "B"}, {0x33ff00 : "C"}, {0x6600ff : "D"}, {0x6633ff : "E"}, {0x6666ff : "F"}, {0x6699ff : "G"}, {0x66ccff : "H"}, {0x66ffff : "I"}, {0x660066 : "J"}, {0x663366 : "K"}, {0x666666 : "L"}, {0x669966 : "M"}, {0x66cc66 : "N"}, {0x66ff66 : "O"}, {0x990099 : "P"}, {0x993399 : "Q"}, {0x996699 : "R"}, {0x999999 : "S"}, {0x99cc99 : "T"}, {0x99ff99 : "U"}, {0x990000 : "V"}, {0x993300 : "W"}, {0x996600 : "X"}, {0x999900 : "Y"}, {0x99cc00 : "Z"}, {0x99ff00 : "["}, {0xcc00ff : "\\"}, {0xcc33ff : "]"}, {0xcc66ff : "^"}, {0xcc99ff : "_"}, {0xccccff : "`"}, {0xccffff : "a"}, {0xcc0066 : "b"}, {0xcc3366 : "c"}, {0xcc6666 : "d"}, {0xcc9966 : "e"}, {0xcccc66 : "f"}, {0xccff66 : "g"}, {0xff00ff : "h"}, {0xff33ff : "i"}, {0xff66ff : "j"}, {0xff99ff : "k"}, {0xffccff : "l"}, {0xffffff : "m"}, {0xff0000 : "n"}, {0xff3300 : "o"}, {0xff6600 : "p"}, {0xff9900 : "q"}, {0xffcc00 : "r"}, {0xffff00 : "s"}, {0xFFCC66 : "*"}, {0xFFFF99 : "+"}, {0x00FF00 : "t"}, {0x00CC00 : "u"}, {0x009900 : "v"}, {0x006600 : "w"}, {0x003300 : "x"}, {0x00FF33 : "y"}, {0x009933 : "z"}, {0x666666 : "{"}, {0x999999 : "|"}, {0xCCCCCC : "}"}, {0x333333 : "~"}]; private var colorDataArray:Array = [ ["!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!"], ["!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!"], ["!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!"], ["!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!"], ["!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!"], ["!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!"], ["!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!"], ["!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!"], ["!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!"], ["!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!"], ["!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!"], ["!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!"], ["!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!", "!"], ]; private var dotoArray:Array = new Array(); private function createEditor():void { var uc:UIComponent = new UIComponent(); for (var i:uint = 0; i < MAP_Y_LEN; i++) { for (var j:uint = 0; j < MAP_X_LEN; j++) { var dt:Sprite = getDoto(j, i); dotoArray.push(dt); uc.addChild(dt); } } var palWidthCount:uint = SIZE + 1 + 8; var palY:uint = 0; var palX:uint = SIZE + 1; var isEligible:Boolean = false; for each (var p:Object in colorPal) { for (var c:* in p) { if (c == 0x666666 || c == 0xff3300 || c == 0x663366) { isEligible = true; break; } uc.addChild(getPal(palX, palY, uint(c))); } if (isEligible) { isEligible = false; continue; } if (palX > palWidthCount) { palX = SIZE + 1; palY++; } else { palX++; } } uc.width = SIZE * 20; uc.height = SIZE * 20; addChild(uc); bmd = new BitmapData(width, height, false, 0xFFFFFFFF); bmd.draw(uc); readFeliCa(); } private function getDoto(px:uint , py:uint):Sprite { var sp:Sprite = new Sprite(); sp.x = px * SIZE; sp.y = py * SIZE; sp.graphics.lineStyle(1, 0xFFFFFF); sp.graphics.beginFill(0x000000); sp.graphics.drawRect(0, 0, SIZE, SIZE); sp.graphics.endFill(); sp.addEventListener(MouseEvent.MOUSE_DOWN, onDotoMouseEventHandler); return sp; } private function getPal(px:uint , py:uint, c:uint):Sprite { var sp:Sprite = new Sprite(); sp.x = (px * SIZE) + px + 1; sp.y = (py * SIZE) + py + 1; sp.graphics.beginFill(c); sp.graphics.drawRect(0, 0, SIZE, SIZE); sp.graphics.endFill(); sp.addEventListener(MouseEvent.MOUSE_DOWN, onPalClickHandler); return sp; } private function onPalClickHandler(event:MouseEvent):void { if (event.target is UIComponent) { return; } selectColor = bmd.getPixel(stage.mouseX, stage.mouseY); } private function onDotoMouseEventHandler(event:MouseEvent):void { if (event.target is UIComponent) { return; } if (stage.mouseX >= SIZE * MAP_X_LEN || stage.mouseY >= SIZE * MAP_Y_LEN) { return; } readTimer.stop(); var sp:Sprite = event.target as Sprite; sp.graphics.lineStyle(1, 0xFFFFFF); sp.graphics.beginFill(selectColor); sp.graphics.drawRect(0, 0, SIZE, SIZE); sp.graphics.endFill(); var px:uint = stage.mouseX / SIZE; var py:uint = stage.mouseY / SIZE; for each (var p:Object in colorPal) { var colorStr:String = p[selectColor]; if (colorStr) { var data:Array = colorDataArray[py]; data[px] = colorStr; colorDataArray[py] = data; } } removeEventListener(MouseEvent.MOUSE_DOWN, onDotoMouseEventHandler); addEventListener(MouseEvent.MOUSE_UP, onMouseUpEventHandler); addEventListener(MouseEvent.MOUSE_MOVE, onDotoMouseEventHandler); } private var isWrite:Boolean = false; private var isRead:Boolean = false; private function onMouseUpEventHandler(event:MouseEvent):void { addEventListener(MouseEvent.MOUSE_DOWN, onDotoMouseEventHandler); removeEventListener(MouseEvent.MOUSE_UP, onMouseUpEventHandler); removeEventListener(MouseEvent.MOUSE_MOVE, onDotoMouseEventHandler); if (!isWrite) { isWrite = true; t.addEventListener(TimerEvent.TIMER, onWriteHandler); t.start(); } readTimer.start(); } private function onReadHandler(e:TimerEvent):void { if (!isRead && !isWrite) { readTimer.removeEventListener(TimerEvent.TIMER, onReadHandler); readFeliCa(); isRead = true; } } private function onWriteHandler(e:TimerEvent):void { writeFeliCa(); t.stop(); t.removeEventListener(TimerEvent.TIMER, onWriteHandler); } private var out:String = ""; private function drawReadData():void { var isLoad:Boolean = false; for (var i:uint = 0; i < out.length; i++) { var cData:String= out.substr(i, 1); var colorIndex:uint = i / MAP_X_LEN; var data:Array = colorDataArray[colorIndex]; data[i % MAP_X_LEN] = cData; colorDataArray[colorIndex] = data; isLoad = false; for each (var p:Object in colorPal) { if (isLoad) { break; } for (var c:* in p){ if (p[c] == cData) { var sp:Sprite = dotoArray[i]; sp.graphics.lineStyle(1, 0xFFFFFF); sp.graphics.beginFill(c); sp.graphics.drawRect(0, 0, SIZE, SIZE); sp.graphics.endFill(); isLoad = true; break; } } } } out = ""; } private function mainFeliCa():void { info.text = ""; var port:uint = 10250; // インスタンス生成 fCtrl = new FeliCaControl(); // 接続前にイベント登録 fCtrl.addEventListener(OpenStatusEvent.OPEN_FAILURE, onFailureHandler); fCtrl.addEventListener(OpenStatusEvent.OPEN_COMPLETE, onCompleteHandler); fCtrl.open(port, "__FELICA_STANDARD_KEY__", ""); //fCtrl.open(port); info.text += "OPEN中\n"; } private function onCompleteHandler(event:OpenStatusEvent):void { removeEvents(); configureEventListeners(); doOpenRW(); info.text += "OPEN正常\n"; } /** * リーダライタの読み込み開始 */ private function doOpenRW():void { info.text += "リーダー/ライタOPEN\n"; fCtrl.access(new FeliCaOpenReaderWriterAutoRequest()); } private function configureEventListeners(isAdd:Boolean = true):void { if (isAdd) { // リスナー登録 fCtrl.addEventListener(FeliCaStatusEvent.FELICA_ACCESS_COMPLETE, onFeliCaAccessComplete); fCtrl.addEventListener(FeliCaStatusEvent.FELICA_ACCESS_FAILURE, onFeliCaAccessFailure); fCtrl.addEventListener(FeliCaStatusEvent.FELICA_ACCESS_PARAMETER_ERROR, onFeliCaAccessParameterError); } else { // リスナー削除 fCtrl.removeEventListener(FeliCaStatusEvent.FELICA_ACCESS_COMPLETE, onFeliCaAccessComplete); fCtrl.removeEventListener(FeliCaStatusEvent.FELICA_ACCESS_FAILURE, onFeliCaAccessFailure); fCtrl.removeEventListener(FeliCaStatusEvent.FELICA_ACCESS_PARAMETER_ERROR, onFeliCaAccessParameterError); } } private function onFeliCaAccessFailure(event:FeliCaStatusEvent):void { info.text += event.object + "\n"; fCtrl.close(); if (!readTimer.hasEventListener(TimerEvent.TIMER)) { readTimer.addEventListener(TimerEvent.TIMER, onReadHandler); readTimer.stop(); readTimer.start(); } isWrite = false; isRead = false; } private function onFeliCaAccessParameterError(event:FeliCaStatusEvent):void { info.text += event.object + "\n"; fCtrl.close(); if (!readTimer.hasEventListener(TimerEvent.TIMER)) { readTimer.addEventListener(TimerEvent.TIMER, onReadHandler); } isWrite = false; isRead = false; } private function onFeliCaAccessComplete(event:FeliCaStatusEvent):void { const o:Object = event.object; if (o is FeliCaOpenReaderWriterAutoResponse) { info.text += "ポーリング開始\n"; doPolling(); return; } onFeliCaHandler(event); } /** * ポーリング実行 */ private function doPolling():void { var request:FeliCaPollingAndGetCardInformationRequest = new FeliCaPollingAndGetCardInformationRequest(); request.systemCode = "FFFF"; fCtrl.access(request); } private function onFailureHandler(event:OpenStatusEvent):void { fCtrl.close(); info.text += event.object + "\n"; isWrite = false; isRead = false; if (!readTimer.hasEventListener(TimerEvent.TIMER)) { readTimer.addEventListener(TimerEvent.TIMER, onReadHandler); } } private const FELICA_R:uint = 0; private const FELICA_W:uint = 1; private var accessFeliCa:int = -1; private function readFeliCa():void { isRead = true; accessFeliCa = FELICA_R; mainFeliCa(); } private function writeFeliCa():void { readTimer.stop(); readTimer.removeEventListener(TimerEvent.TIMER, onReadHandler); accessFeliCa = FELICA_W; mainFeliCa(); } private function createByte():String { //rBtn.visible = wBtn.visible = false; var data:String = ""; for (var i:uint = 0; i < colorDataArray.length; i++) { data+=colorDataArray[i].join(""); } info.text += "書き込み対象データ" + data + "\n"; const b:ByteArray = new ByteArray(); b.writeUTFBytes(data); var result:String = ""; var temp:String; for (i = 0; i < b.length; i++) { temp = b[i].toString(16); if (temp.length != 2) { temp = "0" + temp; } result += temp; } info.text += "書き込み対象データ" + result + "\n"; return result; } /** * カード専有開始 * @param event FeliCaHoldEvent */ private function onFeliCaHandler(event:FeliCaStatusEvent):void { const o:Object = event.object; if (o as FeliCaPollingAndGetCardInformationResponse) { var req:FeliCaPollingAndGetCardInformationResponse = o as FeliCaPollingAndGetCardInformationResponse; removeEventListener(FeliCaStatusEvent.FELICA_ACCESS_COMPLETE, onFeliCaHandler); switch (accessFeliCa) { case FELICA_R : doNfcType3TagRead(); break; case FELICA_W : doNfcType3TagWrite(); break; } } // 発表Point1 // NFCType3TagResponseによるレスポンス if (o is NFCType3TagResponse) { // NFCType3TagReponseの型キャスト var response:NFCType3TagResponse = o as NFCType3TagResponse; // カード読み込みの場合 if (response.type == NFCType3TagResponse.READ) { info.text += "読み込み完了\n"; // カードに保存している情報を取得 var readData:String = response.data; // 情報は文字コードを16進数(0xなし)で保持している為、 // 2文字後とに読み込む為のステップ値 var nextData:uint = 2; // 読み込みの文字コードから文字に変換していく。 for (var i:uint=0; i < readData.length; i +=nextData) { var c:uint = uint("0x" + readData.substring(i, (i + nextData))); var charStr:String = String.fromCharCode(c); out+=charStr; } info.text +="data =>" + out + "\n"; // 画面に表示反映 drawReadData(); if (!isFirstRead) { readTimer.addEventListener(TimerEvent.TIMER, onReadHandler); readTimer.start(); isFirstRead = true; } isRead = false; if (!readTimer.hasEventListener(TimerEvent.TIMER)) { readTimer.addEventListener(TimerEvent.TIMER, onReadHandler); } fCtrl.close(); // カード書き込みの場合 } else if (response.type == NFCType3TagResponse.WRITE) { info.text +="書き込み完了\n"; isWrite = false; if (!readTimer.hasEventListener(TimerEvent.TIMER)) { readTimer.addEventListener(TimerEvent.TIMER, onReadHandler); readTimer.start(); } fCtrl.close(); } rBtn.visible = wBtn.visible = true; } } private function doNfcType3TagRead():void { // NFC Type3 Tag のデータを読み込みする為の情報の設定 var request:NFCType3TagRequest = new NFCType3TagRequest(); request.type = NFCType3TagRequest.READ; // NFC Type3 Tag データを読み込み要求 // NFC Type3 Tag データの読み込みを実行 fCtrl.access(request); } private function doNfcType3TagWrite():void { // NFC Type3 Tag のデータを読み込みする為の情報の設定 var request:NFCType3TagRequest = new NFCType3TagRequest(); request.type = NFCType3TagRequest.WRITE; // NFC Type3 Tag データを読み込み要求 request.data = createByte(); info.text +="書き込み対象データ" + request.data + "\n"; // NFC Type3 Tag データの読み込みを実行 fCtrl.access(request); } private function onKickBrowser():void{ var url:URLRequest = new URLRequest("http://mossamina.blog99.fc2.com/blog-entry-15.html"); navigateToURL(url, "_blank"); } private function onKickBrowser2():void{ var url:URLRequest = new URLRequest("http://mossamina.blog99.fc2.com/blog-entry-19.html"); navigateToURL(url, "_blank"); } private function removeEvents():void { fCtrl.removeEventListener(OpenStatusEvent.OPEN_COMPLETE, onCompleteHandler); fCtrl.removeEventListener(OpenStatusEvent.OPEN_FAILURE, onFailureHandler); fCtrl.removeEventListener(FeliCaStatusEvent.FELICA_ACCESS_COMPLETE, onFeliCaAccessComplete); fCtrl.removeEventListener(FeliCaStatusEvent.FELICA_ACCESS_FAILURE, onFeliCaAccessFailure); fCtrl.removeEventListener(FeliCaStatusEvent.FELICA_ACCESS_PARAMETER_ERROR, onFeliCaAccessParameterError); } ]]> </mx:Script> <mx:Button id="wBtn" x="116" y="217" label="カード書き込み" height="55" click="writeFeliCa();"/> <mx:Button id="rBtn" x="10" y="217" label="カード読み込み" height="55" click="readFeliCa();"/> <mx:Button id="wBtn0" x="10" y="280" label="wonderfl de プニョ×2 デビュー" height="55" click="onKickBrowser();" width="202"/> <mx:Button id="wBtn1" x="10" y="343" label="wonderfl de ゲーム デビュー" height="55" click="onKickBrowser2();" width="202"/> <mx:TextArea id="info" x="290" y="217" text="" width="150" height="181" color="0x000000" editable="false" /> </mx:Application> ドットフ絵リカ(ドットフェリカと読む) for wonderfl