java簡素なブロック崩し作ってみた

#はじめに
きょうで始めてQiitaに投稿することになりました。正直に何をすれば以下わからず、困惑していますが、とりあえずプログラミング言語のスキルアップの向上のためにもできる限り毎日投稿していきたいと思います。よろしくお願いします
#なぜQiitaに投稿することになったのか
正直に言えば就活でアピールポイントとして加えたいからです。今のままだと何もできないままエンジニア目指したいですと言われても落ちるのが分かるのでせめて、Qiitaに投稿して、自分の実力がどれくらいなのかを公開したく思いました。これから自分の興味のある分野だけ進捗が生まれるように投稿をし続けたいです
#なぜブロック崩しを作ることになったのか
学校の課題で自由に作りなさいとの事で過去作ったゲームをここに投稿したいと思いました。あとは自分はブロック崩しやテトリスやぷよぷよが大好きなのでレトロゲームが作りたく思いました。
#ブロック崩しのルール
ブロック崩しはやったことがある人ならわかりますが、あるボールをラケットやバーで打ち返し画面の下に落ちないように工夫する必要がある。打ち返した際にボールをブロックにあてて、全部のブロックを消すか、ブロックを消した際に得点などを加えたりする。非常にシンプルなゲームですが作ってみるととても大変でした。
![breakout.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680378/64812b4d-5844-38f3-0caa-2a11d4b29a8c.png)
画像の通りブロック崩しの例です。一つだけではつまらないので、ボールの大きさ、速さ、ボールの数も変えました。この時点で逸脱していますが、とりあえずそんな感じで。ブロックもボールの当たる回数で消えるようにしています。画像の通りならば黄色ならば３回、青ならば１かい、緑ならば二回黒は何度当たっても消えないようにしています制限時間も任意に設定できます。ただし、課題の提出期限もあり、ゲームの制限時間後、ブロックの数などをカウントすればよかったのですが間に合わず中途半端な出来になってしまいました。必ずgameclearと表示され失敗の条件ができませんでした。そのため、何回か投稿して改善していきます

#参考サイト
http://aidiary.hatenablog.com/entry/20040918/1251373370
このサイトによってブロック崩しが作れました。根幹のアルゴリズムはこちらを参考にして下さい。
一部はほとんど同じですが、本当にわかりやすいです。ありがとうございました。
#javaの環境
java version "12.0.1" 2019-04-16
Java(TM) SE Runtime Environment (build 12.0.1+12)
Java HotSpot(TM) 64-Bit Server VM (build 12.0.1+12, mixed mode, sharing)
#プログラムコード
900行近くなりましたので別々に記事を分けて説明をしていきたいと思います。そうした方が飽きないと思うので...


```java

import javax.swing.Timer;
import java.awt.Color;
import javax.swing.*;
import java.awt.*;
import java.text.ParseException;


public class TimerTest1 extends JFrame {
 static int x=855;
static int y=800;
    private Timer timer;
    private int countdown_sec = 5;
    private CardLayout card = new CardLayout(0, 0);

    public static void main(String[] args) throws ParseException {
          TimerTest1 frame = new TimerTest1();
         
          frame.setSize(x,y);
          frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          frame.getContentPane().setBackground(new Color(0, 0, 0));
          frame.setVisible(true);
  }
    TimerTest1() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setTitle("タイトル画面");
        setLayout(card);
        JPanel panel = new Draw();
        //JPanel labelPanel = new JPanel();
        //JLabel label = new JLabel();
        JPanel game_over = new breakout();
        game_over.setOpaque(false);
        add(panel,"文字の描画");
       // labelPanel.add(label);
       
      
        timer = new Timer(1000, (e) -> {
          
           
            if (countdown_sec ==0){
              add(game_over, "gameover_window");
                timer.stop();
              
                showPanel("gameover_window");
               
                return;
            }
            countdown_sec--;
        }); 
        timer.start();
    }
    
    public void showPanel(String name) {
        card.show(getContentPane(), name);
    }
    public static class Draw extends JPanel{
    public   void paintComponent(Graphics g){
draw(g);
    }
    public static  void draw(Graphics g){
      g.setFont(new Font("TimeRoman", Font.CENTER_BASELINE, 30));
      g.setColor(Color.red);
      g.drawString("ブロック崩し",300 , 200);
      g.setColor(Color.red); 
      g.drawString("五秒後に始まるよー!", 250, 300); 
      g.drawString("制限時間は３０秒です", 250, 400); 
      g.setColor(Color.red);
      g.setColor(Color.red);
      g.drawString("マウスを横に動かしてボールを跳ね返そう", 125, 500);  
      g.setColor(Color.red);
      g.drawString("マウスは下の矢印の先っぽがが初期位置でつ", 100, 600); 
      g.setColor(Color.red);
      g.drawString("↓",425 , 700);
    }
  }
  }

```


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

   
   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;
   static int x=855;
   static int y=800;
   static int size =15;
   static final int NUM_BLOCK_ROW = 4;
   // ブロックの列数
    static final int NUM_BLOCK_COL = 9;
   // ブロック数
    static final int NUM_BLOCK = NUM_BLOCK_ROW * NUM_BLOCK_COL;
    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;
    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;
    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;
    static final int SumBlock=  NUM_BLOCK+NUM_BLOCK2+NUM_BLOCK3;
 
    //二次元マップの作成
      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",                        
                                 };
                                 
       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);
               }
           }
        }
       public void displayTime(Graphics g) {
        if ( gameover ) {
       
          g.setFont(new Font("TimeRoman", Font.BOLD, 50));
          g.setColor(Color.YELLOW);
          g.drawString("GAME CLEAR", 250, 550); 
          for(int j=0;j<countball;j++){
            int ballsize =ball[j].Size();
          ball[j].Size();
                if(ballsize==0){
                return;
                }
          }
        } else {
         int dt = (int) (time - System.currentTimeMillis() * 0.001);
          g.setFont(new Font("TimeRoman", Font.BOLD, 50));
          g.setColor(Color.orange);
          g.drawString("Time: " + dt+"  ",300, 550);
                 if ( dt == 0 ) gameover = true;
        }
    }
  
      class TimeBomb extends TimerTask  {
       
       public void run(){
     
        while(true){
               for(int j=0;j<countball;j++){
               ball[j].move();
              
                  // ラケットとボールの衝突処理
            int collidePos0 = racket.collideWith(ball[j]);
            
            // ラケットに当たっていたら
            if (collidePos0 != Racket.NO_COLLISION4) {
                // ボールの当たった位置に応じてボールの速度を変える
                switch (collidePos0) {
                    case Racket.LEFT4:
                        // ラケットの左側に当たったときは左に反射するようにしたい
                        // もしボールが右に進んでいたら反転して左へ
                        // 左に進んでいたらそのまま
                        if (ball[j].getVX() > 0) ball[j].boundX();
                        ball[j].boundY();
                        break;
                    case Racket.RIGHT4:
                        // ラケットの右側に当たったときは右に反射するようにしたい
                        // もしボールが左に進んでいたら反転して右へ
                        // 右に進んでいたらそのまま
                        if (ball[j].getVX() < 0) ball[j].boundX();
                        ball[j].boundY();
                        break;
                }
            }
               for (int i = 0; i < NUM_BLOCK; i++) {
                   // すでに消えているブロックは無視
                   if (block[i].isDeleted())
                       continue;
                   // ブロックの当たった位置を計算
                   int collidePos = block[i].collideWith(ball[j]);
                   // ブロックに当たっていたら
                   if (collidePos != Block.NO_COLLISION) {
                       block[i].delete();
              
                       // ボールの当たった位置からボールの反射方向を計算
                       switch (collidePos) {
                           case Block.DOWN :
                           case Block.UP :
                               ball[j].boundY();
                               break;
                           case Block.LEFT :
                           case Block.RIGHT :
                               ball[j].boundX();
                               break;
                           case Block.UP_LEFT :
                           case Block.UP_RIGHT :
                           case Block.DOWN_LEFT :
                           case Block.DOWN_RIGHT :
                               ball[j].boundXY();
                               break;
                       }
                       break; // 1回に壊せるブロックは1つ
                    }
                }
               for (int i = 0; i < NUM_BLOCK1; i++) {
                   int collidePos1 = block1[i].collideWith(ball[j]);
                   if ( collidePos1 !=Unbreakblock.NO_COLLISION1) {
                       block1[i].notdelete();
                       
                       switch (collidePos1) {
                           case Unbreakblock.DOWN1 :
                           case Unbreakblock.UP1 :
                               ball[j].boundY();
                               break;
                           case Unbreakblock.LEFT1 :
                           case Unbreakblock.RIGHT1 :
                               ball[j].boundX();
                               break;
                           case Unbreakblock.UP_LEFT1 :
                           case Unbreakblock.UP_RIGHT1 :
                           case Unbreakblock.DOWN_LEFT1 :
                           case Unbreakblock.DOWN_RIGHT1 :
                               ball[j].boundXY();
                               break;
                       }
                       break; 
                   }
                }
               for (int i = 0; i < NUM_BLOCK2; i++) {
                   if (block2[i].isDeleted()){
                       continue;
                    }
                   int collidePos2 = block2[i].collideWith(ball[j]);
                   if ( collidePos2 !=Twobreakblock.NO_COLLISION2) {
                      
                           block2[i].delete();
                      
                       switch (collidePos2) {
                         
                           case Twobreakblock.DOWN2 :
                           case Twobreakblock.UP2 :
                               ball[j].boundY();
                               break;
                          
                           case Twobreakblock.LEFT2 :
                           case Twobreakblock.RIGHT2 :
                               ball[j].boundX();
                               break;
                         
                           case Twobreakblock.UP_LEFT2 :
                           case Twobreakblock.UP_RIGHT2 :
                           case Twobreakblock.DOWN_LEFT2 :
                           case Twobreakblock.DOWN_RIGHT2 :

                               ball[j].boundXY();
                               break;
                       }
                       break; 
                   }
               }
               
              for (int i = 0; i < NUM_BLOCK3; i++) {
               if (block3[i].isDeleted()){
     
                   continue;
               }
                   int collidePos3 = block3[i].collideWith(ball[j]);
                   
                   if ( collidePos3 !=Threebreakblock.NO_COLLISION3) {
                       block3[i].delete();
                      
                       
                       switch (collidePos3) {
                         
                           case Threebreakblock.DOWN3 :
                           case Threebreakblock.UP3 :
                               ball[j].boundY();
                               break;
                          
                           case Threebreakblock.LEFT3 :
                           case Threebreakblock.RIGHT3 :
                               ball[j].boundX();
                               break;
                         
                           case Threebreakblock.UP_LEFT3 :
                           case Threebreakblock.UP_RIGHT3 :
                           case Threebreakblock.DOWN_LEFT3 :
                           case Threebreakblock.DOWN_RIGHT3 :
                               ball[j].boundXY();
                               break;
                       }
                       break; 
                    }
                }
               }
               repaint();
               try {
                   Thread.sleep(20);
               }catch(InterruptedException e){
                   e.printStackTrace();
                   
               }
            }
       }
      }
        
       public void paintComponent(Graphics g){
           racket.draw(g);
           displayTime(g);
           
           for(int i=0;i<countball;i++){
               ball[i].draw(g);
           }
           
           for (int i=0;i<NUM_BLOCK;i++){
               if(!block[i].isDeleted()){
                   block[i].draw(g);
               }
           }
           for (int i=0;i<NUM_BLOCK1;i++){
               if(!block1[i].isDeleted()){
                   block1[i].draw(g);
               }
           }
          
          for (int i=0;i<NUM_BLOCK2;i++){
               if(!block2[i].isDeleted()){
                   block2[i].draw(g);
               }
           }
           
           for (int i=0;i<NUM_BLOCK3;i++){
               if(!block3[i].isDeleted()){
                   block3[i].draw(g);
               }
           }
               for (int y = 0; y <= MY; y++) {
                 for (int x = 0; x <= MX; x++) {
                   int xx = 40*x, yy = 40*y;
                   switch ( map[y][x] ) {
                     //ブロックの描画
             case 'B':  g.setColor(Color.green);
                        g.fillRect(xx, yy, 26, 10);
                        g.fillRect(xx+32, yy, 8, 10);
                        g.fillRect(xx, yy+15, 10, 10);
                        g.fillRect(xx+16, yy+15, 24, 10);
                        g.fillRect(xx, yy+30, 18, 10);
                        g.fillRect(xx+24, yy+30, 16, 10);
                        break;
                   }
                }
            } 
        }
       
       @Override
       public void mouseMoved(MouseEvent e){
          int x =e.getX();
         racket.move(x);
           repaint();
       }
       @Override
       public void mouseDragged(MouseEvent e){

       }
    }
        class Racket {
       public int width =120;
       public static  int height = 5;
       public static final int NO_COLLISION4 = 0;  // 未衝突
       public static final int LEFT4 = 1;
       public static final int RIGHT4 = 2;
                private int center;
   
        public Racket (){
       center = breakout.x/2;
   
        }       
        public int  collideWith(Ball ball) {
      //ボールの衝突判定
        Rectangle racketRectLeft = new Rectangle(
               center - width / 2, breakout.y - height-90,
               width/2, height);
               Rectangle racketRectRight = new Rectangle(
                center, breakout.y - height-90,
                width / 2, height);
      
        Rectangle ballRect = new Rectangle(
               ball.getX(), ball.getY(),
               ball.getSize(), ball.getSize());
        if (racketRectLeft.intersects(ballRect)) {
           return LEFT4;
        }
        else if (racketRectRight.intersects(ballRect)) {
        return RIGHT4;
        }
       return NO_COLLISION4;
        }

        public  void draw (Graphics g){
        g.setColor(Color.WHITE);
        g.fillRect(center - width/2,breakout.y-height-90,width,height);
   
        }
        public void move (int x ){
      center =x;
       if (center<(width/2)+40)
       center =(width/2)+40;
       else if (center > breakout.x - (width / 2)-55) 
           center = breakout.x - (width / 2)-55;
   
        }
        }
     class Ball  {
       
      private   int x;
       private  int y;
       private  int vx;
       private  int vy;
       private int size;
       double time;
       int remain=37;
       boolean gameover=false;
       int dt = (int) (time - System.currentTimeMillis() * 0.001);
       Random rand ;
       public Ball(int  x,int y,int vx,int vy,int size ){
           
   this.x=x;
   this.y=y;
   this.vx=vx;
   this.vy=vy;
     this.size =size;    
     time = System.currentTimeMillis() * 0.001 + remain; 
       }
        public  void draw(Graphics g){
           
   g.setColor(Color.RED);
   g.fillOval(x,y,size,size);
  
       }
       
       public int   Size(){
  return size=size-3;
       } 
       public void move(){
         
           if ( gameover ) {
         x=0;
         y=0;
            } else {
            int dt = (int) (time - System.currentTimeMillis() * 0.001);
            x += vx;
            y += vy;
          
            if ( dt == 0 ) gameover = true;
         
            }
           if (x < 40 || x > breakout.x - size-60) {
             boundX();
           }
           if (y < 40  ) {
             boundY();
           }
        }
           public void boundX(){
            vx=-vx;
           }   
           public void boundY(){
            vy=-vy;
           }
       public int getX(){
           return x;
       }
       public void boundXY(){
           vx=-vx;
           vy=-vy;
       }
       public int getY(){
           return y;
       }
       public int getSize(){
           return size;
       }
       public int getVX(){
           return vx;
       }
       public int getVY(){
           return vy;
           
       }
    public void setVX(int v){
        vx=v;
       
    }
    public void setVY(int v){
         vy=v;
      
    }
}
       class Block {
           public static final int WIDTH = 40;
           public static final int HEIGHT = 16;
           public static final int NO_COLLISION = 0; // 未衝突
           public static final int DOWN = 1;
           public static final int LEFT = 2;
           public static final int RIGHT = 3;
           public static final int UP = 4;
           public static final int DOWN_LEFT = 5;
           public static final int DOWN_RIGHT = 6;
           public static final int UP_LEFT = 7;
           public static final int UP_RIGHT = 8;
       
       
           // 位置（左上隅の座標）
           private int x, y;
    
           // ボールが当たって消されたか
           private boolean isDeleted;
       
           public Block(int x, int y) {
               this.x = x;
               this.y = y;
               isDeleted = false;
           }
        
           public void draw(Graphics g) {
               g.setColor(Color.CYAN);
               g.fillRect(x, y, WIDTH, HEIGHT);
       
               // 枠線を描画
               g.setColor(Color.BLACK);
               g.drawRect(x, y, WIDTH, HEIGHT);
           }
           public int collideWith(Ball ball) {
               Rectangle blockRect = new Rectangle(x, y, WIDTH, HEIGHT);
       
               int ballX = ball.getX();
               int ballY = ball.getY();
               int ballSize = ball.getSize();
               if (blockRect.contains(ballX, ballY)
                   && blockRect.contains(ballX + ballSize, ballY)) {
                   // ブロックの下から衝突＝ボールの左上・右上の点がブロック内
                   return DOWN;
               } else if (blockRect.contains(ballX + ballSize, ballY)
                   && blockRect.contains(ballX + ballSize, ballY + ballSize)) {
                   // ブロックの左から衝突＝ボールの右上・右下の点がブロック内
                   return LEFT;
               } else if (blockRect.contains(ballX, ballY)
                   && blockRect.contains(ballX, ballY + ballSize)) {
                   // ブロックの右から衝突＝ボールの左上・左下の点がブロック内
                   return RIGHT;
               } else if (blockRect.contains(ballX, ballY + ballSize)
                   && blockRect.contains(ballX + ballSize, ballY + ballSize)) {
                   // ブロックの上から衝突＝ボールの左下・右下の点がブロック内
                   return UP;
               } else if (blockRect.contains(ballX + ballSize, ballY)) {
                   // ブロックの左下から衝突＝ボールの右上の点がブロック内
                   return DOWN_LEFT;
               } else if (blockRect.contains(ballX, ballY)) {
                   // ブロックの右下から衝突＝ボールの左上の点がブロック内
                   return DOWN_RIGHT;
               } else if (blockRect.contains(ballX + ballSize, ballY + ballSize)) {
                   // ブロックの左上から衝突＝ボールの右下の点がブロック内
                   return UP_LEFT;
               } else if (blockRect.contains(ballX, ballY + ballSize)) {
                   // ブロックの右上から衝突＝ボールの左下の点がブロック内
                   return UP_RIGHT;
               }
       
               return NO_COLLISION;
           }
           public void delete() {
              
       
               isDeleted = true;
           }
         
            public int getX(){
                return x;
            } 
            public int getY(){
               
               return y;
            }
            public boolean isDeleted(){
                return isDeleted;
            }
        }
     interface figure1 {
        public void draw(Graphics g);
        public int collideWith(Ball ball);
        public int getX();
        public int getY();
        public boolean isDeleted();
  
     }
class Unbreakblock implements figure1 {
   public static final int WIDTH1 = 40;
   public static final int HEIGHT1 = 16;
   public static final int NO_COLLISION1= 0; 
   public static final int DOWN1= 1;
   public static final int LEFT1 = 2;
   public static final int RIGHT1 = 3;
   public static final int UP1 = 4;
   public static final int DOWN_LEFT1 = 5;
   public static final int DOWN_RIGHT1 = 6;
   public static final int UP_LEFT1 = 7;
   public static final int UP_RIGHT1 = 8;
   private int a, b;
   private boolean isDeleted;
   public Unbreakblock(int a, int b) {
       this.a = a;
       this.b = b;
       isDeleted = false;
   }
   public void draw(Graphics g) {
       g.setColor(Color.GRAY);
       g.fillRect(a, b, WIDTH1, HEIGHT1);
       g.setColor(Color.BLACK);
       g.drawRect(a, b, WIDTH1, HEIGHT1);
   }
   public int collideWith(Ball ball) {
       Rectangle blockRect = new Rectangle(a, b, WIDTH1, HEIGHT1);
   
       int ballX = ball.getX();
       int ballY = ball.getY();
       int ballSize = ball.getSize();
       if (blockRect.contains(ballX, ballY)
           && blockRect.contains(ballX + ballSize, ballY)) {
          
           return DOWN1;
       } else if (blockRect.contains(ballX + ballSize, ballY)
           && blockRect.contains(ballX + ballSize, ballY + ballSize)) {
           
           return LEFT1;
       } else if (blockRect.contains(ballX, ballY)
           && blockRect.contains(ballX, ballY + ballSize)) {
          
           return RIGHT1;
       } else if (blockRect.contains(ballX, ballY + ballSize)
           && blockRect.contains(ballX + ballSize, ballY + ballSize)) {
          
           return UP1;
       } else if (blockRect.contains(ballX + ballSize, ballY)) {
           
           return DOWN_LEFT1;
       } else if (blockRect.contains(ballX, ballY)) {
          
           return DOWN_RIGHT1;
       } else if (blockRect.contains(ballX + ballSize, ballY + ballSize)) {
         
           return UP_LEFT1;
       } else if (blockRect.contains(ballX, ballY + ballSize)) {
         
           return UP_RIGHT1;
       }
   
       return NO_COLLISION1;
    }
   public void notdelete() {
       isDeleted = false ;
   }
    public int getX(){
        return a;
    } 
    public int getY(){
       
       return b;
    }
    public boolean isDeleted(){
        return isDeleted;
    }
}
   class Twobreakblock implements figure1 {
       public static final int WIDTH2 = 40;
       public static final int HEIGHT2 = 16;
       public static final int NO_COLLISION2= 0; 
       public static final int DOWN2= 21;
       public static final int LEFT2 = 22;
       public static final int RIGHT2 = 23;
       public static final int UP2 = 24;
       public static final int DOWN_LEFT2 = 25;
       public static final int DOWN_RIGHT2 = 26;
       public static final int UP_LEFT2 = 27;
       public static final int UP_RIGHT2 = 28;
    int a, b;
        int count =2;
       private boolean isDeleted;
       public Twobreakblock(int a, int b) {
           this.a = a;
           this.b = b;
           isDeleted = false;
       }
       public void draw(Graphics g) {
           g.setColor(Color.GREEN);
           g.fillRect(a, b, WIDTH2, HEIGHT2);
   
          
           g.setColor(Color.BLACK);
           g.drawRect(a, b, WIDTH2, HEIGHT2);
       }
       public int collideWith(Ball ball) {
           Rectangle blockRect = new Rectangle(a, b, WIDTH2, HEIGHT2);
   
           int ballX = ball.getX();
           int ballY = ball.getY();
           int ballSize = ball.getSize();
           if (blockRect.contains(ballX, ballY)
               && blockRect.contains(ballX + ballSize, ballY)) {
              
               return DOWN2;
           } else if (blockRect.contains(ballX + ballSize, ballY)
               && blockRect.contains(ballX + ballSize, ballY + ballSize)) {
              
               return LEFT2;
           } else if (blockRect.contains(ballX, ballY)
               && blockRect.contains(ballX, ballY + ballSize)) {
               
               return RIGHT2;
           } else if (blockRect.contains(ballX, ballY + ballSize)
               && blockRect.contains(ballX + ballSize, ballY + ballSize)) {
               
               return UP2;
           } else if (blockRect.contains(ballX + ballSize, ballY)) {
               
               return DOWN_LEFT2;
           } else if (blockRect.contains(ballX, ballY)) {
             
               return DOWN_RIGHT2;
           } else if (blockRect.contains(ballX + ballSize, ballY + ballSize)) {
              
               return UP_LEFT2;
           } else if (blockRect.contains(ballX, ballY + ballSize)) {
              
               return UP_RIGHT2;
           }
   
           return NO_COLLISION2;
       }
       public void delete() {
                if(isDeleted==false)
                count--;
                if(count==0)  
           
           isDeleted = true  ;
        } 
        public int getX(){
            return a;
        } 
        public int getY(){
           
           return b;
        }
        public boolean isDeleted(){
            return isDeleted;
        }
     }
     
     class Threebreakblock implements figure1{
       public static final int WIDTH3 = 40;
       public static final int HEIGHT3 = 16;
       public static final int NO_COLLISION3= 0; 
       public static final int DOWN3= 1;
       public static final int LEFT3 = 2;
       public static final int RIGHT3 = 3;
       public static final int UP3 = 4;
       public static final int DOWN_LEFT3 = 5;
       public static final int DOWN_RIGHT3 = 6;
       public static final int UP_LEFT3 = 7;
       public static final int UP_RIGHT3 = 8;
       private int a, b;
        int count =3;
       private boolean isDeleted;
       public Threebreakblock(int a, int b) {
           this.a = a;
           this.b = b;
           isDeleted = false;
       }
       public void draw(Graphics g) {
           g.setColor(Color.YELLOW);
           g.fillRect(a, b, WIDTH3, HEIGHT3);
   
          
           g.setColor(Color.BLACK);
           g.drawRect(a, b, WIDTH3, HEIGHT3);
       }
       public int collideWith(Ball ball) {
           Rectangle blockRect = new Rectangle(a, b, WIDTH3, HEIGHT3);
   
           int ballX = ball.getX();
           int ballY = ball.getY();
           int ballSize = ball.getSize();
           if (blockRect.contains(ballX, ballY)
               && blockRect.contains(ballX + ballSize, ballY)) {
              
               return DOWN3;
           } else if (blockRect.contains(ballX + ballSize, ballY)
               && blockRect.contains(ballX + ballSize, ballY + ballSize)) {
              
               return LEFT3;
           } else if (blockRect.contains(ballX, ballY)
               && blockRect.contains(ballX, ballY + ballSize)) {
               
               return RIGHT3;
           } else if (blockRect.contains(ballX, ballY + ballSize)
               && blockRect.contains(ballX + ballSize, ballY + ballSize)) {
               
               return UP3;
           } else if (blockRect.contains(ballX + ballSize, ballY)) {
               
               return DOWN_LEFT3;
           } else if (blockRect.contains(ballX, ballY)) {
             
               return DOWN_RIGHT3;
           } else if (blockRect.contains(ballX + ballSize, ballY + ballSize)) {
              
               return UP_LEFT3;
           } else if (blockRect.contains(ballX, ballY + ballSize)) {
              
               return UP_RIGHT3;
           }
   
           return NO_COLLISION3;
       }
       public void delete() {
                if(isDeleted==false)
                count--;
                if(count==0)  
           isDeleted = true  ;
        } 
      
        public int getX(){
            return a;
        } 
        public int getY(){
           
           return b;
        }
        public boolean isDeleted(){
            return isDeleted;
        }
     }
```
インデントが汚いですね．．．課題が提出されたそのままの状態を書いております。
breakoutクラスにはそれぞれ、ブロックやボール、ボールを跳ね返すラケットのインスタンス変数を格納しております。
また、extendsでJpanelの機能を継承し、さらに、implementsでマウスイベントを扱えるようにしました。
制限時間は３０秒と設定しておりますが。最初のスタート画面で５秒間待たないといけないようにしました.タイトル画面を含めて３５秒に設定したのになぜか３７秒でないとちょうどゲームがスタートされないようになっています。原因が分かりません。

![breakout03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680378/77854b73-5dba-779f-9675-fa7299844657.png)

いざ実際にコードを説明すると途方もないくらい時間がかかりそう...今回は紹介程度コードを含めて記事を書きました。見てみるともっと省略できる部分もあったのではないか...例えばブロックの機能をほぼ同じコードで重複して書いていたりと、非常にわかりづらい...書けたはいいが相手にわからせなければ意味がないですよね。自己満足で終わらないように今後もわかりやすく相手に伝わるコードを書いていきたいと思います。次回は詳しくコードを説明します