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」の付録
Japanino と光残像キット・P.O.V を使った魚釣りゲーム
--------------------------------------------------
           カニ漁
--------------------------------------------------
■遊び方
 
 P.O.V のハンドルを回すとリ漁船の網が上がります。
 ハンドルを止めると網が下がります。
 網を上下にうまくコントロールして、カニを漁船の中に引き上げると、
 P.O.V の LEDユニットにカニが表示されます。
 
 ※ 画面をクリックでも P.O.V のハンドルを回すかわりになります。
 
 ※ ゲームクリアはありません。
 
 mail:usami@i-tach.com
 
 --------------------------------------------------
 
参考:セットアップ方法の詳細に関しては、以下のページでの説明を
参照してください。
大人の科学マガジンVol.27
http://otonanokagaku.net/magazine/vol27/
wonderfl x japanino
http://wonderfl.net/event/japanino/
注意:光残像キットは、あまり激しく操作すると壊れてしまうことが
ありますので注意してください。
/**
 * Copyright usami ( http://wonderfl.net/user/usami )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/wpxN
 */

// 「大人の科学マガジン vol.27」の付録
// Japanino と光残像キット・P.O.V を使った魚釣りゲーム
// --------------------------------------------------
//            カニ漁
// --------------------------------------------------
// 
// ■遊び方
//  
//  P.O.V のハンドルを回すとリ漁船の網が上がります。
//  ハンドルを止めると網が下がります。
//  網を上下にうまくコントロールして、カニを漁船の中に引き上げると、
//  P.O.V の LEDユニットにカニが表示されます。
//  
//  ※ 画面をクリックでも P.O.V のハンドルを回すかわりになります。
//  
//  ※ ゲームクリアはありません。
//  
//  mail:usami@i-tach.com
//  
//  --------------------------------------------------
//  
// 参考:セットアップ方法の詳細に関しては、以下のページでの説明を
// 参照してください。
// 
// 大人の科学マガジンVol.27
// http://otonanokagaku.net/magazine/vol27/
// 
// wonderfl x japanino
// http://wonderfl.net/event/japanino/
// 
// 注意:光残像キットは、あまり激しく操作すると壊れてしまうことが
// ありますので注意してください。

package {
    import flash.display.Graphics;
    import flash.display.MovieClip;
    import flash.display.Sprite;
    import flash.display.Loader;
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.geom.Point;
    import flash.geom.Rectangle;
    import flash.text.TextField;
    import flash.text.TextFieldAutoSize;
    import flash.text.TextFormat;
    import flash.utils.Timer;
    import flash.events.Event;
    import flash.events.TimerEvent;
    import flash.events.MouseEvent;
    import flash.net.URLRequest;
    import flash.system.LoaderContext;
    
    import Box2D.Dynamics.*;
    import Box2D.Collision.*;
    import Box2D.Collision.Shapes.*;
    import Box2D.Common.Math.*;
    import Box2D.Dynamics.Joints.b2Joint;
    import Box2D.Dynamics.Joints.b2MouseJoint;
    import Box2D.Dynamics.Joints.b2MouseJointDef;
    
    import funnel.*;
    
    [SWF(frameRate="30")]

    public class JapaninoFishingExample extends Sprite {
        private var _japanino:Arduino;
        
        private var loader1:Loader;
        private var loader2:Loader;
        private var loadCnt:int = 0;
        public var m_world:b2World;
        public var m_iterations:int = 10;
        public var m_timeStep:Number = 1.0 / 30.0;
        
        private var body:b2Body;
        private var ami:b2Body;
        private var bodyDef:b2BodyDef;
        private var boxDef:b2PolygonDef;
        private var circleDef:b2CircleDef;
        private var mouseJointDef:b2MouseJointDef;
        private var mouseJoint:b2MouseJoint;
        
        private var xGCnt:int = 0;
        private var efCnt:int = 0;
        private var amiY:Number = 3;
        
        private var container:Sprite;
        
        private var cntBmpData:BitmapData;
        private var cntBmp:Bitmap;
        
        private var amiSp:Sprite
        private var amiPt1:Point;
        private var amiPt2:Point;
        private var line:Sprite;
        private var tx:TextField;
        private var fm:TextFormat;
        
        //-----------------------------------------------------
        //コンストラクタ
        public function JapaninoFishingExample() {
            
            //カニ画像
            var url:String = "http://assets.wonderfl.net/images/related_images/d/d2/d202/d20265e99e54231799ebc88f7edbcfd7755ec5f4";
            loader1 = new Loader();
            loader1.load(new URLRequest(url), new LoaderContext(true));
            loader1.contentLoaderInfo.addEventListener(Event.COMPLETE, loadCompleteHandler);
            
            //船画像
            url = "http://assets.wonderfl.net/images/related_images/3/3d/3d1a/3d1a1353a9c41b0849060661537fb7debab44fa0";
            loader2 = new Loader();
            loader2.load(new URLRequest(url), new LoaderContext(true));
            loader2.contentLoaderInfo.addEventListener(Event.COMPLETE, loadCompleteHandler);
            
            container = new Sprite();
            addChild(container);
            
            var config:Configuration = Arduino.FIRMATA;
            _japanino = new Arduino(config);
            _japanino.addEventListener(FunnelEvent.READY, onJapaninoReady);
        }
        //-----------------------------------------------------
        //画像ロード完了
        private function loadCompleteHandler(e:Event):void {
            loadCnt++
            if (loadCnt == 2) {
                 set_init();
            }
        }
    
        //画像ロード完了
        private function set_init():void{
            
            // シミュレーションする座標の範囲を指定する
            var worldAABB:b2AABB = new b2AABB();
            worldAABB.lowerBound.Set(-100.0, -100.0);
            worldAABB.upperBound.Set(100.0, 100.0);
            
            var gravity:b2Vec2 = new b2Vec2(0.0, 3.0);// 重力を定義する
            var doSleep:Boolean = false;//物体が動いていないときに処理削減するか
            m_world = new b2World(worldAABB, gravity, doSleep);// 世界のインスタンスを作成する
            
            //海
            var umi:Sprite = new Sprite();
            umi.graphics.beginFill(0x1F5CEB);
            umi.graphics.drawRect(0, 0, 465, 465);
            container.addChild(umi);
            
            //空
            var sora:Sprite = new Sprite();
            sora.graphics.beginFill(0x79D0FF);
            sora.graphics.drawRect(0, 0, 465, 115);
            container.addChild(sora);
            
            //雲
            var kumo1:Sprite = getKumo();
            var kumo2:Sprite = getKumo();
            var kumo3:Sprite = getKumo();
            kumo1.x = 50; kumo1.y = -20;
            kumo2.x = -40; kumo2.y = 50;
            kumo3.x = 360; kumo3.y = 35;
            container.addChild(kumo1);
            container.addChild(kumo2);
            container.addChild(kumo3);
            
            //壁
            setWall(-1.3, 1, 0.3, 3, 0x584130);
            setWall(6.6, 1, 0.3, 3, 0x584130);
            setWall( 3, 4.5, 4, 0.6, 0x584130);
            
            //船壁
            setWall(1.62, 0.75, 0.01, 0.4,0x333333);
            setWall(3.02, 0.75, 0.01, 0.4,0x333333);
            setWall( 2.32, 0.2, 0.6, 0.01, 0x333333);
            

            
            //アミ(糸)
            line = new Sprite();
            container.addChild(line);
            
            //アミ(底)
            bodyDef.position.x = 2.32;
            bodyDef.position.y = 3.6;
            rW = 0.6;
            rH = 0.02;
            boxDef = new b2PolygonDef();
            boxDef.SetAsBox(rW , rH*0.1);
            boxDef.density = 3000;//密度
            boxDef.friction = 0.05;//摩擦
            boxDef.restitution = 0.0001;//跳ね返り
            amiSp = new Sprite();
            amiSp.graphics.beginFill(0x000000);
            amiSp.graphics.drawRect( -5, -5, 10, 10);
            amiPt1 = new Point(-5,0);
            amiPt2 = new Point(5,0);
            bodyDef.userData = amiSp;
            bodyDef.userData.width = 100 * 2 * rW;
            bodyDef.userData.height =  100 * 2 * rH;
            container.addChild(bodyDef.userData);
            ami = m_world.CreateBody(bodyDef);//物体を作る
            ami.CreateShape(boxDef);//形を物体に追加する 
            ami.SetMassFromShapes();//重さを計算する
            
            //船
            addChild(loader2)
            loader2.x = 112;
            
            // カニ
            for (var i:int = 1; i < 6; i++){
                bodyDef = new b2BodyDef();
                bodyDef.position.x = Math.random() * 3+1.2;
                bodyDef.position.y = Math.random() * 1.2+1.6;
                var rW:Number = 0.5;
                var rH:Number = 0.4;

                boxDef = new b2PolygonDef();
                var sp:Sprite = getKani();
                bodyDef.userData = sp;
                
                boxDef.SetAsBox(rW * 0.7, rH * 0.85);
                boxDef.density = 0.3;//密度
                boxDef.friction = 0.005;//摩擦
                boxDef.restitution = 0.0001;//跳ね返り
                
                bodyDef.userData.width = 100 * 2 * rW;
                bodyDef.userData.height =  100 * 2 * rH; 
                body = m_world.CreateBody(bodyDef);//物体を作る
                body.CreateShape(boxDef);//形を物体に追加する

                body.SetMassFromShapes();//重さを計算する 
                container.addChild(bodyDef.userData);
            }
            
            
            //テキスト
            fm = new TextFormat();
            fm.size = 90;
            fm.bold = true;
            fm.color = 0xff0000;
            tx = new TextField();
            tx.text = "大漁!!!";
            tx.visible = false;
            tx.autoSize = TextFieldAutoSize.LEFT;
            tx.setTextFormat(fm);
            tx.x = 87; tx.y = 10;
            addChild(tx);
            
            //ドットフィルタ
            var dot:Sprite = new Sprite();
            var len:int = 465 / 3;
            
            for (i = 0; i <= len; i++) 
            {
                dot.graphics.beginFill(0x000000,0.2);
                dot.graphics.drawRect(i*3, 0, 1, 465);
            }
            len = 465 / 2;
            for (i = 0; i <= len; i++) 
            {
                dot.graphics.beginFill(0x000000,0.2);
                dot.graphics.drawRect(0, i*2, 465, 1);
            }
            addChild(dot);
            
            mouseJointDef = new b2MouseJointDef();// マウスジョイントを定義する
            mouseJointDef.body1 = m_world.GetGroundBody();// 片方のbodyにはワールド全体を設定する
            mouseJointDef.body2 = ami;// もう片方には移動させたい物体を設定する
            mouseJointDef.target = ami.GetWorldCenter();// 車体の中心座標を設定する
            mouseJointDef.maxForce = 7000;// マウスで引っ張られるときの力
            mouseJointDef.timeStep = 1 / 30;// シミュレーションの間隔
            mouseJoint = b2MouseJoint(m_world.CreateJoint(mouseJointDef));//マウスジョイントを作る
            
            stage.addEventListener(MouseEvent.CLICK, clickHandler);

            cntBmpData = new BitmapData(465, 465);
            cntBmp = new Bitmap(cntBmpData);
            
            addEventListener(Event.ENTER_FRAME, Update, false, 0, true);
        }
        
        //画像をチェックして P.O.V に送る
        private function set_imgCheck():void {
            var pattern:Array = [];
            var rowStr:String;
            var checkN:int = 0;
            for (var i:int = 0; i < 15; i++) 
            {
                rowStr = "";
                
                for (var n:int = 6; n >= 0; n--) 
                {
                    var col:uint = cntBmpData.getPixel(i * 9 + 169, n * 10 + 30);
                    var r:uint = ( col & 0xff0000 ) >> 16;
                    var b:int = (r > 150)? 1 : 0;
                    rowStr = rowStr + String(b);
                    checkN += b;
                }
                
                pattern.push(parseInt(rowStr, 2))
            }
            if (checkN > 1) {//船にカニが入った場合
                tx.visible = true;
            }else {//船にカニが入ってない場合
                tx.visible = false;
            }
            
            // パターンをカスタムのメッセージとしてJapaninoに転送する
            _japanino.sendSysexMessage(0x10, pattern);
        }
        //-----------------------------------------------------
        /**
         * ハンドラ
         */
        
        // EnterFrame
        private function Update(e:Event):void{
            
            m_world.Step(m_timeStep, m_iterations);
            
            // Go through body list and update sprite positions/rotations
            for (var bb:b2Body = m_world.m_bodyList; bb; bb = bb.m_next) {
                if (bb.m_userData is Sprite){
                    bb.m_userData.x = bb.GetPosition().x * 100;
                    bb.m_userData.y = bb.GetPosition().y * 100;
                    bb.m_userData.rotation = bb.GetAngle() * (180 / Math.PI);
                }
            }
            
            //アミの糸描画
            var gPt1:Point = amiSp.localToGlobal(amiPt1);
            var gPt2:Point = amiSp.localToGlobal(amiPt2);
            var clossY:Number = (gPt1.y + gPt2.y) * 0.5 - 90;
            var g:Graphics = line.graphics;
            g.clear();
            g.lineStyle(2, 0x000000, 0.2);
            g.moveTo(gPt1.x, gPt1.y);
            g.lineTo(232, clossY);
            g.moveTo(gPt2.x, gPt2.y);
            g.lineTo(232, clossY);
            g.lineTo(232, 30);
            
            if (efCnt % 2 == 0) {
                cntBmpData.draw(container);
            }
            
            if (Math.random() < 0.5) xGCnt++;
            m_world.m_gravity.x =  Math.cos(xGCnt*0.1)*2;//重力変更
            
            if (amiY < 3.9) amiY += 0.02;
            
            mouseJoint.SetTarget(new b2Vec2(2.32, amiY)); // マウスジョイントのカーソル位置を更新
            efCnt++
        }
        
        // JapaninoReady
        private function onJapaninoReady(e:Event):void {
            // Japaninoからのイベントに対してイベントリスナをセット
            _japanino.addEventListener(FunnelEvent.FIRMATA_STRING, onMessage);

            // 光残像キットの全面消灯のパターン(7行×19桁)
            var pattern:Array = [

                parseInt("0000000", 2),
                parseInt("0000000", 2),
                parseInt("0000000", 2),
                parseInt("0000000", 2),
                parseInt("0000000", 2),
                parseInt("0000000", 2),
                parseInt("0000000", 2),
                parseInt("0000000", 2),
                parseInt("0000000", 2),
                parseInt("0000000", 2),
                parseInt("0000000", 2),
                parseInt("0000000", 2),
                parseInt("0000000", 2),
                parseInt("0000000", 2),
                parseInt("0000000", 2),];

            // パターンをカスタムのメッセージとしてJapaninoに転送して表示をクリアする
            _japanino.sendSysexMessage(0x10, pattern);
        }
        
        // Japaninoからメッセージを受信
        private function onMessage(event:FunnelEvent):void {
            
            // メッセージが"!"であれば(=光残像キットのハンドルが回転した通知であれば)
            if (event.message == "!") {
                
                set_imgCheck();
                
                if (amiY > 1.2) amiY -= 0.3;
                
            }
        }
        
        // Click
        private function clickHandler(e:MouseEvent):void {
            
            set_imgCheck();
            
            if (amiY > 1.2) amiY -= 0.35;
        }
        //-----------------------------------------------------
        //雲を返す
        private function getKumo():Sprite {
            var _kumo:Sprite = new Sprite();
            var xs:Array = [0, 31, 71, 21, 58];
            var ys:Array = [10, 0, 4, 31, 26];
            
            for (var i:int = 0; i < 5; i++) 
            {
                _kumo.graphics.beginFill(0xffffff);
                _kumo.graphics.drawCircle(xs[i], ys[i], 25);
            }
            _kumo.scaleY = 0.85;
            return _kumo;
        }
        
        //壁を配置
        private function setWall(_x:Number,_y:Number,_w:Number,_h:Number,col:uint):void {
            
            bodyDef = new b2BodyDef();//物体の定義を作る 
            
            bodyDef.position.Set(_x, _y);
            boxDef = new b2PolygonDef();
            boxDef.SetAsBox(_w, _h);
            boxDef.friction = 0.01;//摩擦
            boxDef.density = 0;//密度
            
            var sp:Sprite = new Sprite();
            sp.graphics.beginFill(col);
            sp.graphics.drawRect( -5, -5, 10, 10);
            bodyDef.userData = sp;
            bodyDef.userData.width = 100 * 2 * _w;
            bodyDef.userData.height = 100 * 2 * _h;
            container.addChild(bodyDef.userData);
            
            body = m_world.CreateBody(bodyDef);//物体を作る
            body.CreateShape(boxDef);//形を物体に追加する 
            body.SetMassFromShapes();
        }
        
        //カニSpriteを返す
        private function getKani():Sprite {
            var myBitmapData:BitmapData = new BitmapData(loader1.width, loader1.height, true, 0x00000000);
            myBitmapData.draw(loader1);
            var bmp:Bitmap = new Bitmap(myBitmapData);
            var sp:Sprite = new Sprite();
            
            bmp.x = -bmp.width * 0.5;
            bmp.y = -bmp.height * 0.5;
            sp.addChild(bmp);
            return sp;
        }
        //-----------------------------------------------------
    }
}