おすすめアイテムをいくつか紹介

広告ブロックがONになっていると表示されないことがあります。

【Java】コピペでOK!シンプルなブロック崩しゲームを作ろう!

お疲れ様です。はるさらと申します。

今回は、Javaを使ってシンプルな
ブロック崩しゲームを作成する方法を紹介します。
ブロック崩しは、プレイヤーがパドルを使ってボールを打ち、
画面上のブロックを崩していくゲームです。

この記事では、ゲームの基本的なコードとその解説を行います。
1つのjavaファイルで作成しており
コピペして実行すれば稼働するコードを貼り付けています。

完成すると下記のようなゲームが起動します。

スキルの向上や
課題・プログラム制作等に
役立てていただければ幸いです。

必要なライブラリ

JavaでGUIを作成するために、
javax.swingjava.awtパッケージを使用します。

これらには、ウィンドウを作成するためのクラスや、
グラフィックス描画、イベント処理のためのクラスが含まれています。

コードの全体像

以下が、シンプルではありますが
ブロック崩しゲームを作成するためのJavaプログラムです。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
 
public class BreakoutGame extends JPanel implements ActionListener {
    private static final int WIDTH = 800;
    private static final int HEIGHT = 600;
    private static final int PADDLE_WIDTH = 100;
    private static final int PADDLE_HEIGHT = 20;
    private static final int BALL_SIZE = 20;
    private static final int BLOCK_WIDTH = 60;
    private static final int BLOCK_HEIGHT = 30;
    private static final int BLOCK_ROWS = 5;
    private static final int BLOCK_COLUMNS = 10;
    private static final int BLOCK_PADDING = 10;
 
    private Timer timer;
    private int paddleX;
    private int ballX, ballY, ballDX, ballDY;
    private List<Rectangle> blocks;
 
    public BreakoutGame() {
        setPreferredSize(new Dimension(WIDTH, HEIGHT));
        setBackground(Color.BLACK);
        setFocusable(true);
        addKeyListener(new PaddleMover());
 
        initGame();
        timer = new Timer(10, this);
        timer.start();
    }
 
    private void initGame() {
        paddleX = WIDTH / 2 - PADDLE_WIDTH / 2;
        ballX = WIDTH / 2 - BALL_SIZE / 2;
        ballY = HEIGHT / 2 - BALL_SIZE / 2;
        ballDX = 2;
        ballDY = -2;
 
        blocks = new ArrayList<>();
        for (int row = 0; row < BLOCK_ROWS; row++) {
            for (int col = 0; col < BLOCK_COLUMNS; col++) {
                int x = col * (BLOCK_WIDTH + BLOCK_PADDING) + BLOCK_PADDING;
                int y = row * (BLOCK_HEIGHT + BLOCK_PADDING) + BLOCK_PADDING;
                blocks.add(new Rectangle(x, y, BLOCK_WIDTH, BLOCK_HEIGHT));
            }
        }
    }
 
    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
 
        g.setColor(Color.WHITE);
        g.fillRect(paddleX, HEIGHT - PADDLE_HEIGHT, PADDLE_WIDTH, PADDLE_HEIGHT);
        g.fillOval(ballX, ballY, BALL_SIZE, BALL_SIZE);
 
        g.setColor(Color.RED);
        for (Rectangle block : blocks) {
            g.fillRect(block.x, block.y, block.width, block.height);
        }
    }
 
    @Override
    public void actionPerformed(ActionEvent e) {
        ballX += ballDX;
        ballY += ballDY;
 
        if (ballX <= 0 || ballX >= WIDTH - BALL_SIZE) {
            ballDX = -ballDX;
        }
        if (ballY <= 0) {
            ballDY = -ballDY;
        }
        if (ballY >= HEIGHT - BALL_SIZE) {
            initGame();
        }
 
        Rectangle ballRect = new Rectangle(ballX, ballY, BALL_SIZE, BALL_SIZE);
        Rectangle paddleRect = new Rectangle(paddleX, HEIGHT - PADDLE_HEIGHT, PADDLE_WIDTH, PADDLE_HEIGHT);
 
        if (ballRect.intersects(paddleRect)) {
            ballDY = -ballDY;
        }
 
        List<Rectangle> blocksToRemove = new ArrayList<>();
        for (Rectangle block : blocks) {
            if (ballRect.intersects(block)) {
                ballDY = -ballDY;
                blocksToRemove.add(block);
            }
        }
        blocks.removeAll(blocksToRemove);
 
        if (blocks.isEmpty()) {
            initGame();
        }
 
        repaint();
    }
 
    private class PaddleMover extends KeyAdapter {
        @Override
        public void keyPressed(KeyEvent e) {
            if (e.getKeyCode() == KeyEvent.VK_LEFT) {
                paddleX -= 10;
            }
            if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
                paddleX += 10;
            }
        }
    }
 
    public static void main(String[] args) {
        JFrame frame = new JFrame("Breakout Game");
        BreakoutGame game = new BreakoutGame();
        frame.add(game);
        frame.pack();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }
}

コードの解説

1. インポートとクラス定義

1
2
3
4
5
6
7
8
9
10
11
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
 
public class BreakoutGame extends JPanel implements ActionListener {
  • javax.swing.*java.awt.* パッケージをインポートします。
    これにより、Swingコンポーネントやグラフィックス描画機能を使用できます。
  • BreakoutGame クラスは JPanel を拡張し、ActionListener を実装します。
    これにより、ゲームの描画とタイマーイベントを処理しています。

2. 初期化と設定

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
private static final int WIDTH = 800;
private static final int HEIGHT = 600;
private static final int PADDLE_WIDTH = 100;
private static final int PADDLE_HEIGHT = 20;
private static final int BALL_SIZE = 20;
private static final int BLOCK_WIDTH = 60;
private static final int BLOCK_HEIGHT = 30;
private static final int BLOCK_ROWS = 5;
private static final int BLOCK_COLUMNS = 10;
private static final int BLOCK_PADDING = 10;
 
private Timer timer;
private int paddleX;
private int ballX, ballY, ballDX, ballDY;
private List<Rectangle> blocks;
  • ゲームのウィンドウサイズ、パドル、
    ボール、ブロックのサイズなどの定数を定義します。
  • ゲームの状態を保持するための変数
    (パドルの位置、ボールの位置と速度、ブロックのリストなど)を宣言します。

3. ゲームの初期化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public BreakoutGame() {
    setPreferredSize(new Dimension(WIDTH, HEIGHT));
    setBackground(Color.BLACK);
    setFocusable(true);
    addKeyListener(new PaddleMover());
 
    initGame();
    timer = new Timer(10, this);
    timer.start();
}
 
private void initGame() {
    paddleX = WIDTH / 2 - PADDLE_WIDTH / 2;
    ballX = WIDTH / 2 - BALL_SIZE / 2;
    ballY = HEIGHT / 2 - BALL_SIZE / 2;
    ballDX = 2;
    ballDY = -2;
 
    blocks = new ArrayList<>();
    for (int row = 0; row < BLOCK_ROWS; row++) {
        for (int col = 0; col < BLOCK_COLUMNS; col++) {
            int x = col * (BLOCK_WIDTH + BLOCK_PADDING) + BLOCK_PADDING;
            int y = row * (BLOCK_HEIGHT + BLOCK_PADDING) + BLOCK_PADDING;
            blocks.add(new Rectangle(x, y, BLOCK_WIDTH, BLOCK_HEIGHT));
        }
    }
}
  • コンストラクタで、パネルのサイズを設定し、背景色を黒にします。
    また、キーリスナーを追加してパドルの操作を可能にします。
  • initGame メソッドで、ゲームの初期状態
    (パドル、ボール、ブロックの配置など)を設定しています。

4. 描画処理

1
2
3
4
5
6
7
8
9
10
11
12
13
@Override
protected void paintComponent(Graphics g) {
    super.paintComponent(g);
 
    g.setColor(Color.WHITE);
    g.fillRect(paddleX, HEIGHT - PADDLE_HEIGHT, PADDLE_WIDTH, PADDLE_HEIGHT);
    g.fillOval(ballX, ballY, BALL_SIZE, BALL_SIZE);
 
    g.setColor(Color.RED);
    for (Rectangle block : blocks) {
        g.fillRect(block.x, block.y, block.width, block.height);
    }
}
  • paintComponent メソッドで、パドル、ボール、ブロックを描画します。
    背景が黒なので、パドルとボールは白、ブロックは赤で描画しています。

5.ゲームロジックとイベント処理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
@Override
public void actionPerformed(ActionEvent e) {
    ballX += ballDX;
    ballY += ballDY;
 
    if (ballX <= 0 || ballX >= WIDTH - BALL_SIZE) {
        ballDX = -ballDX;
    }
    if (ballY <= 0) {
        ballDY = -ballDY;
    }
    if (ballY >= HEIGHT - BALL_SIZE) {
        initGame();
    }
 
    Rectangle ballRect = new Rectangle(ballX, ballY, BALL_SIZE, BALL_SIZE);
    Rectangle paddleRect = new Rectangle(paddleX, HEIGHT - PADDLE_HEIGHT, PADDLE_WIDTH, PADDLE_HEIGHT);
 
    if (ballRect.intersects(paddleRect)) {
        ballDY = -ballDY;
    }
 
    List<Rectangle> blocksToRemove = new ArrayList<>();
    for (Rectangle block : blocks) {
        if (ballRect.intersects(block)) {
            ballDY = -ballDY;
            blocksToRemove.add(block);
        }
    }
    blocks.removeAll(blocksToRemove);
 
    if (blocks.isEmpty()) {
        initGame();
    }
 
    repaint();
}
  • actionPerformed メソッドで、ボールの位置を更新し、
    壁との衝突を処理します。
    また、ボールとパドルの衝突を検出し、ボールの方向を反転させます。
  • ボールとブロックの衝突を検出し、ブロックを削除します。
    すべてのブロックが削除された場合は、ゲームを再初期化しています。
  • repaint() メソッドを呼び出して、画面を更新します。

6. パドルの操作

1
2
3
4
5
6
7
8
9
10
11
private class PaddleMover extends KeyAdapter {
    @Override
    public void keyPressed(KeyEvent e) {
        if (e.getKeyCode() == KeyEvent.VK_LEFT) {
            paddleX -= 10;
        }
        if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
            paddleX += 10;
        }
    }
}
  • PaddleMover クラスで、キーボードの左右矢印キーで
    パドルを移動させる処理を実装します。

7. メインメソッド

1
2
3
4
5
6
7
8
public static void main(String[] args) {
    JFrame frame = new JFrame("Breakout Game");
    BreakoutGame game = new BreakoutGame();
    frame.add(game);
    frame.pack();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setVisible(true);
}
  • main メソッドで、JFrame を作成し、BreakoutGame パネルを追加して表示します。

javaでブロック崩しを作成するまとめ

今回は、JavaのSwingライブラリを使用して
シンプルなブロック崩しゲームを作成しました。

実際にコピペして起動してみて
色々数値などいじってみていただければ
仕組み等が分かってくると思います。

このソースでゲームの基本的なロジックやグラフィックス描画、
イベント処理
について学びながらゲームを作成する手助けになれれば幸いです。

また、スタート・エンディング画面
玉のスピードの加速処理など
ゲームとしての完成度はまだ低いので
是非、機能追加して自分だけのゲームを完成させてください!

それではまたー!