Interactive Grid-Bomb Sandbox (With Enemies)
Click to plant a bomb! Blow up the moving enemies (👾).
Complete Java Source Code
Copy the source code below to run it inside your local desktop Java IDE environment:
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.Random;
import javax.swing.*;
public class Bomberman extends JFrame implements ActionListener {
private final JButton[][] grid;
private final int[][] bombs;
private final Timer timer;
private final int ROWS = 10;
private final int COLS = 10;
private final ArrayList<Point> enemies;
private final Random rand = new Random();
public Bomberman() {
super("Bomberman Desktop Engine (Enemies Embedded)");
setLayout(new GridLayout(ROWS, COLS));
grid = new JButton[ROWS][COLS];
bombs = new int[ROWS][COLS];
enemies = new ArrayList<>();
// Spawn initial 4 enemies
enemies.add(new Point(2, 2));
enemies.add(new Point(2, 7));
enemies.add(new Point(7, 2));
enemies.add(new Point(7, 7));
for (int row = 0; row < ROWS; row++) {
for (int col = 0; col < COLS; col++) {
grid[row][col] = new JButton();
grid[row][col].setBackground(Color.LIGHT_GRAY);
add(grid[row][col]);
grid[row][col].addActionListener(this);
}
}
updateGridRendering();
int delay = 1000;
timer = new Timer(delay, this);
timer.start();
setSize(500, 500);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(Bomberman::new);
}
@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == timer) {
handleTimerTick();
} else {
handleButtonClick((JButton) e.getSource());
}
}
private void handleButtonClick(JButton clickedButton) {
for (int row = 0; row < ROWS; row++) {
for (int col = 0; col < COLS; col++) {
if (clickedButton == grid[row][col]) {
if (bombs[row][col] == 0) {
grid[row][col].setText("💣");
grid[row][col].setBackground(Color.RED);
bombs[row][col] = 4;
}
return;
}
}
}
}
private void handleTimerTick() {
boolean[][] toExplode = new boolean[ROWS][COLS];
for (int row = 0; row < ROWS; row++) {
for (int col = 0; col < COLS; col++) {
if (bombs[row][col] > 0) {
bombs[row][col]--;
if (bombs[row][col] == 0) {
toExplode[row][col] = true;
} else {
grid[row][col].setText("💣 (" + bombs[row][col] + ")");
}
}
}
}
for (int row = 0; row < ROWS; row++) {
for (int col = 0; col < COLS; col++) {
if (toExplode[row][col]) {
triggerExplosion(row, col);
}
}
}
moveEnemies();
updateGridRendering();
}
private void moveEnemies() {
int[][] directions = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
for (Point enemy : enemies) {
ArrayList<Point> validMoves = new ArrayList<>();
for (int[] dir : directions) {
int nr = enemy.x + dir[0];
int nc = enemy.y + dir[1];
if (nr >= 0 && nr < ROWS && nc >= 0 && nc < COLS && bombs[nr][nc] == 0) {
validMoves.add(new Point(nr, nc));
}
}
if (!validMoves.isEmpty()) {
Point choice = validMoves.get(rand.nextInt(validMoves.size()));
enemy.setLocation(choice.x, choice.y);
}
}
}
private void updateGridRendering() {
for (int row = 0; row < ROWS; row++) {
for (int col = 0; col < COLS; col++) {
if (bombs[row][col] > 0) continue;
boolean hasEnemy = false;
for (Point enemy : enemies) {
if (enemy.x == row && enemy.y == col) {
hasEnemy = true;
break;
}
}
if (hasEnemy) {
grid[row][col].setText("👾");
} else if (grid[row][col].getText().equals("👾") || grid[row][col].getText().equals("")) {
grid[row][col].setText("");
}
}
}
}
private void triggerExplosion(int r, int c) {
int[][] directions = {{0, 0}, {-1, 0}, {1, 0}, {0, -1}, {0, 1}};
for (int[] dir : directions) {
int newRow = r + dir[0];
int newCol = c + dir[1];
if (newRow >= 0 && newRow < ROWS && newCol >= 0 && newCol < COLS) {
grid[newRow][newCol].setText("💥");
grid[newRow][newCol].setBackground(Color.ORANGE);
// Blast kills enemy
for (int i = enemies.size() - 1; i >= 0; i--) {
Point p = enemies.get(i);
if (p.x == newRow && p.y == newCol) {
enemies.remove(i);
}
}
int finalRow = newRow;
int finalCol = newCol;
Timer clearTimer = new Timer(500, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
grid[finalRow][finalCol].setText("");
grid[finalRow][finalCol].setBackground(Color.LIGHT_GRAY);
updateGridRendering();
}
});
clearTimer.setRepeats(false);
clearTimer.start();
}
}
}
}