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

ジャポニ〜ニョ♪

大人の科学マガジンVol.27のジャパニーノを使用した簡単なゲームです。
必要な周辺機器:ジャパニーノ, カメラ 
検証機:MacBook, ジャパニーノ,iSight 
ゲームの内容
左から右へ横切る人面魚を画面から消える前に釣ることがゲームの目的となります。
進行:
1. 撮影モード:
ここではゲームに出演する人面魚を作成します。
人面魚の顔の輪郭に合わせて位置調整します。
ジャパニーノを回すと人面魚が作成します。
決定有無の選択はジャパニーノを回して選択。
決定はマウスをクリックしてください。
2. ゲームモード: 
魚と人面魚を左から右へ横切ってます。
一番画面下にいる人面魚を釣るとゲームクリアです。
操作方法:
画面上部の黒い●を←→キーを押下すると移動しつづけます。
ジャパニーノを回すと●から縦線を引かれます。
縦線の一番下位置に魚が触れると魚が釣られた状態になります。
そのままジャパニーノを回すと魚は釣り上がっていきます。
縦線に魚が触れると線がなくなります。
3. 魚拓モード(ツイッター):
人面魚を釣りきると魚拓モードに遷移します。
ここで公開決定有無をジャパニーノを回して選択します。
決定はマウスクリックで行います。
公開すると魚拓の画像データが、サーバにアップします。
サーバにアップ後、公開した魚拓が参照できます。
つぶやく可能なリンクをクリックすると
ツイートのテキスト入力した状態でツイッターのサイトに
遷移します。(この状態は、まだつぶやいてません。)
ツイッターのツイートボタンをクリックするとつぶやかれます。
※ 魚拓の画像の削除機能はありません。ツイッターのテキスト
入力では、画像URLがございますので、画像URLをお知らせ
いただきましたら、削除させていただきます。
mail:tokufxug@gmail.com
twitter:@tokufxug
参考:セットアップ方法の詳細に関しては、以下のページでの説明を
参照してください。
大人の科学マガジンVol.27
http://otonanokagaku.net/magazine/vol27/
wonderfl x japanino
http://wonderfl.net/event/japanino/
注意:光残像キットは、あまり激しく操作すると壊れてしまうことが
ありますので注意し
/**
 * Copyright tokufxug ( http://wonderfl.net/user/tokufxug )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/2jGw
 */

// forked from tokufxug's forked from: Japanino Fishing Example
// 
// 大人の科学マガジンVol.27のジャパニーノを使用した簡単なゲームです。
// 
// 必要な周辺機器:ジャパニーノ, カメラ 
// 検証機:MacBook, ジャパニーノ,iSight 
// 
// ゲームの内容
// 左から右へ横切る人面魚を画面から消える前に釣ることがゲームの目的となります。
// 
// 進行:
// 1. 撮影モード:
//     ここではゲームに出演する人面魚を作成します。
//     人面魚の顔の輪郭に合わせて位置調整します。
//     ジャパニーノを回すと人面魚が作成します。
//     決定有無の選択はジャパニーノを回して選択。
//     決定はマウスをクリックしてください。
// 
// 2. ゲームモード: 
//     魚と人面魚を左から右へ横切ってます。
//     一番画面下にいる人面魚を釣るとゲームクリアです。
//     操作方法:
//         画面上部の黒い●を←→キーを押下すると移動しつづけます。
//         ジャパニーノを回すと●から縦線を引かれます。
// 
//         縦線の一番下位置に魚が触れると魚が釣られた状態になります。
//         そのままジャパニーノを回すと魚は釣り上がっていきます。
//         縦線に魚が触れると線がなくなります。
// 
// 3. 魚拓モード(ツイッター):
//     人面魚を釣りきると魚拓モードに遷移します。
//     ここで公開決定有無をジャパニーノを回して選択します。
//     決定はマウスクリックで行います。
//     公開すると魚拓の画像データが、サーバにアップします。
//     サーバにアップ後、公開した魚拓が参照できます。
//     
//     つぶやく可能なリンクをクリックすると
//     ツイートのテキスト入力した状態でツイッターのサイトに
//     遷移します。(この状態は、まだつぶやいてません。)
//     ツイッターのツイートボタンをクリックするとつぶやかれます。
//
//    ※ 魚拓の画像の削除機能はありません。ツイッターのテキスト
//      入力では、画像URLがございますので、画像URLをお知らせ
//      いただきましたら、削除させていただきます。
//
//      mail:tokufxug@gmail.com
//      twitter:@tokufxug
//
//
// 参考:セットアップ方法の詳細に関しては、以下のページでの説明を
// 参照してください。
// 
// 大人の科学マガジンVol.27
// http://otonanokagaku.net/magazine/vol27/
// 
// wonderfl x japanino
// http://wonderfl.net/event/japanino/
// 
// 注意:光残像キットは、あまり激しく操作すると壊れてしまうことが
// ありますので注意してください。
package
{
    
    import com.adobe.images.JPGEncoder;
    
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.IOErrorEvent;
    import flash.events.KeyboardEvent;
    import flash.events.MouseEvent;
    import flash.filters.ColorMatrixFilter;
    import flash.geom.Matrix;
    import flash.geom.Point;
    import flash.geom.Rectangle;
    import flash.net.URLLoader;
    import flash.net.URLRequest;
    import flash.net.URLRequestHeader;
    import flash.net.URLRequestMethod;
    import flash.net.URLVariables;
    import flash.net.navigateToURL;
    import flash.system.Security;
    import flash.text.TextField;
    import flash.text.TextFieldAutoSize;
    import flash.text.TextFormat;
    import flash.utils.ByteArray;
    import flash.utils.Endian;
    
    import funnel.Arduino;
    import funnel.FunnelEvent;
    import funnel.i2c.HMC6343_Advanced;
    
    [SWF(width="465", height="465", frameRate="10")]
    public class Japoninyo extends Sprite
    {
        /**
         * ジャパニーノ
         */ 
        private var _j:Arduino = null;
        
        /**
         * ジャポ二〜ニョ♪BitMapデータ
         */
        private var jimenGameCharBmd:BitmapData 
        = new BitmapData(424, 301, true, 0x00ffff00);
        
        /**
         * ジャポ二〜ニョ♪BitMap
         */ 
        private var jimenGameCharBmp:Bitmap;
        
        /**
         * ジャポ二〜ニョ♪カメラ
         */
        private var jimenCamera:JinmenCamera = null;
        
        /**
         * ジャポ二〜ニョ♪の体部
         */
        private var fishTempImg:FishImage = null;
        
        /**
         * ジャポ二〜ニョ♪作成画面
         */
        private var jimenStage:JinmengyoCreateStage = null;
        
        /**
         * 現在の機能モードを保持
         */ 
        private var Mode:uint = 0;
        
        public const EDIT:uint = 0;
        public const GAME:uint = 1;
        
        
        /**
         * コンストラクタ
         */ 
        public function Japoninyo()
        {
            Security.loadPolicyFile("http://tokufxug.heteml.jp/crossdomain.xml");
            initJapanino();
        }
        
        /**
         * ジャパニーノのインスタンス作成とREADYイベントを登録
         */ 
        private function initJapanino():void {
            _j = new Arduino(Arduino.FIRMATA);
            _j.addEventListener(FunnelEvent.READY, onReadyHandler);
        }
        
        /**
         * ジャパニーノ接続完了イベント
         */ 
        private function onReadyHandler(e:FunnelEvent):void {
            createEdit();
        }
        // ----------- ジャポ二〜ニョ♪の編集画面機能
        /**
         * ジャポ二〜ニョ♪の編集機能の作成
         */ 
        private function createEdit():void {
            initEdit();
            doEditExe();
        }
        
        /**
         * ジャポ二〜ニョ♪の編集機能の初期化
         */ 
        private function initEdit():void {
            
            // Japaninoの開始イベントを削除
            _j.removeEventListener(FunnelEvent.READY, onReadyHandler);
            
            jimenCamera = new JinmenCamera(400, 400, 10);
            fishTempImg = new FishImage("http://tokufxug.heteml.jp/japoninyo/img/y.gif");
            jimenStage = new JinmengyoCreateStage();
            
            // ジャポニーニョ♪のゲーム表示用Biamapインスタンスを作成
            jimenGameCharBmp = new Bitmap(jimenGameCharBmd);
            
            // 光残像キットの全面消灯のパターン(7行×15桁)
            var pattern:Array = [
                parseInt("00111100", 2),
                parseInt("00011000", 2),
                parseInt("00100100", 2),
                parseInt("01000010", 2),
                parseInt("01000010", 2),
                parseInt("01011010", 2),
                parseInt("01101010", 2),
                parseInt("01100110", 2),
                parseInt("01000010", 2),
                parseInt("01001010", 2),
                parseInt("01000010", 2),
                parseInt("01001010", 2),
                parseInt("01000100", 2),
                parseInt("00101000", 2),
                parseInt("00110000", 2)];
            
            // パターンをカスタムのメッセージとしてJapanino二転送して表示をクリアする
            _j.sendSysexMessage(0x10, pattern);
            _j.addEventListener(FunnelEvent.FIRMATA_STRING, onCheeseHandler);
        }
        
        /**
         * 編集画面作成表示処理
         */ 
        private function doEditExe():void {
            addChild(jimenCamera);
            addChild(fishTempImg);
            addChild(jimenStage);
        }
        
        // 編集画面のカメラ停止フラグ
        private var isCheese:Boolean = false;
        
        /**
         * ジャポ二〜ニョ♪のシャッターイベント
         * @e:FunnelEvent 
         */
        private function onCheeseHandler(e:FunnelEvent):void {
            if (Mode != EDIT) {
                return;
            }
            // 1イベントだとすぐ反応してしまうため、2度目のイベントで
            // 停止と作成処理を行うよう二している
            if (!isCheese) {
                isCheese = true;
                return;
            }
            isCheese = false;
            
            // ゲームで使用するジャポ二〜ニョ♪のBitMapを作成
            createGameCharacterJinmengyo();
            
            if (e.message == "!") {
                if (jimenStage.edit) {
                    editMode();
                    stage.addEventListener(MouseEvent.CLICK, onMouseClickSelectMode);
                } else {
                    jimenStage.selectAnser();
                }
            }
        }
        
        
        /**
         * ジャポニ〜ニョ(ゲーム用)キャラクター二よる表示オブジェクトを作成
         */ 
        private function createGameCharacterJinmengyo():void {
            
            jimenGameCharBmp.scaleX = 1.0;
            jimenGameCharBmp.scaleY = 1.0;
            jimenGameCharBmp.scaleZ = 1.0;
            
            jimenGameCharBmp.scaleX*=0.25;
            jimenGameCharBmp.scaleY*=0.25;
            jimenGameCharBmp.scaleZ*=0.25;
            
            // 作成したジャポニーニョ♪の描画処理
            jimenGameCharBmd.draw(this
                ,new Matrix(1, 0, 0, 1
                    , ((430 - 424) / 2) * -1
                    , ((400 - 301) / 2) * -1)
                , null
                , "normal"
                , new Rectangle(0, 0, 424, 301)
                , false);
            
            // 描画処理後、背景色を透明二変更
            jimenGameCharBmd.floodFill(10, 10, 0x00000000);
        }
        
        private function onMouseClickSelectMode(event:MouseEvent):void {
            stage.removeEventListener(MouseEvent.CLICK, onMouseClickSelectMode);
            if (jimenStage.isYes()) {
                ///////////////////////
                // ゲームスタート
                ///////////////////////
                gameStart();
            } else {
                editMode();
            }
        }
        
        /**
         * 編集続行、編集終了の切り替え
         */ 
        private function editMode():void {
            jimenStage.edit = !jimenStage.edit;
            jimenCamera.roll();
            jimenStage.textChange();
        }
        // ----------- ジャポ二〜ニョ♪の編集画面機能
        
        // ----------- ジャポ二〜ニョ♪のゲームモード 開始
        
        // ゲームで使用するキャレクターの配列
        private var gameCharArray:Array = new Array();
        // 竿
        private var sao:Tsurizao = new Tsurizao();
        
        /**
         * ゲームスタート
         */ 
        private function gameStart():void {
            initGame();
            createGameChar();
        }
        
        /**
         * 編集中の表示リストから削除
         */ 
        private function initGame():void {
            Mode = GAME;
            // 編集中に使用していた機能は全て削除
            removeChild(jimenCamera);
            jimenCamera.removeEventListener(Event.ENTER_FRAME, 
                jimenCamera.onEnterFrameHandler);
            
            removeChild(fishTempImg);
            removeChild(jimenStage);
            
            _j.removeEventListener(FunnelEvent.FIRMATA_STRING, onCheeseHandler);
            // ジャパニーノのコントローラーイベントを作成
            _j.addEventListener(FunnelEvent.FIRMATA_STRING, onPlayJapaninoHanlder);
            // 竿のモードきりかえイベント
            stage.addEventListener(KeyboardEvent.KEY_DOWN, sao.onKey);
        }
        
        /**
         * ジャパニーノによるジャポノ〜ニョ♪の数
         */ 
        private static const CHAR_MAX:uint = 6;
        
        public var yourFish:FishImage = null;
        /**
         * 
         */ 
        private function createGameChar():void {
            
            addChild(sao);
            sao.cacheAsBitmap = true;
            sao.x = 10;
            sao.y = 10;
            
            for (var i:uint = 0; i < CHAR_MAX;i++) {
                var japFish:FishImage =  new FishImage("http://tokufxug.heteml.jp/japoninyo/img/j.png");
                japFish.init();
                addChild(japFish);
                gameCharArray.push(japFish);
            }
            
            jimenGameCharBmp.cacheAsBitmap = true;
            yourFish = new FishImage("");
            yourFish.addBitmap(jimenGameCharBmp);
            
            yourFish.y = 380;
            // yourFish.y = 20;
            
            yourFish.isYouFish = true;
            addChild(yourFish);
            gameCharArray.push(yourFish);
            addEventListener(Event.ENTER_FRAME, onNowPlay);
        }
        
        private function onNowPlay(event:Event):void {
            sao.moveX();
            for (var i:uint = 0; i < gameCharArray.length; i++) {
                var fish:FishImage = (gameCharArray[i] as FishImage);
                if (!fish.isLife) {
                    continue;
                }
                // 捕まっている
                if (fish.isCatch) {
                    sao.catchFish();
                    fish.rotation=-30;
                    fish.x = sao.x+5 - 100;
                    fish.y = sao.getLinePosY();
                    
                    // つり上げられた
                    if (fish.y <= 8) {
                        sao.initStatus();
                        removeChild(fish);
                        fish.isLife = false;
                        fish.isCatch = false;
                        // ゲームクリアイベント
                        if (fish.isYouFish) {
                            gyotakuStart();
                            return;
                        }
                    }
                    continue;
                }
                if (fish.hitTestObject(sao)) {
                    // 竿糸が接触した場合
                    if (sao.linePosY + 5 >= fish.y + 30) {
                        for (var j:uint = 0; j < gameCharArray.length; j++) {
                            var localFish:FishImage = (gameCharArray[j] as FishImage);
                            if (localFish.isLife) {
                                localFish.isCatch = false;
                                localFish.rotation = 0;
                            }
                        }
                        sao.initStatus();
                        sao.viewLine(-sao.linePosY);
                    } else {
                        var isSaoCatch:Boolean = false;
                        for (var k:uint = 0; k < gameCharArray.length; k++) {
                            var lFish:FishImage = (gameCharArray[j] as FishImage);
                            if (lFish.isCatch) {
                                isSaoCatch = true;
                                break;
                            }
                        }
                        if (!isSaoCatch) {
                            fish.isCatch = true;
                        }
                    }
                    continue;
                }
                if (fish.move()) {
                    initGyotaku();
                    var tf:TextFormat = new TextFormat();
                    tf = new TextFormat();
                    tf.font = "_typewriter";
                    tf.size = 12;
                    tf.color = 0x000000;
                    
                    var endlbl:TextField = new TextField();
                    
                    endlbl.defaultTextFormat = tf;
                    endlbl.autoSize = TextFieldAutoSize.LEFT;
                    endlbl.selectable = false;
                    endlbl.text = "おわり";
                    endlbl.x = (465 / 2) - 10;
                    endlbl.y = 465 / 2;
                    addChild(endlbl);
                }
            }
        }
        
        private function onPlayJapaninoHanlder(event:FunnelEvent):void {
            if (event.message == "!") {
                sao.move();
            }
        }
        // ----------- ジャポ二〜ニョ♪のゲームモード 終了
        
        // ----------- 魚拓モード開始
        private var nGyotakuScale:Number = 1.0;
        private var twitPicFld:TwitPicEditView = null;
        private function gyotakuStart():void {
            initGyotaku();
            gyotakuMode();
        }
        
        private function gyotakuMode():void {
            for (var x:int = 0; x < jimenGameCharBmd.width; x++) {
                for (var y:int = 0; y < jimenGameCharBmd.height; y++) {
                    var c:int = jimenGameCharBmd.getPixel(x, y);
                    c = (((c >> 16) & 255) + ((c >> 8) & 255) + (c & 255)) / 3;
                    if (c <= 0x010) {
                        jimenGameCharBmd.setPixel(x, y, 0x000000);
                    } else if (c <= 0x020) {
                        jimenGameCharBmd.setPixel(x, y, 0x111111);
                    } else if (c <= 0x030) {
                        jimenGameCharBmd.setPixel(x, y, 0x000000);
                    } else if (c <= 0x040) {
                        jimenGameCharBmd.setPixel(x, y, 0x333333);
                    } else if (c <= 0x050) {
                        jimenGameCharBmd.setPixel(x, y, 0x000000);
                    } else if (c <= 0x060) {
                        jimenGameCharBmd.setPixel(x, y, 0xFFFFFF);
                    } else if (c <= 0x070) {
                        jimenGameCharBmd.setPixel(x, y, 0xEEEEEE);
                    } else if (c <= 0x080) {
                        jimenGameCharBmd.setPixel(x, y, 0xFFFFFF);
                    } else if (c <= 0x090) {
                        jimenGameCharBmd.setPixel(x, y, 0xEEEEEE);
                    } else {
                        jimenGameCharBmd.setPixel(x, y, 0xFFFFFF);
                    }
                }
            }
            
            twitPicFld = new TwitPicEditView(this, yourFish);
            addChild(twitPicFld);
            _j.addEventListener(FunnelEvent.FIRMATA_STRING, twitPicFld.onSelectedAnserHandler);
            stage.addEventListener(MouseEvent.CLICK, twitPicFld.onMouseClick);
            
            var sc:Number = (465 - yourFish.moveX) / 465;
            sc = sc < 0.1 ? 0.1 : sc;
            sc = sc > 1.0 ? 1.0 : sc;
            // 表示
            jimenGameCharBmp.scaleX = sc;
            jimenGameCharBmp.scaleY = sc;
            jimenGameCharBmp.scaleZ = sc;
            
            // 位置
            var pos:uint = yourFish.moveX / 5;
            jimenGameCharBmp.x = pos;
            jimenGameCharBmp.y = pos;
            
            addChild(jimenGameCharBmp);
            
        }
        
        private function onUploadTwitPic():void {
            var cul:CanvasUploader = new CanvasUploader();
            cul.uploadSprite(this);
        }
        
        private function initGyotaku():void {
            removeEventListener(Event.ENTER_FRAME, onNowPlay);
            for (var i:uint = 0; i < gameCharArray.length; i++) {
                var fish:FishImage = (gameCharArray[i] as FishImage);
                if (contains(fish)) {
                    removeChild(fish); 
                }
            }
            sao.removeEventListener(KeyboardEvent.KEY_DOWN, sao.onKey);
            _j.removeEventListener(FunnelEvent.FIRMATA_STRING, onPlayJapaninoHanlder);
            
            sao.g.clear();
            removeChild(sao);
        }
        // -----------魚拓モード終了
    }
}

import flash.system.LoaderContext;
/**
 * ジャポニーニョ♪魚表示オブジェクト
 * @author tokufxug
 * http://twitter.com/tokufxug
 */
class FishImage extends Sprite {
    
    private var speed:Number = .5;
    
    // 捕まり中判定
    public var isCatch:Boolean = false;
    
    // 捕まり済判定
    public var isLife:Boolean = true;
    
    public var isYouFish:Boolean = false;
    
    public var moveX:uint = 0;
    
    public function FishImage(tURL:String) {
        if (tURL == "") {
            return;
        }
        // URLRequestクラスを 読み込むパス tURL を元二作る。
        var urImage:URLRequest = new URLRequest(tURL);
        try {
            // Loader(読込)オブジェクトを作成、設定。
            var img:Loader = new Loader();
            
            // URLRequestを読込に設定。
            img.load(urImage);
            // 表示させる。
            addChild(img);
        } catch (e:SecurityError) {
            var tf:TextFormat = new TextFormat();
            var fld:TextField = new TextField();
            tf.font = "_typewriter";
            tf.size = 16;
            tf.color = 0x007700;
            
            fld.defaultTextFormat = tf;
            fld.autoSize = TextFieldAutoSize.LEFT;
            fld.x = 50;
            fld.y = 400;
            fld.selectable = false;
            fld.text = e.toString();
            addChild(fld);
        }
    }
    
    public function addBitmap(bm:Bitmap):void {
        addChild(bm);
    }
    
    /**
     * ゲームで使用する画像サイズに変更
     */ 
    public function changeGameSize():void {
        this.scaleX*=.25;
        this.scaleY*=.25;
        this.scaleZ*=.25;
    }
    
    /**
     * 配置処理
     */ 
    public function placement():void {
        this.x = Math.floor(Math.random() * 200);
        this.y = Math.floor(Math.random() * 4) + 1;
        this.y*=90;
        this.speed = Math.floor(Math.round(Math.random() * 20)) + 1;
    }
    
    public function init():void {
        changeGameSize();
        placement();
        this.cacheAsBitmap = true;
    }
    
    public function move():Boolean {
        var ret:Boolean = false;
        this.x+=speed;
        if (x >= moveX && !isCatch) {
            moveX = x;
        }
        if (this.x > 465) {
            if (!isYouFish) {
                this.x = -200;
                speed = Math.floor(Math.random() * 10) + 1;
            } else {
                ret = true;
            }
        }
        return ret;
    }
}

import com.adobe.images.JPGEncoder;

import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Graphics;
import flash.display.Loader;
import flash.display.Shape;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.events.IEventDispatcher;
import flash.events.KeyboardEvent;
import flash.events.MouseEvent;
import flash.geom.Matrix;
import flash.media.Camera;
import flash.media.Video;
import flash.net.FileReference;
import flash.net.URLLoader;
import flash.net.URLRequest;
import flash.net.URLRequestMethod;
import flash.net.URLVariables;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.text.TextFormat;
import flash.utils.ByteArray;

import funnel.Arduino;
import funnel.FunnelEvent;

/**
 * ジャポニーニョ♪カメラを映す
 * @author tokufxug
 * http://twitter.com/tokufxug
 */
class JinmenCamera extends Sprite {
    
    private var _isMovie:Boolean = false;
    // 高さ
    private var _h:Number;
    // 幅
    private var _w:Number;
    
    // カメラを映すキャンバス
    private var _bmd:BitmapData;
    
    // ビデオ
    private var _video:Video;
    
    // 反転用のマトリクス
    private var _mirrorMatrix:Matrix;
    
    // コンストラクタ
    public function JinmenCamera(h:Number, w:Number, f:uint) {
        // カメラ
        var camera:Camera = Camera.getCamera();
        camera.setMode(w, h, f, false);
        // 高さ
        _h = h;
        // 幅
        _w = w;
        // ビデオ
        _video = new Video();
        _video.attachCamera(camera);
        // 反転用のMatrix
        _mirrorMatrix = new Matrix();
        _mirrorMatrix.scale(-1, 1);
        _mirrorMatrix.translate(w, 0);
        
        _bmd = new BitmapData(_w, _h);
        
        var bmp:Bitmap = new Bitmap(_bmd);
        bmp.x = 15;
        bmp.y = 94;
        
        _isMovie = true;
        
        addChild(bmp);
        addEventListener(Event.ENTER_FRAME, onEnterFrameHandler, false, 0 ,true);
    }
    
    public function roll():Boolean {
        if (_isMovie) {
            removeEventListener(Event.ENTER_FRAME, onEnterFrameHandler);
            _isMovie = false;
        } else {
            addEventListener(Event.ENTER_FRAME, onEnterFrameHandler, false, 0 ,true);
            _isMovie = true;
        }
        return _isMovie;
    }
    
    
    public function onEnterFrameHandler(e:Event):void {
        _bmd.draw(_video, _mirrorMatrix);
    }
    
    public function get data():BitmapData {
        return _bmd;
    }
}

/**
 * ジャポニーニョ♪作成時のメッセージや決定イベントの監視
 * @author tokufxug
 * http://twitter.com/tokufxug
 */
class JinmengyoCreateStage extends Sprite {
    
    private var fld:TextField = new TextField();
    
    private var yes:TextField = new TextField();
    private var no:TextField = new TextField();
    
    // コンストラクタ
    public function JinmengyoCreateStage() {
        var tf:TextFormat = new TextFormat();
        tf.font = "_typewriter";
        tf.size = 16;
        tf.color = 0x007700;
        
        fld.defaultTextFormat = tf;
        fld.autoSize = TextFieldAutoSize.LEFT;
        fld.x = 50;
        fld.y = 400;
        fld.selectable = false;
        
        // はい
        yes.defaultTextFormat = tf;
        yes.autoSize = TextFieldAutoSize.LEFT;
        yes.x = 130;
        yes.y = 420;
        yes.selectable = false;
        yes.text = "オーケー";
        yes.backgroundColor = 0xAAAA00;
        
        // いいえ
        no.defaultTextFormat = tf;
        no.autoSize = TextFieldAutoSize.LEFT;
        no.x = 270;
        no.y = 420;
        no.selectable = false;
        no.text = "もう1回";
        no.background = true;
        no.backgroundColor = 0xAAAA00;
        textChange();
        addChild(fld);
    }
    
    private var isEdit:Boolean = true;
    
    public function get edit():Boolean {
        return isEdit;
    }
    
    public function set edit(value:Boolean):void {
        isEdit = value; 
    } 
    
    public function textChange():void {
        if (isEdit) {
            fld.x = 50;
            fld.y = 400;
            fld.htmlText = "カメラに顔を寄せてハンドル回してハイ!チーズ!";
            if (this.numChildren >= 3) {
                removeChild(yes);
                removeChild(no);
            }
        } else {
            addChild(yes);
            addChild(no);
            fld.x = 180;
            fld.y = 380;
            fld.text = "これでいい?";
        }
    }
    
    public function selectAnser():void {
        yes.background = !yes.background;
        no.background = !no.background;
    }
    
    public function isYes():Boolean {
        return yes.background;
    }
}

/**
 * ジャポニーニョ♪釣り竿
 * @author tokufxug
 * http://twitter.com/tokufxug
 */
class Tsurizao extends Sprite {
    
    public static const STATUS_MOVE_Y:uint = 1;
    
    public static const STATUS_BACK_Y:uint = 2;
    
    private var status:uint = STATUS_MOVE_Y;
    
    private var isMoveRight:Boolean = true;
    
    public var linePosY:uint = 10;
    
    /**
     * コンストラクタ
     */ 
    public function Tsurizao() {
        init();
    }
    
    public function get g():Graphics {
        return graphics;
    }
    
    public function init():void {
        g.beginFill(0x000000);
        g.drawCircle(0, 0, 10);
        g.endFill();
    }
    
    public function initStatus():void {
        status = STATUS_MOVE_Y;
    }
    
    public function move():void {
        switch(status) {
            case STATUS_MOVE_Y:
                viewLine(2);
                break;
            case STATUS_BACK_Y:
                viewLine(-2);
                break;
        }
    }
    
    public function viewLine(my:int):void {
        g.clear();
        linePosY+=my;
        init();
        g.lineStyle(2, 0x000000);
        g.moveTo(5, 0);
        g.lineTo(5, linePosY + 5);
    }
    
    private var isLeft:Boolean = false;
    private var isRight:Boolean = false;
    
    public function onKey(event:KeyboardEvent):void {
        
        isLeft = event.keyCode == 37;
        isRight = event.keyCode == 39;
    }
    
    public function moveX():void {
        var mvx:int = 0;
        if (isLeft) {
            mvx = -1;
        } else if (isRight) {
            mvx = 1;
        }
        x+=mvx;
        if (x >= 460) {
            x = 460;
        } else if (x <= 0) {
            x = 0;
        }
    }
    
    public function catchFish():void {
        status = STATUS_BACK_Y;
    }
    
    public function getLinePosY():uint {
        return linePosY;
    }
}

import flash.system.Security;
import flash.events.IOErrorEvent;
import flash.events.SecurityErrorEvent;
import flash.text.TextFieldType;
import flash.utils.escapeMultiByte;

class CanvasUploader extends EventDispatcher
{
    public static const TWIT_PIC_COMP:String = "TWIT_PIC_COMP";
    public static const TWIT_PIC_ERROR:String = "TWIT_PIC_ERROR";
    private var UPLOAD_URL:String = "http://tokufxug.heteml.jp/japoninyo/script/img_write.php";
    private var _uploadURL:URLRequest;
    private var _file:FileReference;
    private var _loader:URLLoader;
    private var _jpgEncoder:JPGEncoder = new JPGEncoder(85);
    
    public function CanvasUploader() 
    {
        super();
    }
    
    //---------------------------------
    //
    //PUBLIC FUNCTIONS 
    //
    //---------------------------------        
    public function uploadSprite(canvas:Sprite):void
    {    
        var jpgSource:BitmapData = new BitmapData(canvas.width, canvas.height);
        jpgSource.draw(canvas);
        sendJPG(_jpgEncoder.encode(jpgSource));
    }
    
    //---------------------------------
    //
    //PRIVATE FUNCTIONS 
    //
    //---------------------------------
    private function sendJPG (jpgStream:ByteArray):void 
    {
          
          var req:URLRequest = new URLRequest(UPLOAD_URL);
          var l:URLLoader = new URLLoader();
          req.contentType = "application/octet-stream";
          req.method = URLRequestMethod.POST;
          req.data = jpgStream;
          l.addEventListener(IOErrorEvent.IO_ERROR, onError);
          l.addEventListener(Event.COMPLETE, uploadCompleteDataHandler);
          l.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onSecurityErrorHandler);
          l.load(req);
    }
    
    public var compMessage:String = null;
    private function onError(error:IOErrorEvent):void
    {
        compMessage = error.toString();
        dispatchEvent(new Event(TWIT_PIC_ERROR));
    }
    
    private function uploadCompleteDataHandler(event:Event):void
    {
        var vars:URLVariables = new URLVariables(
            event.target.data);
        compMessage = vars.url;
        dispatchEvent(new Event(TWIT_PIC_COMP));
    }
    
    public static const SECURITY_ERROR:String = "securityError";
    private function onSecurityErrorHandler(event:SecurityErrorEvent):void {
        compMessage = event.text;
        dispatchEvent(new Event(SECURITY_ERROR));
    }
    
}


class TwitPicEditView extends Sprite {
    
    private var _conf:TextField = null;
    
    private var _yes:TextField = null;
    
    private var _no:TextField = null;
    
    private var _userNameFld:TextField = null;
    
    private var _userNamelbl:TextField = null;
    
    private var _sendBtn:Sprite = null;
    
    private var _sendBtnLbl:TextField = null;
    //-- 
    private var _bashoLbl:TextField = null;
    
    private var _playerLbl:TextField = null;
    
    private var _gyoshuLbl:TextField = null;
    
    private var _taichoLbl:TextField = null;
    
    private var _dateLbl:TextField = null;
    
    private var _bashoTf:TextField = null;
    
    private var _playerTf:TextField = null;
    
    private var _gyoshuTf:TextField = null;
    
    private var _taichoTf:TextField = null;
    
    private var _dateTf:TextField = null;
    
    private var _sTaicho:String = null;
    
    private var _tf:TextFormat = null;
    
    private var _main:Sprite = null;
    
    private var _yourFish:FishImage = null;
    
    private var _isEditMode:Boolean = false;
    
    public function TwitPicEditView(m:Sprite, f:FishImage) {
        _main = m;
        _tf = new TextFormat();
        _tf.font = "_typewriter";
        _tf.size = 12;
        _tf.color = 0x000000;
        _yourFish = f;
        initMode();
    }
    
    public function initMode():void {
        _conf = new TextField();
        
        _conf.defaultTextFormat = _tf;
        _conf.text = "魚拓を公開しますか?";
        _conf.selectable = false;
        _conf.type = TextFieldType.INPUT;
        _conf.y = 330;
        _conf.autoSize = TextFieldAutoSize.LEFT;
        addChild(_conf);
        
        _yes = new TextField();
        _yes.defaultTextFormat = _tf;
        _yes.autoSize = TextFieldAutoSize.LEFT;
        _yes.y = 370;
        _yes.selectable = false;
        _yes.text = "はい";
        _yes.backgroundColor = 0xAAAA00;
        addChild(_yes);
        
        _no = new TextField();
        _no.defaultTextFormat = _tf;
        _no.autoSize =  TextFieldAutoSize.LEFT;
        _no.y = 370;
        _no.x = 40;
        _no.selectable = false;
        _no.text = "いいえ";
        _no.backgroundColor = 0xAAAA00;
        _no.background = true;
        addChild(_no);
    }
    
    public function editMode():void {
        if (_isEditMode) {
            return;
        }
        removeEventListener(MouseEvent.CLICK, onMouseClick);
        removeChild(_yes);
        removeChild(_no);
        _isEditMode = true;
        
        // ボタン
        _sendBtn = new Sprite();
        _sendBtn.x = 430
        _sendBtn.y = 430;
        
        _sendBtn.graphics.beginFill(0x999999);
        _sendBtn.graphics.drawRect(0, 0, 50, 20);
        _sendBtn.graphics.endFill();
        
        addChild(_sendBtn);
        
        _sendBtnLbl = new TextField();
        _sendBtn.addChild(_sendBtnLbl);
        _sendBtn.addEventListener(MouseEvent.CLICK, onSend);
        
        _sendBtnLbl.defaultTextFormat = _tf;
        _sendBtnLbl.autoSize = TextFieldAutoSize.LEFT;
        _sendBtnLbl.selectable = false;
        _sendBtnLbl.text = "送信";
        
        // ラベル
        _userNamelbl = new TextField();
        
        _userNamelbl.defaultTextFormat = _tf;
        
        _userNamelbl.autoSize = TextFieldAutoSize.LEFT;
        
        _userNamelbl.selectable = false;
        
        _userNamelbl.text = "名前";
        
        _userNamelbl.y = 370;
        
        addChild(_userNamelbl);
        
        // 入力
        _userNameFld = new TextField();
        
        _userNameFld.defaultTextFormat = _tf;
        
        _userNameFld.autoSize =  TextFieldAutoSize.LEFT;
        
        _userNameFld.type = TextFieldType.INPUT;
        
        _userNameFld.border = true;
        
        _userNameFld.borderColor = 0x000000;
        
        _userNameFld.text = "";
        
        _userNameFld.y = 370;
        
        _userNameFld.x = 40;
        
        addChild(_userNameFld);
    }
    
    private var up:CanvasUploader = new CanvasUploader();
    
    private function onSend(event:MouseEvent):void {
        removeEventListener(MouseEvent.CLICK, onSend);
        _conf.text = "";
        
        removeChild(_sendBtn);
        removeChild(_userNamelbl);
        removeChild(_userNameFld);
        
        outInfo();
        up.uploadSprite(_main);
        
        _conf.text = "送信中...";
        
        up.addEventListener(CanvasUploader.TWIT_PIC_COMP, onTwipicComp);
        up.addEventListener(CanvasUploader.TWIT_PIC_ERROR, onTwipError);
        up.addEventListener(CanvasUploader.SECURITY_ERROR, onTwipError);
        
    }
    
    private function outInfo():void {
        
        _bashoLbl = new TextField();
        _playerLbl = new TextField();
        _gyoshuLbl = new TextField();
        _taichoLbl = new TextField();
        _dateLbl = new TextField();
        
        _bashoTf = new TextField();
        _playerTf = new TextField();
        _gyoshuTf = new TextField();
        _taichoTf = new TextField();
        _dateTf = new TextField();
        
        _bashoLbl.defaultTextFormat = 
            _playerLbl.defaultTextFormat = 
            _gyoshuLbl.defaultTextFormat = 
            _taichoLbl.defaultTextFormat =
            _dateLbl.defaultTextFormat = _tf;
        
        _bashoLbl.autoSize = 
            _playerLbl.autoSize = 
            _gyoshuLbl.autoSize = 
            _taichoLbl.autoSize = 
            _dateLbl.autoSize = TextFieldAutoSize.LEFT;
        
        _bashoLbl.selectable = 
            _playerLbl.selectable = 
            _gyoshuLbl.selectable = 
            _taichoLbl.selectable =
            _dateLbl.selectable = false;
        
        _bashoTf.defaultTextFormat = 
            _playerTf.defaultTextFormat = 
            _gyoshuTf.defaultTextFormat = 
            _taichoTf.defaultTextFormat = 
            _dateTf.defaultTextFormat = _tf;
        
        _bashoTf.autoSize = 
            _playerTf.autoSize = 
            _gyoshuTf.autoSize = 
            _taichoTf.autoSize = 
            _dateTf.autoSize = TextFieldAutoSize.LEFT;
        
        _bashoTf.selectable = 
            _playerTf.selectable = 
            _gyoshuTf.selectable = 
            _taichoTf.selectable  = 
            _dateTf.selectable = false;
        
        _bashoLbl.text = "場所:";
        _bashoTf.text = "面白法人カヤック 鎌倉本社";
        _bashoTf.x = 50;
        
        _playerLbl.text = "釣人:";
        _playerLbl.y = 20;
        
        // ユーザー名
        _playerTf.text = uname;
        _playerTf.y = 20;
        _playerTf.x = 50;
        
        _gyoshuLbl.text = "魚種:";
        _gyoshuLbl.y = 40;
        
        _gyoshuTf.text = "ジャポニ〜ニョ♪";
        _gyoshuTf.y = 40;
        _gyoshuTf.x = 50;
        
        _taichoLbl.text = "体長:";
        _taichoLbl.y = 60;
        
        _taichoTf.y = 60;
        _taichoTf.x = 50;
        
        var taicho:int = (465 - _yourFish.moveX);
        taicho = taicho <= 0 ? 1 : taicho;
        taicho = taicho / 10;
        
        var sTaicho:String = "";
        sTaicho+=taicho + "cm";
        
        _taichoTf.text = sTaicho;
        _taichoTf.y = 60;
        _taichoTf.x = 50;
        
        _dateLbl.text = "日時:";
        _dateLbl.y = 300;
        
        const WEEK:Array = ["日", "月", "火", "水", "木", "金", "土"];
        var d:Date = new Date();
        _dateTf.text 
            = d.fullYear + "年" + (d.month + 1) + "月" + d.date + "日" + "(" + WEEK[d.day] + ")" + 
            + d.hours + "時" + d.minutes + "分" + d.seconds + "秒";
        _dateTf.y = 300;
        _dateTf.x = 50;
        
        addChild(_bashoLbl);
        addChild(_bashoTf);
        addChild(_playerLbl);
        addChild(_playerTf);
        addChild(_gyoshuLbl);
        addChild(_gyoshuTf);
        addChild(_taichoLbl);
        addChild(_taichoTf);
        addChild(_dateLbl);
        addChild(_dateTf);
        
        _sTaicho = sTaicho;
    }
    
    private function onTwipicComp(event:Event):void {
        var imgLink:TextField = new TextField();
        
        _conf.border = true;
        _conf.borderColor = 0x0000ff;
        
        imgLink.defaultTextFormat = _tf;
        imgLink.autoSize = TextFieldAutoSize.LEFT;
        imgLink.selectable = false;
        imgLink.htmlText = "<a href='" + up.compMessage + "' target='_blank'>魚拓を見る</a>";
        imgLink.y = 370;
        imgLink.border = true;
        imgLink.borderColor = 0x0000ff;
        
        addChild(imgLink);
        
        var twit:String = "獲ったどー! 体長: " 
            + _sTaicho + " の人面魚 "
            + up.compMessage + " "
            + "http://wonderfl.net/c/2jGw #japanino #wonderfl";
        
        _conf.htmlText = "<a href='http://twitter.com/home?status=" + escapeMultiByte(twit) 
            + "' target='_blank'>魚拓を公開しました。(公開したことをつぶやく)</a>";
    }
    
    private function onTwipError(event:Event):void {
        _conf.text = up.compMessage;
    }
    
    
    public function onSelectedAnserHandler(event:FunnelEvent):void {
        if (event.message == "!") {
            _yes.background = !_yes.background;
            _no.background = !_no.background;
        }
    }
    
    public function onMouseClick(event:MouseEvent):void {
        if (_yes.background) {
            editMode();
        } else {
            removeEventListener(MouseEvent.CLICK, onMouseClick);
            removeChild(_yes);
            removeChild(_no);
            _conf.text = "おわり";
        }
    }
    
    public function get uname():String {
        return _userNameFld.text;
    }
}