/* * Board - the PipeDream board * * by Adam Doppelt * http://www.cs.brown.edu/people/amd/ */ import java.awt.*; import java.applet.Applet; public class Board extends MirrorCanvas implements Runnable { final static Color BACKGROUND = Color.blue; final static Color LINES = Color.white; final static int SIZE = 8; final static int DIED_DELAY = 2000; final static String PRE_MESSAGE = "Click on the board to start playing."; final static String FILL_UP = "I hear the water swirling..."; final static String PLAYING = "Now, lay pipe for your life!"; final static String PAUSED = "Paused. It better be important."; final static String BETWEEN = "You made it! Click to begin the next level."; final static String GAME_OVER = "Gagging silently, you succumb to the inky depths."; final static String NO_IMAGES = "Could not load images!"; final static int PIXELS = SIZE * (Piece.SIZE + 1) + 1; final static Color MESSAGE_FOREGROUND = Color.white; final static Color MESSAGE_BACKGROUND = Color.black; final static int MESSAGE_HEIGHT = 30; Replace replace_; Thread kicker_; Font font_; Queue queue_; Piece pieces_[][]; Water water_; Piece start_; int startRow_, startCol_; Applet applet_; boolean loaded_, playing_, between_; long waterDied_; public Board(Container container, Applet applet) { super(PIXELS, PIXELS + MESSAGE_HEIGHT); loaded_ = false; playing_ = false; between_ = false; new Score(container); container.add("Center", this); queue_ = new Queue(container); applet_ = applet; font_ = new Font("TimesRoman", Font.PLAIN, 14); loaded_ = true; waterDied_ = 0; } public void paint(Graphics g) { if (offscreen_ == null) { super.paint(g); String base = applet_.getCodeBase().toString(); Slicer slicer = new Slicer( applet_, base + "pipes.gif", 2, 4); Image cells[][] = slicer.GetAllCells(true); if (cells == null) { applet_.showStatus(NO_IMAGES); SetMessage(NO_IMAGES); return; } StartPiece.SetupStatics(this, cells[0][0]); WEPiece.SetupStatics(this, cells[1][0]); NSPiece.SetupStatics(this, cells[2][0]); NSEWPiece.SetupStatics(this, cells[3][0]); NWPiece.SetupStatics(this, cells[0][1]); NEPiece.SetupStatics(this, cells[1][1]); SEPiece.SetupStatics(this, cells[2][1]); SWPiece.SetupStatics(this, cells[3][1]); start(); } else super.paint(g); } public void StartGame() { waterDied_ = 0; Score.Reset(); NextLevel(); } public void NextLevel() { Score.AdvanceLevel(); Clear(); queue_.ResetQueue(); startRow_ = (int)(Math.random() * (SIZE - 4)) + 2; startCol_ = (int)(Math.random() * (SIZE - 5)) + 2; start_ = new StartPiece(); AddPiece(start_, startRow_, startCol_); SetMessage(FILL_UP); Flip(); between_ = false; playing_ = true; replace_ = null; kicker_ = new Thread(this); kicker_.start(); } public void run() { try { Thread.sleep(Score.GetInitialDelay()); } catch (InterruptedException e) { ; } SetMessage(PLAYING); kicker_ = null; water_ = new Water(this, start_, startRow_, startCol_); } public void WaterDied() { waterDied_ = System.currentTimeMillis(); if (replace_ != null) { replace_.stop(); replace_ = null; } water_ = null; if (Score.EnoughForNext()) { between_ = true; SetMessage(BETWEEN); } else { playing_ = false; SetMessage(GAME_OVER); } } public void start() { if (offscreen_ == null) return; Clear(); SetMessage(PRE_MESSAGE); } public void stop() { if (kicker_ != null) { kicker_.stop(); kicker_ = null; } if (replace_ != null) { replace_.stop(); replace_ = null; } if (water_ != null) { water_.stop(); water_ = null; } playing_ = false; } public void SetMessage(String message) { offscreen_.setFont(font_); FontMetrics metrics = getFontMetrics(font_); int x = (int)((size().width - metrics.stringWidth(message)) / 2.0); int y = (int)((MESSAGE_HEIGHT + metrics.getMaxDescent()) / 2.0); offscreen_.setColor(MESSAGE_BACKGROUND); offscreen_.fillRect(0, PIXELS, PIXELS, MESSAGE_HEIGHT); offscreen_.setColor(MESSAGE_FOREGROUND); offscreen_.drawString(message, x, y + PIXELS + 3); repaint(); // onscreen_.drawImage(image_, 0, 0, null); } public void AddPiece(Piece piece, int row, int col) { pieces_[row][col] = piece; piece.StampAt(offscreen_, col * (Piece.SIZE + 1) + 1, row * (Piece.SIZE + 1) + 1); Flip(); } public void ReplaceIt(Piece newPiece, int row, int col) { AddPiece(newPiece, row, col); replace_ = null; } public void AddPiece(int row, int col) { if (replace_ == null) { if (row >= 0 && row < SIZE && col >= 0 && col < SIZE) { if (pieces_[row][col] != null) { if (!pieces_[row][col].ContainsWater()) { Piece newPiece = queue_.GetNextPiece(); pieces_[row][col] = null; replace_ = new Replace(this, offscreen_, onscreen_, newPiece, row, col); } } else { Piece newPiece = queue_.GetNextPiece(); AddPiece(newPiece, row, col); } } } } public Piece PieceAt(int row, int col) { if (row >= 0 && row < SIZE && col >= 0 && col < SIZE) return pieces_[row][col]; else return null; } public void DrawWater(Water water) { water.Draw(offscreen_); water.Draw(onscreen_); } public void Clear() { offscreen_.setColor(BACKGROUND); offscreen_.fillRect(0, 0, PIXELS, PIXELS); offscreen_.setColor(LINES); pieces_ = new Piece[SIZE][SIZE]; for(int loop = 0; loop < SIZE; ++loop) { offscreen_.drawLine(loop * (Piece.SIZE + 1), 0, loop * (Piece.SIZE + 1), PIXELS); offscreen_.drawLine(0, loop * (Piece.SIZE + 1), PIXELS, loop * (Piece.SIZE + 1)); } Flip(); } public boolean handleEvent(Event event) { if (!loaded_) return false; if (event.id == Event.MOUSE_UP) { if (playing_) { if (between_) { if (System.currentTimeMillis() - waterDied_ > DIED_DELAY) NextLevel(); } else { int col = event.x / (Piece.SIZE + 1); int row = event.y / (Piece.SIZE + 1); AddPiece(row, col); } } else if (System.currentTimeMillis() - waterDied_ > DIED_DELAY) StartGame(); return true; } else return false; } }