import java.awt.*; import java.applet.*; import java.util.*; public class bomberman extends Applet implements Runnable { private int height, width; private int delay = 83; // 12 fps private Game game; private Thread animate; private MediaTracker tracker; private Graphics offgfx, bggfx; private Image offimage, bgImage; private Font infoFont = new Font("Helvetica", Font.PLAIN, 14); private FontMetrics infoMetrics; public void init() { width = Integer.parseInt(getParameter("width")); height = Integer.parseInt(getParameter("height")); game = new Game((int)(width / 28), (int)(height / 28)); // initialize graphics tracker = new MediaTracker(this); Bomberguy.initResources(this, tracker, 0); Bomb.initResources(this, tracker, 0); Floor.initResources(this, tracker, 0); Block.initResources(this, tracker, 0); Brick.initResources(this, tracker, 0); BlastC.initResources(this, tracker, 0); BlastV.initResources(this, tracker, 0); BlastH.initResources(this, tracker, 0); BlastLEFT.initResources(this, tracker, 0); BlastUP.initResources(this, tracker, 0); BlastRIGHT.initResources(this, tracker, 0); BlastDOWN.initResources(this, tracker, 0); fireItem.initResources(this, tracker, 0); setBackground(Color.green); } public void start() { if (animate == null) { animate = new Thread(this); animate.start(); } } public void stop() { if (animate != null) { animate.stop(); animate = null; } } public void run() { try { tracker.waitForID(0); } catch (InterruptedException e) { return; } // Setup a new game newGame(); // Update everything long t = System.currentTimeMillis(); while (Thread.currentThread() == animate) { repaint(); try { t += delay; Thread.sleep(Math.max(0, t - System.currentTimeMillis())); } catch (InterruptedException e) { break; } } } public void update(Graphics g) { // Create the offscreen graphics context if (offimage == null) { offimage = createImage(width, height); offgfx = offimage.getGraphics(); infoMetrics = offgfx.getFontMetrics(infoFont); } if (bgImage == null) { bgImage = createImage(width, height); bggfx = bgImage.getGraphics(); game.createBackground(bggfx); } offgfx.drawImage(bgImage, 0, 0, null); // Draw the sprites game.draw(offgfx); // Draw the image onto the screen g.drawImage(offimage, 0, 0, null); } public void paint(Graphics g) { if ((tracker.statusID(0, true) & MediaTracker.ERRORED) != 0) { // Draw the error rectangle g.setColor(Color.red); g.fillRect(0, 0, width, height); return; } if ((tracker.statusID(0, true) & MediaTracker.COMPLETE) != 0) { // Draw the offscreen image g.drawImage(offimage, 0, 0, null); } else { // Draw the title message (while the images load) Font f1 = new Font("TimesRoman", Font.BOLD, 28), f2 = new Font("Helvetica", Font.PLAIN, 16); FontMetrics fm1 = g.getFontMetrics(f1), fm2 = g.getFontMetrics(f2); String s1 = new String("Bomberman"), s2 = new String("Loading images..."); g.setFont(f1); g.drawString(s1, (size().width - fm1.stringWidth(s1)) / 2, ((height - fm1.getHeight()) / 2) + fm1.getAscent()); g.setFont(f2); g.drawString(s2, (size().width - fm2.stringWidth(s2)) / 2, size().height - fm2.getHeight() - fm2.getAscent()); } } public boolean keyDown(Event e, int key) { switch(key){ // player 1 input case (int)'8': game.moveBomberguy(0, 2, 0, -1); break; case (int)'6': game.moveBomberguy(0, 3, 1, 0); break; case (int)'4': game.moveBomberguy(0, 1, -1, 0); break; case (int)'2': game.moveBomberguy(0, 0, 0, 1); break; case (int)'5': game.setBomb(0); break; // player 2 input case Event.UP: game.moveBomberguy(1, 2, 0, -1); break; case Event.RIGHT: game.moveBomberguy(1, 3, 1, 0); break; case Event.LEFT: game.moveBomberguy(1, 1, -1, 0); break; case Event.DOWN: game.moveBomberguy(1, 0, 0, 1); break; case (int)' ': game.setBomb(1); break; // player 3 input case (int)'w': game.moveBomberguy(2, 2, 0, -1); break; case (int)'d': game.moveBomberguy(2, 3, 1, 0); break; case (int)'a': game.moveBomberguy(2, 1, -1, 0); break; case (int)'z': game.moveBomberguy(2, 0, 0, 1); break; case (int)'s': game.setBomb(2); break; // player 4 input case (int)'i': game.moveBomberguy(3, 2, 0, -1); break; case (int)'l': game.moveBomberguy(3, 3, 1, 0); break; case (int)'j': game.moveBomberguy(3, 1, -1, 0); break; case (int)'m': game.moveBomberguy(3, 0, 0, 1); break; case (int)'k': game.setBomb(3); break; } return super.keyDown(e, key); } public void newGame() { } } class Game { private int height, width; private Bomberguy[] bomberguy; private Sprite[][] tileArray; Game(int height, int width) { this.height = height; this.width = width; this.tileArray = new Sprite[width][height]; for(int i = 1; i <= width - 2; i++) for(int j = 1; j <= height - 2; j++) if ((int)(Math.random() * 3) != 1) this.tileArray[i][j] = new Brick(i, j); //setup bomberguys bomberguy = new Bomberguy[4]; bomberguy[0] = new Bomberguy(1, 1); bomberguy[1] = new Bomberguy(1, height - 2); bomberguy[2] = new Bomberguy(width - 2, 1); bomberguy[3] = new Bomberguy(width - 2, height - 2); //setup spaces for bomberguys tileArray[1][1] = null; tileArray[1][2] = null; tileArray[2][1] = null; tileArray[1][height - 2] = null; tileArray[1][height - 3] = null; tileArray[2][height - 2] = null; tileArray[width - 2][1] = null; tileArray[width - 3][1] = null; tileArray[width - 2][2] = null; tileArray[width - 2][height - 2] = null; tileArray[width - 2][height - 3] = null; tileArray[width - 3][height - 2] = null; } // create the background image and in the tilearray public void createBackground(Graphics g) { // create block array for(int i = 0; i <= width - 1; i++) for(int j = 0; j <= height - 1; j += height - 1) { this.tileArray[i][j] = new Block(i, j); this.tileArray[i][j].draw(g); } for(int j = 0; j <= height - 1; j++) for(int i = 0; i <= width - 1; i += width - 1) { this.tileArray[i][j] = new Block(i, j); this.tileArray[i][j].draw(g); } for(int i = 2; i <= width - 3; i += 2) for(int j = 2; j <= height - 3; j += 2) { this.tileArray[i][j] = new Block(i, j); this.tileArray[i][j].draw(g); } // create floor for(int i = 1; i <= width - 2; i += 1) for(int j = 1; j <= height - 2; j += 2) { g.drawImage(Floor.image[0], i * 28, j * 28, null); } for(int i = 1; i <= width - 2; i += 2) for(int j = 2; j <= height - 3; j += 2) { g.drawImage(Floor.image[0], i * 28, j * 28, null); } } // recieve input public void moveBomberguy(int guyNum, int dir, int XDir, int YDir) { int x = bomberguy[guyNum].GetX() + XDir; int y = bomberguy[guyNum].GetY() + YDir; boolean go = (tileArray[x][y] == null || tileArray[x][y] instanceof Item); bomberguy[guyNum].move(go, dir, XDir, YDir); } public void setBomb(int guyNum) { if (bomberguy[guyNum].stillAlive()) { int x = bomberguy[guyNum].GetX(); int y = bomberguy[guyNum].GetY(); if (tileArray[x][y] == null) { tileArray[x][y] = new Bomb(x, y, bomberguy[guyNum].getSize()); } } } public void update(Graphics g, int i, int j) { if (!(tileArray[i][j] == null || tileArray[i][j] instanceof Block)) { tileArray[i][j].update(); tileArray[i][j].draw(g); if (tileArray[i][j].timeout()) { if (tileArray[i][j] instanceof Bomb) { explode(i, j); } else if (tileArray[i][j].putItem()) { tileArray[i][j] = new fireItem(i, j); } else tileArray[i][j] = null; } } } public void explode(int x, int y) { int size = ((Bomb)(tileArray[x][y])).getSize(); tileArray[x][y] = new BlastC(x, y); // create explosion radius for(int i = 1; i <= size; i++) { if (tileArray[x + i][y] instanceof Block) i = size; else if (tileArray[x + i][y] instanceof Bomb) { explode(x + i, y); i = size; } else if(tileArray[x + i][y] instanceof Brick) { tileArray[x + i][y] = new BlastH(x + i, y, true); i = size; } else if(tileArray[x + i][y] instanceof Blast) { tileArray[x + i][y] = new BlastC(x + i, y); i = size; } else { if (i == size) tileArray[x + i][y] = new BlastLEFT(x + i, y); else tileArray[x + i][y] = new BlastH(x + i, y); } } for(int i = 1; i <= size; i++) { if (tileArray[x][y - i] instanceof Block) i = size; else if (tileArray[x][y - i] instanceof Bomb) { explode(x, y - i); i = size; } else if(tileArray[x][y - i] instanceof Brick) { tileArray[x][y - i] = new BlastV(x, y - i, true); i = size; } else if(tileArray[x][y - i] instanceof Blast) { tileArray[x][y - i] = new BlastC(x, y - i); i = size; } else { if (i == size) tileArray[x][y - i] = new BlastUP(x, y - i); else tileArray[x][y - i] = new BlastV(x, y - i); } } for(int i = 1; i <= size; i++) { if (tileArray[x - i][y] instanceof Block) i = size + 1; else if (tileArray[x - i][y] instanceof Bomb) { explode(x - i, y); i = size; } else if(tileArray[x - i][y] instanceof Brick) { tileArray[x - i][y] = new BlastH(x - i, y, true); i = size; } else if(tileArray[x - i][y] instanceof Blast) { tileArray[x - i][y] = new BlastC(x - i, y); i = size; } else { if (i == size) tileArray[x - i][y] = new BlastRIGHT(x - i, y); else tileArray[x - i][y] = new BlastH(x - i, y); } } for(int i = 1; i <= size; i++) { if (tileArray[x][y + i] instanceof Block) i = size; else if (tileArray[x][y + i] instanceof Bomb) { explode(x, y + i); i = size; } else if(tileArray[x][y + i] instanceof Brick) { tileArray[x][y + i] = new BlastV(x, y + i, true); i = size; } else if(tileArray[x][y + i] instanceof Blast) { tileArray[x][y + i] = new BlastC(x, y + i); i = size; } else { if (i == size) tileArray[x][y + i] = new BlastDOWN(x, y + i); else tileArray[x][y + i] = new BlastV(x, y + i); } } } public void draw(Graphics g) { // complex for statement to only draw non blocks for(int i = 1; i <= width - 2; i += 1) for(int j = 1; j <= height - 2; j += 2) update(g, i, j); for(int i = 1; i <= width - 2; i += 2) for(int j = 2; j <= height - 3; j += 2) update(g, i, j); // draw and update bomberman for(int i = 0; i < 4; i++) { bomberguy[i].update(); bomberguy[i].draw(g); int x = bomberguy[i].GetX(); int y = bomberguy[i].GetY(); if (tileArray[x][y] instanceof Blast) bomberguy[i].kill(); else if (tileArray[x][y] instanceof fireItem) { bomberguy[i].gotFireItem(); tileArray[x][y] = null; } } } } class Sprite { protected static int NOTHING = 0; protected int frame, state; protected Point pos; protected Image image[]; Sprite(int x, int y) { this.pos = new Point(); this.pos.x = x; this.pos.y = y; this.frame = 0; } public int GetX() { return pos.x; } public int GetY() { return pos.y; } public void update() { } public boolean timeout() { return false; } public boolean putItem() { return false; } public void draw(Graphics g) { g.drawImage(image[frame], pos.x * 28, pos.y * 28, null); } } class Bomberguy extends Sprite { private static int GO = 1, DEAD = 2; private static Image[][] bombManPic; private int dir, XDir, YDir, maxBombs, fireSize, xCounter, yCounter, bombsSet; public Bomberguy(int x, int y) { super(x, y); this.dir = 0; this.XDir = 0; this.YDir = 0; this.xCounter = 0; this.yCounter = 0; this.state = NOTHING; this.maxBombs = 1; this.fireSize = 1; this.bombsSet = 0; } public static void initResources(Applet app, MediaTracker tracker, int id) { bombManPic = new Image[4][5]; for(int i = 0; i < 4; i++) { for(int j = 0; j < 4; j++) { bombManPic[i][j] = app.getImage(app.getDocumentBase(), "./res/bman" + i + "_" + j + ".gif"); tracker.addImage(bombManPic[i][j], id); } } for(int i = 0; i < 4; i++) { bombManPic[i][4] = bombManPic[i][2]; } } public void gotFireItem() { if (this.fireSize < 10) fireSize++; } public int getSize() { return this.fireSize; } public int getMaxBombs() { return this.maxBombs; } public boolean stillAlive() { return (this.state != DEAD); } public void kill() { this.state = DEAD; } public void move(boolean space, int dir, int XDir, int YDir) { if (this.state == NOTHING) { this.dir = dir; if (space) { this.XDir = XDir; this.YDir = YDir; this.state = GO; } } } public void update() { if (this.state == GO) { this.xCounter += XDir * 3; this.yCounter += YDir * 3; this.frame++; if (frame >= 5) { this.frame = 1; } if (Math.abs(xCounter) >= 27 || Math.abs(yCounter) >= 27) { this.pos.x += XDir; this.pos.y += YDir; this.frame = 0; this.xCounter = 0; this.yCounter = 0; this.state = NOTHING; } } } public void draw(Graphics g) { if (this.state != DEAD) g.drawImage(bombManPic[dir][frame], pos.x * 28 + xCounter, pos.y * 28 + yCounter, null); } } class Bomb extends Sprite{ private static Image[] image; private int timer, size; public Bomb(int x, int y, int size) { super(x, y); this.timer = 50; this.size = size; } public static void initResources(Applet app, MediaTracker tracker, int id) { image = new Image[4]; for(int i = 0; i < 3; i++) { image[i] = app.getImage(app.getDocumentBase(), "./res/bomb_" + i + ".gif"); tracker.addImage(image[i], id); } image[3] = app.getImage(app.getDocumentBase(), "./res/bomb_1.gif"); tracker.addImage(image[3], id); } public int getSize() { return this.size; } public void update() { timer--; frame++; if (frame >= 4) { frame = 0; } } public boolean timeout() { return (timer <= 0); } public void draw(Graphics g) { g.drawImage(image[frame], pos.x * 28, pos.y * 28, null); } } class Floor extends Sprite { public static Image image[]; Floor(int x, int y) { super(x, y); } public static void initResources(Applet app, MediaTracker tracker, int id) { image = new Image[1]; image[0] = app.getImage(app.getDocumentBase(), "./res/floor.gif"); tracker.addImage(image[0], id); } } class Block extends Sprite { public static Image image[]; Block(int x, int y) { super(x, y); } public static void initResources(Applet app, MediaTracker tracker, int id) { image = new Image[1]; image[0] = app.getImage(app.getDocumentBase(), "./res/block.gif"); tracker.addImage(image[0], id); } public void draw(Graphics g) { g.drawImage(image[frame], pos.x * 28, pos.y * 28, null); } } class Brick extends Sprite { public static Image image[]; Brick(int x, int y) { super(x, y); } public static void initResources(Applet app, MediaTracker tracker, int id) { image = new Image[1]; image[0] = app.getImage(app.getDocumentBase(), "./res/bricks.gif"); tracker.addImage(image[0], id); } public void draw(Graphics g) { g.drawImage(image[frame], pos.x * 28, pos.y * 28, null); } } class Blast extends Sprite { private int timer; private boolean item; Blast(int x, int y) { super(x, y); this.timer = 25; this.item = false; } Blast(int x, int y, boolean item) { super(x, y); this.timer = 25; if ((int)(Math.random() * 3) == 1) this.item = item; } public boolean timeout() { return (timer <= 0); } public boolean putItem() { return item; } public void update() { timer--; frame = 1 - frame; } } class BlastC extends Blast { public static Image image[]; BlastC(int x, int y) { super(x, y); } BlastC(int x, int y, boolean item) { super(x, y, item); } public static void initResources(Applet app, MediaTracker tracker, int id) { image = new Image[2]; for(int i = 0; i < 2; i++) { image[i] = app.getImage(app.getDocumentBase(), "./res/blast_c_" + i + ".gif"); tracker.addImage(image[i], id); } } public void draw(Graphics g) { g.drawImage(image[frame], pos.x * 28, pos.y * 28, null); } } class BlastV extends Blast { public static Image image[]; BlastV(int x, int y) { super(x, y); } BlastV(int x, int y, boolean item) { super(x, y, item); } public static void initResources(Applet app, MediaTracker tracker, int id) { image = new Image[2]; for(int i = 0; i < 2; i++) { image[i] = app.getImage(app.getDocumentBase(), "./res/blast_v_" + i + ".gif"); tracker.addImage(image[i], id); } } public void draw(Graphics g) { g.drawImage(image[frame], pos.x * 28, pos.y * 28, null); } } class BlastH extends Blast { public static Image image[]; BlastH(int x, int y) { super(x, y); } BlastH(int x, int y, boolean item) { super(x, y, item); } public static void initResources(Applet app, MediaTracker tracker, int id) { image = new Image[2]; for(int i = 0; i < 2; i++) { image[i] = app.getImage(app.getDocumentBase(), "./res/blast_h_" + i + ".gif"); tracker.addImage(image[i], id); } } public void draw(Graphics g) { g.drawImage(image[frame], pos.x * 28, pos.y * 28, null); } } class BlastLEFT extends Blast { public static Image image[]; BlastLEFT(int x, int y) { super(x, y); } public static void initResources(Applet app, MediaTracker tracker, int id) { image = new Image[2]; for(int i = 0; i < 2; i++) { image[i] = app.getImage(app.getDocumentBase(), "./res/blast_left_" + i + ".gif"); tracker.addImage(image[i], id); } } public void draw(Graphics g) { g.drawImage(image[frame], pos.x * 28, pos.y * 28, null); } } class BlastUP extends Blast { public static Image image[]; BlastUP(int x, int y) { super(x, y); } public static void initResources(Applet app, MediaTracker tracker, int id) { image = new Image[2]; for(int i = 0; i < 2; i++) { image[i] = app.getImage(app.getDocumentBase(), "./res/blast_up_" + i + ".gif"); tracker.addImage(image[i], id); } } public void draw(Graphics g) { g.drawImage(image[frame], pos.x * 28, pos.y * 28, null); } } class BlastRIGHT extends Blast { public static Image image[]; BlastRIGHT(int x, int y) { super(x, y); } public static void initResources(Applet app, MediaTracker tracker, int id) { image = new Image[2]; for(int i = 0; i < 2; i++) { image[i] = app.getImage(app.getDocumentBase(), "./res/blast_right_" + i + ".gif"); tracker.addImage(image[i], id); } } public void draw(Graphics g) { g.drawImage(image[frame], pos.x * 28, pos.y * 28, null); } } class BlastDOWN extends Blast { public static Image image[]; BlastDOWN(int x, int y) { super(x, y); } public static void initResources(Applet app, MediaTracker tracker, int id) { image = new Image[2]; for(int i = 0; i < 2; i++) { image[i] = app.getImage(app.getDocumentBase(), "./res/blast_down_" + i + ".gif"); tracker.addImage(image[i], id); } } public void draw(Graphics g) { g.drawImage(image[frame], pos.x * 28, pos.y * 28, null); } } class Item extends Sprite { private int timer; Item(int x, int y) { super(x, y); this.timer = 100; } public boolean timeout() { return (timer <= 0); } public void update() { timer--; } } class fireItem extends Item{ public static Image image[]; fireItem(int x, int y) { super(x, y); } public static void initResources(Applet app, MediaTracker tracker, int id) { image = new Image[1]; image[0] = app.getImage(app.getDocumentBase(), "./res/item_fire.gif"); tracker.addImage(image[0], id); } public void draw(Graphics g) { g.drawImage(image[frame], pos.x * 28, pos.y * 28, null); } }