甥っ子のために簡単なスマホゲームを作ってみる

#はじめに
甥っ子が4歳になりスマホの画面を適当にポチポチ触って遊んでるので、簡単で4歳児にもわかるゲームを作ってあげたいなと思って、勉強を兼ねて実際に作ってみることに。
とはいえ、androidアプリなんて作ったことないし、ましてやゲームなんて…

調べてみたらCode for Funさん([【作って学べる】Android Studio ゲームアプリ開発入門](https://codeforfun.jp/android-studio-catch-the-ball-intro/))が大変わかりやすく環境構築から簡単なゲームを作る手順を解説していたので、これを見ながら勉強して作つくりました。

##出来たもの
出来たものは、ほぼCode for Funさんのと同じ玉取りゲームですが、少し改良を加え、スコアによって玉の動く速度を変えて、ある一定のスコアに達するとタップ一回ごとに玉の速度が若干早くなるという鬼畜仕様になっています。
追加の隠し要素としてランダムで流れてくる☆を取ると、15秒間ゲームオーバーになる黒いモヤットボール？の出現を止め、逆に高得点の赤玉の出現頻度が増えるというボーナスタイム的な要素を追加しています。

ここまではCode for Funさんで作っているサンプルと同じもの
![20200416_181948.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584794/6862fdf1-0769-aa05-cd4d-8a0e86410e3c.gif)

で、これが改造後
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">うーん…<br>反射神経鈍い… <a href="https://t.co/5ihin00dEH">pic.twitter.com/5ihin00dEH</a></p>&mdash; 野田　mono_pest (@mono_pest) <a href="https://twitter.com/mono_pest/status/1251401257396219904?ref_src=twsrc%5Etfw">April 18, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
かなり反射神経を鍛えられる仕様になっているのではないでしょうか。

###変更点
変更したのは以下の部分
まず、玉の動く速度に関する部分と☆要素の出現頻度の部分

```java:MainActivity.java
    public void changePos(){
        boxSpeed = Math.round(screenHeight/(boxMoveSpeed+70));//四捨五入しint型に代入
        orangeSpeed = Math.round(screenWidth/(moveSpeed+35))- OrangeSpeedAdd;
        pinkSpeed = Math.round(screenWidth/(moveSpeed+11)) - PinkSpeedAdd;
        blackSpeed = Math.round(screenWidth/(moveSpeed+20)) - BlackSpeedAdd;
        starSpeed = Math.round(screenWidth/(90.0f));
        hitCheck();

//〜略〜

        //star
        starX -= starSpeed;
        if(starX < 0){
            starX = screenWidth + (7500 * ((float)Math.floor(Math.random()*10)+1));; //スポーン位置調整　(7500*(0~10の乱数+1))
            starY = (float)Math.floor(Math.random()*(frameHeight-star.getHeight()));
        }
        star.setX(starX);
        star.setY(starY);

//〜略
```
☆の出現頻度はたまに出てくる程度の要素にしたかったので、出現までのインターバルを長めに且つランダムなタイミングで出てくるようになっています。
玉の動く速度は`(画面横のサイズ/(速度変数+定数))-速度増減変数`の四捨五入した値になっています。

速度変数moveSpeed(初期値は50)は獲得スコアによって値が減少し、画面をタップするたびに更に減少します。

```java:MainActivity.java
    public boolean onTouchEvent(MotionEvent event) {

        if(start_flg ==  false){
            start_flg = true;
            FrameLayout frame = findViewById(R.id.frame);
            frameHeight = frame.getHeight();
            boxY = box.getY();
            boxSize = box.getHeight();
            startLabel.setVisibility(View.GONE);

            timer.schedule(new TimerTask() {        //タイマータスク作成
                @Override
                public void run() {     //タイマータスクで実行する処理
                    handler.post(new Runnable() {
                        @Override
                        public void run() {
                            changePos();
                        }
                    });
                }
            },0,20); //実行までの待機時間0ms、実行間隔20ms
        }else{
            if(event.getAction() == MotionEvent.ACTION_DOWN){
                action_flg = true;      //画面に触れたらtrue

                //スコアによる速度調整
                if(100<=score && score<200){
                    moveSpeed=50.0f;
                }else if(200<=score && score<300){
                    moveSpeed=40.0f;
                }else if(300<=score && score<400){
                    boxMoveSpeed = -20.0f;
                    moveSpeed=30.0f;
                }else if(400<=score && score<600){
                    moveSpeed-=0.05f;
                }else if(600<=score && score<1000){
                    moveSpeed=10.0f;
                    moveSpeed-=0.1f;
                }else if(1000<=score && score<1500){
                    moveSpeed -=0.5f;
                }else if (1500<=score){
                    moveSpeed -=1.0f;
                }
            }else if(event.getAction()== MotionEvent.ACTION_UP){
                action_flg = false;     //画面から離したらfalse
            }
//〜略
```
ただ、やりすぎると画面の描写の限界を超えて玉が見えなくなります。そして、速度変数と定数を足した値がマイナスになると速度が反転し、玉が逆進します。
(orangeSpeedの場合こんな感じ)
![1587183308584.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584794/8db6b066-a028-7825-1b26-e0c8e008a560.jpeg)
(もっとも、人間を卒業したような方でない場合はこの境地に至る前にゲームオーバーになっているはずですが…)


次に☆を取った時の挙動

```java:MainActivity.java
//〜略
        //star
        float starCenterX = starX + star.getWidth() / 2;
        float starCenterY = starY + star.getHeight() / 2;

        if(hitStatus(starCenterX,starCenterY)){
            soundPlayer.playHitSound();
            starX = -10.0f;
            star();

            TimerTask task = new TimerTask() {
                public void run() {
                    orangeSpawn = 20;
                    blackSpawn = 10;
                    pinkSpawn = 5000;

                    //追加の増減速度を0に戻す
                    OrangeSpeedAdd = 0;
                    PinkSpeedAdd = 0;
                    BlackSpeedAdd = 0;

                    //退避した各速度値を元に戻す
                    orangeSpeed = orangeSave;
                    pinkSpeed = pinkSave;
                    blackSpeed = blackSave;


                }
            };
            Timer timer = new Timer();
            timer.schedule(task, 15000);
```
starを呼び出した15秒後にスポーンの値を初期値に戻し、玉の速度を☆を取る前に戻します。

starの内容は

```java:MainActivity.java
    public void starOption(){
        //各スポーン間隔調整
        orangeSpawn = 1;
        pinkSpawn = 1;
        blackSpawn +=  10000;
        blackX=blackSpawn;     //スポーン位置に戻す
        BlackSpeedAdd = blackSpeed;        //速度0にする
        OrangeSpeedAdd = 5 - (int)Math.floor(Math.random()*10);       //速度を+5~-5の乱数の値で増減
        PinkSpeedAdd = 5 - (int)Math.floor(Math.random()*10);
        //スコアが400以上であれば、上記の追加増減速度からさらに速度を減速させる
        if(score>=400){
            OrangeSpeedAdd += 5;
            PinkSpeedAdd += 10;
        }
    }
```
starでは玉のスポーン間隔を短くし、黒モヤットボールの動きを止めてスポーン位置に戻しています。
また、各玉の速度増減変数に5~-5までのランダムの値を追加して、速度を調整しています。

元コードから改良したMainActivity.javaのファイルのみ晒しておきます。
(https://github.com/mono-taro/simple_game)
Code for Funさんの記事とあわせてご覧ください。

#甥っ子にやらせてみる　-追記しました(4/25)
最後は完成したゲームを甥っ子にやらせてみたら追記します。
###追記(4/25)
甥っ子にやらせてみましたが、5分で飽きられました…予想はしていたけど…
曰く、にゃんこ大戦争のほうが面白いとかなんとかで…
なんでも、ガチャを引くのが楽しい？らしい(やったことがないからわからないけど)


#参考
Code for Fun[【作って学べる】Android Studio ゲームアプリ開発入門](https://codeforfun.jp/android-studio-catch-the-ball-intro/)