スマートデバイスプログラミング 第10回
スワイプ操作を判定してみよう

GameCanvasについて

・GameCanvasの機能:今週使う変数、メソッド

・新規のメソッドはありません。

課題

(1)swipeを判定する仕組みを作ってみましょう。
(2)swipeの方向を文字で表示してみましょう
(3)提示された方向にすばやくswipeするゲームを作ってみましょう。
(4)その他、プログラムを改良したり、学んだ技術を駆使して、何か面白いことをやってみましょう。
作ったC#のプログラムを添付してください。
(プロジェクトを保存したフォルダのasset以下にあると思います。
コメント欄には、どこまでやったかと、ゲームが動いた人はハイスコアを書いてください。

課題の進め方

前回、apkが作れなかった人、xcodeを用いてうまく実機で動かせなかったmax&iOSユーザーは、前回の課題の問題解決から始めましょう。
「課題の進め方」
※今回は第9回なので、フォルダはk09に改名してください。
サンプルの起動を確認し、スクリプトが編集できる状態になったら、
続きを読み進めてください。

課題1をやってみましょう(新gameCanvas用)

  1. プログラムを編集

    (クラスに入った直後)に変数の宣言を足す

    
        int pointer_start_x;
        int pointer_start_y;
        int pointer_dx;
        int pointer_dy;
        int old_pointer_count = 0;
        int swipe_dir=0;
        int swipe_dir_last = 0;
        const int NO_DIR = 0;
        const int DIR_UP = 1;
        const int DIR_DOWN = 2;
        const int DIR_RIGHT = 3;
        const int DIR_LEFT = 4;
        const int SWIPE_DIST = 30;
    

    (InitGame()の中)に初期化処理を足す

    
            gc.SetResolution(720,1280);
    
    

    (UpdateGame()の中)に下記の行を足す

    
            CalcSwipe();
    

    DrawGame()の中に下記の行を記載

    
    
           gc.ClearScreen();
    
            // 黒の文字を描画します
            gc.SetColor(0, 0, 0);
            gc.SetFontSize(36);
    
            gc.DrawString("DIR:"+swipe_dir,0,0);
            gc.DrawString("LAST:"+swipe_dir_last,0,40);
    

    クラスを閉じるかっこの手前にメソッドを追加

    
    
    void CalcSwipe(){
            if(gc.GetPointerFrameCount(0)==1){
                pointer_start_x = (int)gc.GetPointerX(0);
                pointer_start_y = (int)gc.GetPointerY(0);
            }
            if(gc.GetPointerFrameCount(0)>0){
                pointer_dx = (int)gc.GetPointerX(0)-pointer_start_x;
                pointer_dy = (int)gc.GetPointerY(0)-pointer_start_y;
            }
    
            swipe_dir = NO_DIR; 
    
            if(gc.PointerCount == 0 && old_pointer_count ==1 ){
            
                if(pointer_dx * pointer_dx > pointer_dy * pointer_dy){
                    if(pointer_dx > SWIPE_DIST){
                        swipe_dir = DIR_RIGHT;
                    }
                    else if(pointer_dx < -SWIPE_DIST){
                        swipe_dir = DIR_LEFT;
                    }
                }
                else {
                    if(pointer_dy > SWIPE_DIST){
                        swipe_dir = DIR_DOWN;
                    }
                    else if(pointer_dy < -SWIPE_DIST){
                        swipe_dir = DIR_UP;
                    }
                }
            } 
    
            old_pointer_count = gc.PointerCount;
    
            if(swipe_dir != NO_DIR){
                swipe_dir_last = swipe_dir;
            }
    }
    
    
  2. セーブして実行してみましょう。
  3. スワイプした瞬間、swipe_dirに値が入ります。
  4. swipe_dir_lastには最後にスワイプした方向が保存されます。

課題2のヒント


第2回のカードの文字列表示を参考に作成しましょう。


string[] dir_name = {"NO DIR","UP","DOWN","RIGHT","LEFT"};

gc.DrawString(dir_name[swipe_dir_last],0,80);

などを適宜追加します。

課題3のヒント

ラウンド数が数秒表示されたあとお題が表示され(swipe判定開始)、 正しい方向にswipeすると成功、正しい方向にswipeすると失敗になります。 全10ラウンドで終了、反応が早ければ早いほど高得点、というルールで作ります。 下記を適宜配置したりなどしてみましょう。
//追加で用意する変数
//GameStateSub:ゲーム内の処理の切り分けを行う
//(0:ラウンド表示中、1:お題提示中、2:成功、3:失敗、4:終了)
//count:汎用カウンター
//round:何ラウンド目かを保存
//target_dir:お題の方向を保存
//score:得点

//変数宣言に追加
    int GameStateSub = 0;
    int count = 0;
    int round = 0;
    int target_dir=0;
    int score = 0;

//initGame内に追加




//updateGameの中
        if(GameStateSub == 0){
            count++;
            if(count == 180){
                GameStateSub = 1;
                count =0;
                target_dir = gc.Random(1,4);
            }
        }
        else if(GameStateSub == 1){
            count++;
            if(swipe_dir!=NO_DIR){
                if(swipe_dir == target_dir){
                    GameStateSub = 2;
                    score += 300-count; 
                    count = 0;
                }
                else {
                    GameStateSub = 3;
                    score -= 500;
                    count = 0;
                }
            }
        }
        
        else if(GameStateSub == 2 || GameStateSub ==3){
            count++;
            if(count > 180){
                round++;
                if(round >=10){
                    GameStateSub = 4;
                    count = 0;
                }
                else {
                    GameStateSub=0;
                    count = 0;
                }
            }
        }


//DrawGameの中

//テスト表示
        gc.DrawString("STATESUB:"+GameStateSub,0,160);
        gc.DrawString("COUNT:"+count,0,200);
        gc.DrawString("ROUND:"+round,0,240);
        gc.DrawString("TARGET:"+target_dir,0,280);
        gc.DrawString("SCORE:"+score,0,320);

        gc.SetFontSize(48);
        if(GameStateSub==0){
            gc.DrawString("ROUND:"+(round+1),320,600);
            gc.DrawString("READY!",320,650);
        }
        else if(GameStateSub==1){
           gc.DrawString(dir_name[target_dir],360,640);     
        }
        else if(GameStateSub==2){
           gc.DrawString("SUCCESS",360,640);    
        }
        else if(GameStateSub==3){
           gc.DrawString("FAIL",360,640);  
        }
        else if(GameStateSub==4){
            gc.DrawString("FINISHED!",360,600); 
            gc.DrawString("SCORE:"+score,360,650);  
        }



課題4のヒント

より良くする案を考えてみましょう。

補足

よくある質問

スクリプトを更新したのに、何も変わらない

プログラムが間違っていてビルドエラーが出ている可能性が高いです。

エディタ上でbuildしてみましょう。

{}の対応が間違っていないか、全角スペースが入っているかなど、確認してみましょう