[Java] I tried to make a simple block break

16 minute read

Introduction

For the first time today, I will post to Qiita. To be honest, I am confused as to what to do below, but for the time being, I would like to post as much as possible every day to improve my programming language skills. Thank you

Why did you decide to post on Qiita?

To be honest, I want to add it as an appeal point for job hunting. As it is now, I can understand that even if I can say that I want to aim for an engineer without doing anything, I will fall, so at the very least, I posted it on Qiita and I wanted to disclose my ability. I want to continue posting so that progress can be made only in the fields of my interest

Why did you decide to make a block break

I wanted to post here the game I made in the past as I was free to make it for school assignments. After that, I love block breaking, Tetris and Puyo Puyo, so I wanted to make a retro game.

Block breaking rules

If you’ve done block breaking before, you’ll understand, but it’s necessary to devise a ball so you don’t hit it with a racket or bar and drop it under the screen. When hitting back, hit the ball to the block and erase all blocks, or add points when erasing the block. It’s a very simple game, but it was very difficult to make. breakout.png As shown in the image, this is an example of block breaking. Since only one is boring, I changed the size, speed, and number of balls. It deviates at this point, but for the time being like that. The block also disappears when the ball hits. If it is as shown in the image, it is 3 times if it is yellow, 1 time if it is blue, and 2 times if it is green. However, there was a deadline for submission of the assignment, and I should have counted the number of blocks etc. after the time limit of the game, but it was halfway done because it was not in time. It was always displayed as game clear and the failure condition could not be set. Therefore, I will post it several times to improve it.

Reference site

http://aidiary.hatenablog.com/entry/20040918/1251373370 This site allows you to make a block break. Please refer to here for the basic algorithm. Some are pretty much the same, but it’s really straightforward. Thank you very much.

java environment

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)

Program code

Since it is close to 900 lines, I would like to explain each article separately. I don’t think I’ll get tired of doing that…


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("Title screen");
        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, "text drawing");
       // 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("Block breaking", 300, 200);
      g.setColor(Color.red);
      g.drawString("It will start in 5 seconds!", 250, 300);
      g.drawString("Time limit is 30 seconds", 250, 400);
      g.setColor(Color.red);
      g.setColor(Color.red);
      g.drawString("Move the mouse sideways to bounce the ball", 125, 500);
      g.setColor(Color.red);
      g.drawString("The mouse has the tip of the arrow below it in the initial position", 100, 600);
      g.setColor(Color.red);
      g.drawString("↓", 425, 700);
    }
  }
  }

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;
   // 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;
    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;
 
    //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",                        
                                 };
                                 
       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();// racquet and ball collision handling
            int collidePos0 = racket.collideWith(ball[j]);
            
            // If you hit the racket
            if (collidePos0 != Racket.NO_COLLISION4) {
                // change the speed of the ball depending on where it hits
                switch (collidePos0) {
                    case Racket.LEFT4:
                        // If you hit the left side of the racket, you want to reflect it to the left
                        // If the ball is going to the right, flip it and go to the left
                        // If you are going to the left
                        if (ball[j].getVX()> 0) ball[j].boundX();
                        ball[j].boundY();
                        break;
                    case Racket.RIGHT4:
                        // When you hit the right side of the racket, you want it to reflect to the right
                        // If the ball goes to the left, flip it over and go to the right
                        // If you are going to the right
                        if (ball[j].getVX() <0) ball[j].boundX();
                        ball[j].boundY();
                        break;
                }
            }
               for (int i = 0; i <NUM_BLOCK; i++) {
                   // ignore blocks that have already disappeared
                   if (block[i].isDeleted())
                       continue;
                   // Calculate the hit position of the block
                   int collidePos = block[i].collideWith(ball[j]);
                   // If you hit a block
                   if (collidePos != Block.NO_COLLISION) {
                       block[i].delete();
              
                       //Calculate the direction of the ball's reflection from where it hits
                       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; // One block can be broken at one time
                    }
                }
               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でマウスイベントを扱えるようにしました。 制限時間は30秒と設定しておりますが。最初のスタート画面で5秒間待たないといけないようにしました.タイトル画面を含めて35秒に設定したのになぜか37秒でないとちょうどゲームがスタートされないようになっています。原因が分かりません。

breakout03.png

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

Tags:

Updated: