お疲れ様です。はるさらと申します。
今回は、Javaを使ってシンプルな
ブロック崩しゲームを作成する方法を紹介します。
ブロック崩しは、プレイヤーがパドルを使ってボールを打ち、
画面上のブロックを崩していくゲームです。
この記事では、ゲームの基本的なコードとその解説を行います。
1つのjavaファイルで作成しており
コピペして実行すれば稼働するコードを貼り付けています。
完成すると下記のようなゲームが起動します。

スキルの向上や
課題・プログラム制作等に
役立てていただければ幸いです。
必要なライブラリ
JavaでGUIを作成するために、javax.swing
とjava.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ライブラリを使用して
シンプルなブロック崩しゲームを作成しました。
実際にコピペして起動してみて
色々数値などいじってみていただければ
仕組み等が分かってくると思います。
このソースでゲームの基本的なロジックやグラフィックス描画、
イベント処理について学びながらゲームを作成する手助けになれれば幸いです。
また、スタート・エンディング画面や
玉のスピードの加速処理など
ゲームとしての完成度はまだ低いので
是非、機能追加して自分だけのゲームを完成させてください!
それではまたー!