[Java] I tried breaking the block with java (1)

6 minute read

things to do

The previous article is below

https://qiita.com/strict39275/items/41da2ad3bb8fd60228e0 Even if I thought carefully, the code did not reach my ideal, but I would like to improve it from now on. In this article, I would like to explain each class. It’s going to be a tremendous time if you explain everything all at once, so it’s better to explain each class one by one next time. I’ll do it.

Class structure diagram

It is a class structure diagram created by shiracamus. I think the breakout class is the main and the instance variables of the class are created in it. java1.png

Program code

I would like to explain one by one, including reflection.

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.util.Timer;
import java.util.TimerTask;

It seems better to declare the import statement at the beginning of the code. This will make it easier to see what library this code uses. By entering a declaration such as import javax.swing. You can use the classes created by java. In other words, you can display the screen and input mouse events without writing the code yourself. Most of the import statements use on-demand type import. For example, if you import the on-demand type, you can use all the functions in javax.util. In other words, if you add ✳︎ at the end of the import statement, you will not worry about errors. However, you will not know which function to use, so it is better to be careful.

breakout class description

This time I will only explain the breakout class

   public class breakout extends JPanel implements MouseMotionListener{
       static int countball =15;
      
       
   Racket racket;
   Ball[] ball;
   Block[] block;
   Unbreakblock[] block1;
   Twobreakblock[] block2;
   Threebreakblock[] block3;

   double time;
   int remain=37;
   boolean gameover=false;

Features in this code

  • The breakout class inherits the functionality of JPanel and has the function of actually displaying the screen. In that panel, I entered implements and enabled the mouse function.
  • Declare static as a class variable, and set the number of balls to 15.
  • Declare instance variables racket, ballblock1, block2, and block3 that are not declared static, and take the variables that have the functions of each class. ・The time from execution to when the value of gameover becomes True is set to 37 seconds. ・Since the initial state is not the gameover state, the initial boolean value is set to false.

In other words, what did you do?

This is the basis for making a game. Even if you make a game, it does not mean that it is not displayed on the screen, and even if you do not have a mouse function you can not even use a racket that bounces the ball, so this code created an environment that you can use like that. I can’t play a game without knowing how many balls I want to make, so I’ve defined the initial values for now.

Code of number of blocks and screen size


static int x=855;
   static int y=800;
   static int size =15; //No need because the number of balls is declared in countball
// Number of light blue blocks
   static final int NUM_BLOCK_ROW = 4;
   // number of columns in the block
    static final int NUM_BLOCK_COL = 9;
   // number of blocks
    static final int NUM_BLOCK = NUM_BLOCK_ROW * NUM_BLOCK_COL;
// number of gray blocks
    static final int NUM_BLOCK_ROW1 = 8;

    static final int NUM_BLOCK_COL1 = 1;
    
    static final int NUM_BLOCK1 = NUM_BLOCK_ROW1 * NUM_BLOCK_COL1;
//Number of green blocks
    static final int NUM_BLOCK_ROW2 = 8;

    static final int NUM_BLOCK_COL2 = 3;
    
    static final int NUM_BLOCK2 = NUM_BLOCK_ROW2 * NUM_BLOCK_COL2;
// number of yellow blocks
    static final int NUM_BLOCK_ROW3 = 8;

    static final int NUM_BLOCK_COL3 = 4;
    
    static final int NUM_BLOCK3 = NUM_BLOCK_ROW3 * NUM_BLOCK_COL3;
// find the number of all blocks
    static final int SumBlock= NUM_BLOCK+NUM_BLOCK2+NUM_BLOCK3;

Forget static int size=15

Features in this code

・The horizontal size of the panel is 855 and the vertical length is 800. Declare the number of blocks here. ROW is the number of columns in the block COL is the number of rows in the block

  • Multiply and find the number of blocks. For example, if there are 8 rows and 4 columns, 8×4=32 blocks will be created.
  • Calculate the number of light blue, gray, green and yellow blocks ・Set each sum as Sumblock

In other words, what did you do?

Defined the size of the game screen and also declared the number of blocks. Here you can freely change the number of blocks. Since I want to inherit the value when the number of this block decreased, I declared it as static and used it as another class variable. You didn’t need to declare final.

Block initial position code


 //Create a 2D map
      private char[][] map;
       private int MX = 20, MY = 18;
       private String[] map_str = {
       "B",
       "B",
       "B",
       "B",
       "B",
       "B",
       "B",
       "B",
       "B",
       "B",
       "B",
       "B",
       "B",
       "B",
       "B",
       "B",
       "B",
       "B",
       "B",
                                 };

Features in this code

・Create a variable that actually draws a block with a char type map variable ・The range of the block to be drawn is horizontal 20 vertical 18 ・Blocks are placed only on the right

The reason why the blocks are placed on the left wall and the upper wall is because it is defined as an initial value in the future code.

Ball function and block position code


 public breakout(){
        time = System.currentTimeMillis() * 0.001 + remain;
           addMouseMotionListener(this);
           racket =new Racket();
           ball = new Ball[countball];
           Random rand = new Random();
           int n=countball;
            int num[] = new int [n];
      for(int i=0;i<n;i++){
            num[i]= 40+rand.nextInt(700);
           ball[0]=new Ball(num[0],250,5,-6,7);
           ball[1]=new Ball(num[1],260,-5,-3,10);
           ball[2]=new Ball(num[2],420,4,6,8);
           ball[3]=new Ball(num[3],480,-5,2,10);
           ball[4]=new Ball(num[4],590,5,-6,11);
           ball[5]=new Ball(num[5],550,-5,-3,12);
           ball[6]=new Ball(num[6],570,4,6,13);
           ball[7]=new Ball(num[7],480,-5,2,14);
           ball[8]=new Ball(num[8],490,5,-6,8);
           ball[9]=new Ball(num[9],400,-5,-3,8);
           ball[10]=new Ball(num[10], 350,4,6,9);
           ball[11]=new Ball(num[11],400,-5,2,10);ball[12]=new Ball(num[12],390,-5,-3,10);
           ball[13]=new Ball(num[13],500,4,6,10);
           ball[14]=new Ball(num[14],530,-5,2,7);
      }
           block = new Block[NUM_BLOCK];
           block1 = new Unbreakblock[NUM_BLOCK1];
          block2 = new Twobreakblock[NUM_BLOCK2];
           block3 =new Threebreakblock[NUM_BLOCK3];
          
           for (int i = 0; i < NUM_BLOCK_ROW; i++) {
               for (int j = 0; j < NUM_BLOCK_COL; j++) {
                   int x =2* j * Block.WIDTH + Block.WIDTH+50;
                   int y =2* i * Block.HEIGHT + Block.HEIGHT+600;
                   block[i * NUM_BLOCK_COL + j] = new Block(x, y);
               }
            }
           for ( int c = 0; c < NUM_BLOCK_ROW1; c++) {
               for (int d = 0; d < NUM_BLOCK_COL1; d++) {
                   int a = 2*c *  Unbreakblock.WIDTH1 +  Unbreakblock.WIDTH1+50;
                   int b = d *  Unbreakblock.HEIGHT1 +  Unbreakblock.HEIGHT1+450;
                   block1[d * NUM_BLOCK_COL1 + c] = new  Unbreakblock(a, b);
               }
            }
           for ( int c = 0; c < NUM_BLOCK_ROW2; c++) {
               for (int d = 0; d < NUM_BLOCK_COL2; d++) {
                   int a = 2*c *  Twobreakblock.WIDTH2 +  Twobreakblock.WIDTH2+50;
                   int b = 2*d *  Twobreakblock.HEIGHT2 +  Twobreakblock.HEIGHT2+300;
                   block2[c* NUM_BLOCK_COL2 + d] = new  Twobreakblock(a, b);
               }
           }
         for ( int c = 0; c < NUM_BLOCK_ROW3; c++) {
               for (int d = 0; d < NUM_BLOCK_COL3; d++) {
                   int a =2* c * Threebreakblock.WIDTH3 +  Threebreakblock.WIDTH3+50;
                   int b = 5*d * Threebreakblock.HEIGHT3 +  Threebreakblock.HEIGHT3+60;
                   block3[c * NUM_BLOCK_COL3 + d] = new  Threebreakblock(a, b);
               }
           } 
          TimeBomb timeBomb = new TimeBomb();
           Timer timer = new Timer();
           timer.schedule(timeBomb,  5000);
          
           map = new char[MY+2][MX+2];
           for (int x = 0; x <= MX+1; x++) {
             map[0][x] = 'B'; 
            // map[MY+1][x] = 'B';いらないです
           }
           for (int y = 0; y <= MY+1; y++) {
             map[y][0] = 'B'; 
             //map[y][MX+1] = 'B'; //いらないです
           }
           for (int y = 1; y <= MY; y++) {
               for (int x = 1; x <= MX; x++) {
                 map[y][x] = map_str[y-1].charAt(x-1);
               }
           }
        }

このコード内にある機能

・制限時間を有するdouble型のtimeにremainにプラス、現在の制限時間の×0.001とする。 ・ここでRacket,Ballクラスのインスタンス変数を用いる ・ボールの横の座標をランダムにするためにrandを宣言する ・ボールの横の座標を40に続いて0~700までのランダムに数字を配列numに代入させる。つまり、15個のボールの横の座標をランダムに生成して、その値をnumに代入する。 ・Ballクラスに宣言されている引数は左から、ボールの横の座標、ボールの縦の座標、ボールの横へ進む速度、ballの縦へ進む速度 としている。縦の座標はブロックの座標と被らないように、手動で入力した。 ・ブロックの数をそのままblock,block1,block2,block3にインスタンス変数を生成した。 ・縦の座標、横の座標を記入するために、for文で多重ループさせて、x,yやa,bなどにブロックの座標をそれぞれ設置した。 ・ timer.schedule(timeBomb, 5000);でプログラムが実行されてもボール、ブロックの機能などを最初の5秒間は停止するようにした。 ・ブロックの配置初期位置を定義した。ブロックのいらないとコメントしたところは壁以外でブロックを置けるようにした機能なのでいらないです

言い換えると何をしたのか

ここで初めて、ボールの機能、ブロックの位置、緑の壁の位置を定義しました。ブロックとボールの座標がかぶらないようにボールの縦の座標は手動に設定しました。そうでないと、ブロックの中にボールがある状態となってしまい、風船が割れて中身が出てきたような感じになってしまうので縦の座標はランダムは無しにしました。前回のBBBと表示されているコードもありましたがここでも、ブロックを置けることができます。

コードのいらない部分


 for(int i=0;i<n;i++){
            num[i]= 40+rand.nextInt(700);
}
ball[0]=new Ball(num[0],250,5,-6,7);
ball[1]=new Ball(num[1],260,-5,-3,10);
           ball[2]=new Ball(num[2],420,4,6,8);
           ball[3]=new Ball(num[3],480,-5,2,10);
           ball[4]=new Ball(num[4],590,5,-6,11);
           ball[5]=new Ball(num[5],550,-5,-3,12);
           ball[6]=new Ball(num[6],570,4,6,13);
           ball[7]=new Ball(num[7],480,-5,2,14);
           ball[8]=new Ball(num[8],490,5,-6,8);
           ball[9]=new Ball(num[9],400,-5,-3,8);
           ball[10]=new Ball(num[10], 350,4,6,9);
           ball[11]=new Ball(num[11],400,-5,2,10);
           ball[12]=new Ball(num[12],390,-5,-3,10);
           ball[13]=new Ball(num[13],500,4,6,10);
           ball[14]=new Ball(num[14],530,-5,2,7);

でも問題がないような感じがしてきました。実際にコンパイラして、わざわざ何回もインスタンス宣言する必要がなくて、for文の中に入るのは num[i]= 40+rand.nextInt(700);で十分でしたね。

感想

breakoutクラスのメソッドと、それ以降のクラスや、TimerTaskは次回にします。 正直なところ、やりたいことはなんとなく理解しましたが、無駄なコードを書く部分が多すぎましたね。疑問点が多すぎる。中途半端すぎるのが残念ですね。完璧にしすぎては時間が消えるので、ある程度は削って、加えたりしていきたいと思います。