Javaで作るブロック崩し③|テキスト表示、画面遷移を実装する

AndroidStudio
今回はテキストを作っていきます!
            
スタートやゲームクリアなど、ゲーム進行に合わせて表示されるようにしていきます。
これでさらにゲームっぽくなりますね。
            
ではさっそく始めていきましょう!

テキストを作成!

完成動画がこちら
テキストの場合は、すでにAndroidStudioでクラスが用意されているため、ブロックやバーのようにクラスを別途作る必要がないです。
            
なのでいきなりメインクラスから書いていきましょう!

メインクラスを編集

レイアウト(テキスト)を配置

package com.example.myapp_block;

import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.Point;
import android.os.Bundle;
import android.os.Handler;
import android.view.Display;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.RelativeLayout;
import android.widget.TextView;


public class MainActivity extends AppCompatActivity {
    Bar bar;
    Ball ball;
    Block[][] block;
    TextView[] textView;                       //テキストの配列変数を準備
    Intent intent;                             //画面遷移用の変数を準備
    Handler handler = new Handler();
    Runnable runnable;
    RelativeLayout relativeLayout;
    RelativeLayout.LayoutParams params;        //テキストのプロパティ設定用の変数を準備
    int width, height;
    int tap;
    int dx = 10, dy = 10;
    int colSize, rowSize;
    int breakBlocks = 0;                       //壊れたブロック数をカウントする変数を準備
    int WC = ViewGroup.LayoutParams.WRAP_CONTENT;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        relativeLayout = new RelativeLayout(this);
        relativeLayout.setBackgroundColor(Color.BLACK);
        setContentView(relativeLayout);

        WindowManager windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
        Display display = windowManager.getDefaultDisplay();
        Point point = new Point();
        display.getSize(point);
        width = point.x;
        height = point.y;

        ball = new Ball(MainActivity.this);
        ball.x = width / 2;
        ball.y = height / 2;
        relativeLayout.addView(ball);

        bar = new Bar(MainActivity.this);
        bar.left = width / 3;
        bar.right = width / 3 * 2;
        bar.top = height / 5 * 4;
        bar.bottom = height / 5 * 4 + 20;
        relativeLayout.addView(bar);

        colSize = 2;
        rowSize = 1;
        block = new Block[colSize][rowSize];
        for (int row = 0; row < rowSize; row++) {
            for (int col = 0; col < colSize; col++) {
                block[col][row] = new Block(MainActivity.this);
                block[col][row].left = (width - (colSize - 1) * 10) / colSize * col + col * 10;
                block[col][row].right = (width - (colSize - 1) * 10) / colSize * (col + 1) + col * 10;
                block[col][row].top = height / 36 * (row + 3) + row * 10;
                block[col][row].bottom = height / 36 * (row + 4) + row * 10;
                relativeLayout.addView(block[col][row]);
            }
        }

        //①テキスト生成
        textView = new TextView[6];
        for (int num = 0; num < 6; num++) {
            textView[num] = new TextView(this);
            textView[num].setTextColor(Color.WHITE);
            textView[num].setText("");
            switch (num) {
                case 0: textViewProperty(num, 64, 270, 700);
                    break;
                case 1: textViewProperty(num, 64, 80, 700);
                    break;
                case 2: textViewProperty(num, 28, 80, 1100);
                    break;
                case 3: textViewProperty(num, 28, 610, 1100);
                    break;
                case 4: textViewProperty(num, 28, 650, 1100);
                    break;
                case 5: textViewProperty(num, 64, 130, 700);
                    break;
            }
        }

        //②テキスト表示
        textView[0].setText("スタート");
    }


    //③テキストプロパティ設定メソッド
    public void textViewProperty(int num, int size, int leftMargin, int topMargin) {
        textView[num].setTextSize(size);
                                                           //レイアウトの属性を設定  
        params = new RelativeLayout.LayoutParams(WC, WC);     //テキストの表示形式を設定
        params.addRule(RelativeLayout.ALIGN_PARENT_TOP);      //親の上辺(top=0)を基点に
        params.addRule(RelativeLayout.ALIGN_PARENT_LEFT);     //親の左辺(left=0)を基点に
        params.setMargins(leftMargin, topMargin, 0, 0);       //左、上、右、下のマージン
        relativeLayout.addView(textView[num], params);        //レイアウトにテキストを描写
    }


    // タッチイベントメソッド //
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        
        textView[0].setText("");           //④タッチしたらスタート非表示

        tap = (int) event.getX();

        runnable = new Runnable() {
            @Override
            public void run() {
                //ここから動きの部分
                bar.left = tap - (width / 6);
                bar.right = tap + (width / 6);

                ball.x += dx;
                ball.y += dy;


                // ここにゲームクリア時の処理が入る //
                
                // ここにゲームオーバー時の処理が入る //
                

                //画面端                                  //ここから当たり判定
                //画面左端
                if (ball.x <= ball.radius) {
                    dx = -dx;
                    //画面右端
                } else if (ball.x >= width - ball.radius) {
                    dx = -dx;
                    //画面上端
                } else if (ball.y <= ball.radius) {
                    dy = -dy;
                    //画面下端
                } else if (ball.y >= height - ball.radius) {
                    dx = 0;
                    dy = 0;
                }


                //バー
                //バー上面
                if ((ball.y + ball.radius >= bar.top - 5) &&
                        (ball.y + ball.radius <= bar.top + 5) &&
                        (ball.x <= bar.right) &&
                        (ball.x >= bar.left)) {
                    dy = -dy;
                }

                double leftSpace2 = Math.pow(bar.left - ball.x, 2);
                double rightSpace2 = Math.pow(bar.right - ball.x, 2);
                double topSpace2 = Math.pow(bar.top - ball.y, 2);
                //バー左上角
                if (leftSpace2 + topSpace2 <= Math.pow(ball.radius, 2)) {
                    //ボールが右下斜め方向に進んでいた時
                    if (dx > 0 && dy > 0) {
                        dx = -dx;
                        dy = -dy;
                    }
                    //ボールが左下斜め方向に進んでいた時
                    if (dx < 0 && dy > 0) {
                        dy = -dy;
                    }
                }
                //バー右上角
                if (rightSpace2 + topSpace2 <= Math.pow(ball.radius, 2)) {
                    //ボールが右下斜め方向に進んでいた時
                    if (dx > 0 && dy > 0) {
                        dy = -dy;
                    }
                    //ボールが左下斜め方向に進んでいた時
                    if (dx < 0 && dy > 0) {
                        dx = -dx;
                        dy = -dy;
                    }
                }


                //ブロックの当たり判定
                for (int row = 0; row < rowSize; row++) {
                    for (int col = 0; col < colSize; col++) {
                        //ブロック左面
                        if ((ball.x + ball.radius <= block[col][row].left + 5) &&
                                (ball.x + ball.radius >= block[col][row].left - 5) &&
                                (ball.y <= block[col][row].bottom) &&
                                (ball.y >= block[col][row].top)) {
                            dx = -dx;
                            breakBlock(col, row);
                        }
                        //ブロック右面
                        if ((ball.x - ball.radius <= block[col][row].right + 5) &&
                                (ball.x - ball.radius >= block[col][row].right - 5) &&
                                (ball.y <= block[col][row].bottom) &&
                                (ball.y >= block[col][row].top)) {
                            dx = -dx;
                            breakBlock(col, row);
                        }
                        //ブロック下面
                        if ((ball.y - ball.radius <= block[col][row].bottom + 5) &&
                                (ball.y - ball.radius >= block[col][row].bottom - 5) &&
                                (ball.x >= block[col][row].left) &&
                                (ball.x <= block[col][row].right)) {
                            dy = -dy;
                            breakBlock(col, row);
                        }
                        //ブロック上面
                        if ((ball.y + ball.radius <= block[col][row].top + 5) &&
                                (ball.y + ball.radius >= block[col][row].top - 5) &&
                                (ball.x >= block[col][row].left) &&
                                (ball.x <= block[col][row].right)) {
                            dy = -dy;
                            breakBlock(col, row);
                        }
                        
                        double leftSpace = Math.pow(block[col][row].left - ball.x, 2);
                        double bottomSpace = Math.pow(block[col][row].bottom - ball.y, 2);
                        double rightSpace = Math.pow(block[col][row].right - ball.x, 2);
                        double topSpace = Math.pow(block[col][row].top - ball.y, 2);
                        //ブロック左下角
                        if (leftSpace + bottomSpace <= Math.pow(ball.radius, 2)) {
                            //ボールが右下斜め方向に進んでいた時
                            if (dx > 0 && dy > 0) {
                                dx = -dx;
                            }
                            //ボールが右上斜め方向に進んでいた時
                            if (dx > 0 && dy < 0) {
                                dx = -dx;
                                dy = -dy;
                            }
                            //ボールが左上斜め方向に進んでいた時
                            if (dx < 0 && dy < 0) {
                                dy = -dy;
                            }
                            breakBlock(col, row);
                        }
                        //ブロック左上角
                        if (leftSpace + topSpace <= Math.pow(ball.radius, 2)) {
                            //ボールが右下斜め方向に進んでいた時
                            if (dx > 0 && dy > 0) {
                                dx = -dx;
                                dy = -dy;
                            }
                            //ボールが右上斜め方向に進んでいた時
                            if (dx > 0 && dy < 0) {
                                dx = -dx;
                            }
                            //ボールが左下斜め方向に進んでいた時
                            if (dx < 0 && dy > 0) {
                                dy = -dy;
                            }
                            breakBlock(col, row);
                        }
                        //ブロック右下角
                        if (rightSpace + bottomSpace <= Math.pow(ball.radius, 2)) {
                            //ボールが左上斜め方向に進んでいた時
                            if (dx < 0 && dy < 0) {
                                dx = -dx;
                                dy = -dy;
                            }
                            //ボールが右上斜め方向に進んでいた時
                            if (dx > 0 && dy < 0) {
                                dy = -dy;
                            }
                            //ボールが左下斜め方向に進んでいた時
                            if (dx < 0 && dy > 0) {
                                dx = -dx;
                            }
                            breakBlock(col, row);
                        }
                        //ブロック右上角
                        if (rightSpace + topSpace <= Math.pow(ball.radius, 2)) {
                            //ボールが左上斜め方向に進んでいた時
                            if (dx < 0 && dy < 0) {
                                dx = -dx;
                            }
                            //ボールが右下斜め方向に進んでいた時
                            if (dx > 0 && dy > 0) {
                                dy = -dy;
                            }
                            //ボールが左下斜め方向に進んでいた時
                            if (dx < 0 && dy > 0) {
                                dx = -dx;
                                dy = -dy;
                            }
                            breakBlock(col, row);
                        }
                    }
                }

                handler.removeCallbacks(runnable);
                relativeLayout.removeView(bar);
                relativeLayout.removeView(ball);
                relativeLayout.addView(ball);
                relativeLayout.addView(bar);
                handler.postDelayed(runnable, 10);
            }
        };
        handler.postDelayed(runnable, 10);

        return super.onTouchEvent(event);
    }


    //ブロックを壊すメソッド
    public void breakBlock(int col, int row) {
        block[col][row].top = -50;
        block[col][row].bottom = -50;
        block[col][row].setVisibility(View.GONE);
        breakBlocks++;                                  //⑤壊れたブロック数+1
    }

}
まず、onCreateメソッド内でテキストを生成していきます。(①)
テキストは複数使用するので配列を利用します。
setTextColorメソッドで文字色を指定します。
また、ゲーム進行に合わせて画面に文字を表示していくため、最初は文字を空欄にします。
そしてswitch文を使って、各テキストのプロパティ(サイズや位置)を決めていきます。
プロパティを決める際にtextViewPropertyメソッドを使っていますが、これは以下で作成します。
テキストを生成し終えたら、まずは初期表示としてtextView[0]に”スタート”を表示させます。(②)
③では先ほど説明したテキストのプロパティ設定メソッドを実装します。
引数にテキストの番号とサイズ、画面左端からのマージン、画面上端からのマージンをとります。
レイアウトの属性を設定するのにLayoutParamsを用います。
また、テキストの表示形式として、WRAP_CONTENTを設定します。
そして、配置の基点として、親である画面の上辺(top=0の位置)、左辺(left=0の位置)を指定します。
つまり、画面左上(0,0)を基点として配置していきます。
setMarginsメソッドでParamsにマージンをセットして、そのParamsをaddViewメソッドの引数として渡すことで、レイアウトにテキストを描写します。
            
④では、初期表示していたスタートの文字をタッチによって非表示になるようにしています。
           
⑤では、ブロックが壊れるたびにbreakBlocksという変数が+1されるようにしています。

ゲームクリア、ゲームオーバー時の処理を追加

//①ゲームクリア時の処理
    if (breakBlocks == rowSize * colSize) {           //ブロックを全て壊したらゲームクリア
        textView[2].setText("ステージ選択");
        textView[4].setText("次のステージ");
        textView[5].setText("ゲームクリア");
        //テキストにListenerを設定
        textView[4].setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                intent = new Intent(MainActivity.this, MainActivity.class);
                startActivity(intent);
            }
        });
    }


//②ゲームオーバー時の処理    
    if (dx == 0 && breakBlocks != rowSize * colSize){   //ボールが画面下に出たらゲームオーバー
        textView[1].setText("ゲームオーバー");
        textView[2].setText("ステージ選択");
        textView[3].setText("もう一度トライ");
        //テキストにListenerを設定
        textView[3].setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                intent = new Intent(MainActivity.this, MainActivity.class);
                startActivity(intent);
            }
        });
    }
          
ここでは、ゲームクリア、ゲームオーバー時の処理を追加しています。
それぞれでテキストの表示を切り替えています。
また、”もう一度トライ”と”次のステージ”のテキストにはListenerを設定して、画面遷移を実装しています。実装するには、Intentに引数として(遷移元のアクティビティ、遷移先のアクティビティ)を渡します。
今回はどちらも現在のアクティビティに戻って、ゲームを最初からやり直せるようにしてあります。
            
以上で、今回の目標まで完成しました。お疲れ様です!
次回は今までのコードを綺麗に整えていく、リファクタリングというものを行なっていこうと思います!

コメント

タイトルとURLをコピーしました