diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d98981c --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +/target/ +/.classpath +/.project +/.settings/ diff --git a/doc/current/GamePlay.png b/doc/current/GamePlay.png new file mode 100644 index 0000000..0fee0e0 Binary files /dev/null and b/doc/current/GamePlay.png differ diff --git a/doc/original/Bomb.gif b/doc/original/Bomb.gif new file mode 100644 index 0000000..d5abb4c Binary files /dev/null and b/doc/original/Bomb.gif differ diff --git a/doc/original/Exit.gif b/doc/original/Exit.gif new file mode 100644 index 0000000..bb64607 Binary files /dev/null and b/doc/original/Exit.gif differ diff --git a/doc/original/GameScreen.gif b/doc/original/GameScreen.gif new file mode 100644 index 0000000..fe1585f Binary files /dev/null and b/doc/original/GameScreen.gif differ diff --git a/doc/original/HelpScreen.gif b/doc/original/HelpScreen.gif new file mode 100644 index 0000000..324ed36 Binary files /dev/null and b/doc/original/HelpScreen.gif differ diff --git a/doc/original/Mine.gif b/doc/original/Mine.gif new file mode 100644 index 0000000..8b68f5d Binary files /dev/null and b/doc/original/Mine.gif differ diff --git a/doc/original/Mouse.gif b/doc/original/Mouse.gif new file mode 100644 index 0000000..9fbaa65 Binary files /dev/null and b/doc/original/Mouse.gif differ diff --git a/doc/original/MouseMaze.dsk b/doc/original/MouseMaze.dsk new file mode 100644 index 0000000..3d7dbd8 Binary files /dev/null and b/doc/original/MouseMaze.dsk differ diff --git a/doc/original/Robot.gif b/doc/original/Robot.gif new file mode 100644 index 0000000..4d46528 Binary files /dev/null and b/doc/original/Robot.gif differ diff --git a/doc/original/Skull.gif b/doc/original/Skull.gif new file mode 100644 index 0000000..52d2b4c Binary files /dev/null and b/doc/original/Skull.gif differ diff --git a/doc/original/WinningScreen.gif b/doc/original/WinningScreen.gif new file mode 100644 index 0000000..db3a427 Binary files /dev/null and b/doc/original/WinningScreen.gif differ diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..57b2ba7 --- /dev/null +++ b/pom.xml @@ -0,0 +1,46 @@ + + + 4.0.0 + a2geek.games + mouse-maze-2001 + 1.9.0-FINAL + Mouse Maze 2001 + A recreation of a game developed in 1983. + + + 1.8 + 1.8 + 2.4.3 + + + + + + org.apache.maven.plugins + maven-shade-plugin + ${maven.shade.version} + + + package + + shade + + + + + + a2geek.games.mousemaze2001.MouseMaze2001 + Mouse Maze 2001 + ${project.version} + + + + + + + + + + \ No newline at end of file diff --git a/src/main/java/a2geek/games/mousemaze2001/GameSettingsPanel.java b/src/main/java/a2geek/games/mousemaze2001/GameSettingsPanel.java new file mode 100644 index 0000000..776e86e --- /dev/null +++ b/src/main/java/a2geek/games/mousemaze2001/GameSettingsPanel.java @@ -0,0 +1,308 @@ +package a2geek.games.mousemaze2001; +import java.util.*; +import javax.swing.border.*; + +import a2geek.games.mousemaze2001.domain.*; +import a2geek.games.mousemaze2001.images.ImageManager; + +import java.awt.*; +import javax.swing.*; + +import java.awt.event.*; + +/** + * Provides the panel used for game settings. + * + * Creation date: (10/27/01 7:32:59 PM) + * @author: Rob Greene + * @version: RJG 10/29/2001 22:40:54 + */ +public class GameSettingsPanel extends JPanel implements ActionListener { + private static final String HARD = "hard"; + private static final String EASY = "easy"; + private static final String DEFAULT = "default"; + + private JSlider bombsPerLevel; + private JSlider robotRange; + private JSlider robotShotFrequency; + private JSlider robotMineFrequency; + private JCheckBox mouseShoots; + private JCheckBox robotShotDistanceFixed; + private JCheckBox animatedImages; + private JCheckBox unlimitedLevels; + private JCheckBox unlimitedLives; + private JCheckBox shieldedRobots; + + private GameSettings easySettings; + private GameSettings hardSettings; + private GameSettings defaultSettings; + private GameSettings currentSettings; + +/** + * GameSettingsPanel constructor comment. + */ +public GameSettingsPanel() { + super(); + initializeSettings(); + initializeComponents(); + copyFromCurrentSettings(); +} + + +/** + * Handle action events from buttons. + * + * Creation date: (10/27/01 7:45:27 PM) + */ +public void actionPerformed(ActionEvent actionEvent) { + String command = actionEvent.getActionCommand(); + if (command != null) { + if (DEFAULT.equals(command)) { + currentSettings = new GameSettings(defaultSettings); + } else if (EASY.equals(command)) { + currentSettings = new GameSettings(easySettings); + } else if (HARD.equals(command)) { + currentSettings = new GameSettings(hardSettings); + } + copyFromCurrentSettings(); + } +} + + +/** + * Copy the current settings values to the screen components. + * + * Creation date: (10/27/01 11:38:39 PM) + */ +public void copyFromCurrentSettings() { + bombsPerLevel.setMaximum(currentSettings.getMaxBombsPerLevel()); + bombsPerLevel.setValue(currentSettings.getBombsPerLevel()); + robotRange.setMaximum(currentSettings.getMaxRobotShotRange()); + robotRange.setValue(currentSettings.getRobotShotRange()); + robotShotDistanceFixed.setSelected(currentSettings.isFixedRobotShotRange()); + robotShotFrequency.setValue(currentSettings.getRobotShootFrequency()); + robotMineFrequency.setValue(currentSettings.getRobotMineFrequency()); + mouseShoots.setSelected(currentSettings.isShootingMouse()); + animatedImages.setSelected(currentSettings.isAnimatedImages()); + unlimitedLevels.setSelected(currentSettings.isUnlimitedGameLevels()); + unlimitedLives.setSelected(currentSettings.isUnlimitedLives()); + shieldedRobots.setSelected(currentSettings.isShieldedRobots()); + repaint(); +} + + +/** + * Copy the current settings values from the screen components. + * + * Creation date: (10/27/01 11:38:39 PM) + */ +public void copyToCurrentSettings() { + currentSettings.setBombsPerLevel(bombsPerLevel.getValue()); + currentSettings.setRobotShotRange(robotRange.getValue()); + currentSettings.setFixedRobotShotRange(robotShotDistanceFixed.isSelected()); + currentSettings.setRobotShootFrequency(robotShotFrequency.getValue()); + currentSettings.setRobotMineFrequency(robotMineFrequency.getValue()); + currentSettings.setShootingMouse(mouseShoots.isSelected()); + currentSettings.setAnimatedImages(animatedImages.isSelected()); + currentSettings.setUnlimitedGameLevels(unlimitedLevels.isSelected()); + currentSettings.setUnlimitedLives(unlimitedLives.isSelected()); + currentSettings.setShieldedRobots(shieldedRobots.isSelected()); +} + + +/** + * Create a bordered panel. + * + * Creation date: (10/27/01 8:35:30 PM) + */ +protected JPanel createBorderedPanel(String title) { + return createBorderedPanel(title, BoxLayout.Y_AXIS); +} + + +/** + * Create a bordered panel. + * + * Creation date: (10/27/01 8:35:30 PM) + */ +protected JPanel createBorderedPanel(String title, int axis) { + JPanel thePanel = new JPanel(); + thePanel.setLayout(new BoxLayout(thePanel, axis)); + TitledBorder titledBorder = new TitledBorder(title); + titledBorder.setTitleColor(Color.black); + thePanel.setBorder(titledBorder); + return thePanel; +} + + +/** + * Create a standard image button. + * + * Creation date: (10/27/01 3:05:07 PM) + */ +protected JButton createImageButton(String resourceName, String commandString) { + return createImageButton(resourceName, commandString, this); +} + + +/** + * Create a standard image button. + * + * Creation date: (10/27/01 3:05:07 PM) + */ +protected JButton createImageButton(String resourceName, String commandString, ActionListener actionListener) { + JButton button = new JButton(new ImageIcon(ImageManager.getInstance().getImage(resourceName))); + button.setActionCommand(commandString); + button.addActionListener(actionListener); + return button; +} + + +/** + * Create a slider panel. + * + * Creation date: (10/27/01 8:38:48 PM) + */ +protected JSlider createSlider(int minimumValue, int maximumValue, int currentValue) { + JSlider theSlider = new JSlider(minimumValue, maximumValue, currentValue); + if (maximumValue >= 100) { + theSlider.setMinorTickSpacing(1); + theSlider.setMajorTickSpacing(10); + } else { + theSlider.setMajorTickSpacing(1); + } + theSlider.setPaintTicks(true); + theSlider.setPaintLabels(true); + theSlider.setSnapToTicks(true); + theSlider.setForeground(Color.black); + // change the foreground color of all labels (numbers) + Dictionary table = theSlider.getLabelTable(); + Enumeration e = table.elements(); + while (e.hasMoreElements()) { + JLabel label = (JLabel) e.nextElement(); + label.setForeground(Color.black); + } + + return theSlider; +} + + +/** + * Retrieve the current game settings. + * + * Creation date: (10/28/01 1:23:58 PM) + */ +public GameSettings getCurrentSettings() { + copyToCurrentSettings(); + return currentSettings; +} + + +/** + * Initialize the graphical components. + * + * Creation date: (10/27/01 11:18:17 PM) + */ +protected void initializeComponents() { + GameSettings curs = currentSettings; + JPanel everything = new JPanel(); + BoxLayout boxLayout = new BoxLayout(everything, BoxLayout.Y_AXIS); + everything.setLayout(boxLayout); + + JPanel bombsPanel = createBorderedPanel("Bombs per level"); + bombsPerLevel = createSlider(0,curs.getMaxBombsPerLevel(),curs.getBombsPerLevel()); + bombsPanel.add(bombsPerLevel); + + JPanel rangePanel = createBorderedPanel("Range of robot shooting"); + robotRange = createSlider(1,curs.getMaxRobotShotRange(),curs.getRobotShotRange()); + robotShotDistanceFixed = new JCheckBox("Robots can only shoot the maximum distance (specified above)"); + robotShotDistanceFixed.setSelected(curs.isFixedRobotShotRange()); + robotShotDistanceFixed.setHorizontalAlignment(JCheckBox.LEFT); + rangePanel.add(robotRange); + rangePanel.add(robotShotDistanceFixed); + + JPanel freqPanel = createBorderedPanel("Robot shooting frequency (%)"); + robotShotFrequency = createSlider(0,100,curs.getRobotShootFrequency()); + freqPanel.add(robotShotFrequency); + + JPanel minePanel = createBorderedPanel("Robot mine dropping frequency (%)"); + robotMineFrequency = createSlider(0,100,curs.getRobotMineFrequency()); + minePanel.add(robotMineFrequency); + + JPanel settingsPanel = createBorderedPanel("Other settings"); + mouseShoots = new JCheckBox("Honestly, mice can shoot. Really!"); + mouseShoots.setSelected(curs.isShootingMouse()); + animatedImages = new JCheckBox("Animated images"); + animatedImages.setSelected(curs.isAnimatedImages()); + unlimitedLevels = new JCheckBox("Unlimited levels"); + unlimitedLevels.setSelected(curs.isUnlimitedGameLevels()); + unlimitedLives = new JCheckBox("Unlimited lives"); + unlimitedLives.setSelected(curs.isUnlimitedLives()); + shieldedRobots = new JCheckBox("Are robots shielded?"); + shieldedRobots.setSelected(curs.isShieldedRobots()); + settingsPanel.add(mouseShoots); + settingsPanel.add(shieldedRobots); + settingsPanel.add(animatedImages); + settingsPanel.add(unlimitedLevels); + settingsPanel.add(unlimitedLives); + + JPanel predefinedPanel = createBorderedPanel("Predefined game settings"); + predefinedPanel.setLayout(new GridLayout(3,1)); + JButton easyButton = createImageButton("EasyButton.gif", EASY); + JButton defaultButton = createImageButton("DefaultButton.gif", DEFAULT); + JButton hardButton = createImageButton("HardButton.gif", HARD); + predefinedPanel.add(easyButton); + predefinedPanel.add(defaultButton); + predefinedPanel.add(hardButton); + + JPanel comboPanel = new JPanel(new GridLayout(1,2)); + comboPanel.add(predefinedPanel); + comboPanel.add(settingsPanel); + + everything.add(bombsPanel); + everything.add(rangePanel); + everything.add(freqPanel); + everything.add(minePanel); + everything.add(comboPanel); + + // apparantly these need to be separate panels... + JPanel dividerPanel = new JPanel(); + JPanel dividerPanel2 = new JPanel(); + JPanel dividerPanel3 = new JPanel(); + JPanel dividerPanel4 = new JPanel(); + + this.setLayout(new BorderLayout()); + this.add(dividerPanel, BorderLayout.WEST); + this.add(dividerPanel2, BorderLayout.EAST); + this.add(dividerPanel3, BorderLayout.SOUTH); + this.add(dividerPanel4, BorderLayout.NORTH); + this.add(everything, BorderLayout.CENTER); +} + + +/** + * Initialize the predefined Settings. + * + * Creation date: (10/27/01 11:20:00 PM) + */ +protected void initializeSettings() { + currentSettings = new GameSettings(MazeDomain.getInstance().getGameSettings()); + easySettings = new GameSettings(); + easySettings.load("easy.properties"); + hardSettings = new GameSettings(); + hardSettings.load("hard.properties"); + defaultSettings = new GameSettings(); + defaultSettings.load("default.properties"); +} + + +/** + * Set the current game settings. + * + * Creation date: (10/28/01 1:23:14 PM) + */ +public void setCurrentSettings(GameSettings gameSettings) { + currentSettings = new GameSettings(gameSettings); + copyFromCurrentSettings(); +} +} \ No newline at end of file diff --git a/src/main/java/a2geek/games/mousemaze2001/IntroPanel.java b/src/main/java/a2geek/games/mousemaze2001/IntroPanel.java new file mode 100644 index 0000000..cc9fa17 --- /dev/null +++ b/src/main/java/a2geek/games/mousemaze2001/IntroPanel.java @@ -0,0 +1,325 @@ +package a2geek.games.mousemaze2001; +import java.io.*; +import java.awt.image.*; +import java.net.*; +import java.awt.*; +import javax.swing.*; + +import a2geek.games.mousemaze2001.images.*; + +/** + * Insert the type's description here. + * + * Creation date: (10/16/01 10:28:58 PM) + * @author: Rob Greene + * @version: RJG 10/31/2001 22:12:32 + */ +public class IntroPanel extends JPanel { + private static IntroPanel instance = new IntroPanel(); + private String[] imageNames = { + "OriginalMouseMazeLogo.gif", + "OriginalMouseMazeHelp.gif", + "OriginalMouseMazeGameShot.gif", + "OriginalMouseMazeWin.gif" + }; + private Image[] scaledImages; + private int ticker; + private int stage; + private String[] story = { + "A long time ago,", + "when life was much different,", + "I wrote my first game called...", + "", + "&1", + "", + "", + "This a rewrite.", + "", + "", + "The Apple ][,", + "simple graphics,", + "small computers,", + "All Gone!", + "", + "", + "The original help screen:", + "&2", + "", + "A game in progress:", + "&3", + "", + "The winners' screen:", + "&4" + }; + private Image marquee; + private Thread creationThread; + +/** + * IntroPanel constructor comment. + */ +protected IntroPanel() { + super(); + initialize(); +} + + +public static IntroPanel getInstance() { + return instance; +} + + +protected int getMaxStage() { + return 2; +} + + +public void incrementTicker() { + ticker++; +} + + +private void initialize() { + setMinimumSize(new Dimension(560,384)); + setMaximumSize(new Dimension(560*2,384*2)); + setPreferredSize(new Dimension(560,384)); + + // load original images + Image originalImages[] = new Image[imageNames.length]; + ImageManager imageManager = ImageManager.getInstance(); + for (int i=0; i 0) { + scaled = scaled.getScaledInstance(width, -1, Image.SCALE_FAST); + } + tracker.addImage(scaled, i); + scaledImages[i] = scaled; + } + try { + tracker.waitForAll(); + } catch (InterruptedException ex) { + } +} + + +/** + * This method will layout the marquee on the given grapics context - which can be + * the screen as well as an off-screen image. + * + * Creation date: (10/19/01 11:16:17 PM) + */ +protected int layoutMarquee(Image layoutImage) { + Graphics g = layoutImage.getGraphics(); + Font font = new Font(g.getFont().getFontName(), Font.BOLD, 20); + g.setFont(font); + FontMetrics metrics = g.getFontMetrics(); + int fontHeight = metrics.getHeight(); + int lines = story.length; + + int screenHeight = layoutImage.getHeight(null); + int screenWidth = layoutImage.getWidth(null); + g.setColor(Color.black); + g.fillRect(0,0,screenWidth,screenHeight); + + int y = fontHeight + 10; // just a buffer + for (int i=0; i= 0 && shape < scaledImages.length) { + Image image = scaledImages[shape]; + int shapeWidth = image.getWidth(null); + int shapeHeight = image.getHeight(null); + int x = (screenWidth - shapeWidth) / 2; + int yPos = y - fontHeight+10; + g.setColor(Color.blue); + g.fillRoundRect(x-5,yPos-5,shapeWidth+10,shapeHeight+10,5,5); + g.drawImage(image,x,yPos,null); + y+= shapeHeight+10; + } + } else { + int stringWidth = metrics.stringWidth(line); + int x = (screenWidth - stringWidth) / 2; + g.setColor(Color.lightGray); + g.drawString(line, x, y); + y+= fontHeight; + } + } + return y + 10; +} + + +private void nextStage() { + stage++; + if (stage >= getMaxStage()) { + stage = 0; + } + resetTicker(); +} + + +public void paint(Graphics g) { + Font oldFont = g.getFont(); + + int screenHeight = getHeight(); + int screenWidth = getWidth(); + g.setColor(Color.black); + g.fillRect(0,0,screenWidth,screenHeight); + + switch (stage) { + case 0: paintMarquee(g); + break; + case 1: paintSectionTwo(g); + break; + } + + g.setFont(oldFont); // not sure if this needs to be done.. +} + + +/** + * Paint the scrolling marquee. + * The marquee image creation is placed here since the initialize method apparantly + * cannot create a Graphics object from an Image; thus the marquee cannot be rendered + * from the constructor. The marquee image itself is laid out twice - once to get the + * height (allows it to remain somewhat dynamic) and then to generate the real image. + * The rest of the logic here is just to draw the image on the physical screen. + * + * Creation date: (10/19/01 11:13:58 PM) + */ +public void paintMarquee(Graphics g) { + if (marquee == null) { + if (creationThread == null) { + creationThread = new Thread() { + public void run() { + int width = 500; + int height = 800; + Image layoutImage = createImage(width,height); + height = layoutMarquee(layoutImage); + Image marqueeTemp = createImage(width, height); + layoutMarquee(marqueeTemp); + marquee = marqueeTemp; + resetTicker(); + }; + }; + creationThread.setDaemon(true); + creationThread.start(); + } + } + + int screenHeight = getHeight(); + int screenWidth = getWidth(); + if (marquee == null) { + String message = "Please wait..."; + Font font = new Font(g.getFont().getFontName(), Font.BOLD, 20); + g.setFont(font); + FontMetrics metrics = g.getFontMetrics(); + int fontHeight = metrics.getHeight(); + int stringWidth = metrics.stringWidth(message); + int x = (screenWidth - stringWidth) / 2; + int y = (screenHeight - fontHeight) / 2; + g.setColor(Color.green); + g.drawString(message, x, y); + } else { + int y = screenHeight - ticker;; + int shapeWidth = marquee.getWidth(null); + int shapeHeight = marquee.getHeight(null); + int x = (screenWidth - shapeWidth) / 2; + g.drawImage(marquee,x,y,null); + y+= shapeHeight; + if (y < 0) { + nextStage(); + } + } +} + + +public void paintSectionTwo(Graphics g) { + Font font = new Font(g.getFont().getFontName(), Font.BOLD, 20); + g.setFont(font); + g.setColor(Color.blue); + FontMetrics metrics = g.getFontMetrics(); + int fontHeight = metrics.getHeight(); + int fontAscent = metrics.getAscent(); + int screenHeight = getHeight(); + int screenWidth = getWidth(); + int y = (screenHeight - fontHeight*8) / 2; + + String title = "Controlling Mouse Maze"; + int stringWidth = metrics.stringWidth(title); + g.drawString(title, (screenWidth - stringWidth) / 2, y); + + int saveY = y; + int x; + String[] keys; + for (int z=0; z<2; z++) { + if (z == 0) { + y = saveY; + x = (screenWidth / 4); + title = "To Shoot:"; + keys = new String[] { "Q", "W", "E", "A", null, "D", "Z", "X", "C" }; + } else { + y = saveY; + x= (screenWidth / 2); + title = "To Move:"; + keys = new String[] { "Home", "Up", "PgUp", "Left", null, "Right", "End", "Down", "PgDn" }; + } + g.setColor(Color.blue); + y+= fontHeight * 2; + g.drawString(title, x, y); + y+= fontHeight; + int maxWidth = 0; + for (int i=0; i maxWidth) maxWidth = width; + } + } + int padding = 6; + for (int i=0; i 1000) { + nextStage(); + } +} + + +public void resetTicker() { + ticker= 0; +} +} \ No newline at end of file diff --git a/src/main/java/a2geek/games/mousemaze2001/MazeGridPanel.java b/src/main/java/a2geek/games/mousemaze2001/MazeGridPanel.java new file mode 100644 index 0000000..7c36171 --- /dev/null +++ b/src/main/java/a2geek/games/mousemaze2001/MazeGridPanel.java @@ -0,0 +1,138 @@ +package a2geek.games.mousemaze2001; +import java.awt.*; +import javax.swing.*; + +import a2geek.games.mousemaze2001.domain.*; +import a2geek.games.mousemaze2001.mazeobjects.*; + +/** + * Insert the type's description here. + * + * Creation date: (10/11/01 10:13:35 PM) + * @author: Rob Greene + * @version: RJG 10/31/2001 22:12:32 + */ +public class MazeGridPanel extends JPanel { + private int gridWidth = 14; + private int gridHeight = 9; + // the following keep an aspect ratio of 1.33333:1 for w:h + private int minCellHeight = 16; + private int minCellWidth = 15; + private int prefCellWidth = 32; + private int prefCellHeight = 30; + private int maxCellWidth = 64; + private int maxCellHeight = 60; + +/** + * MazeGridPanel constructor comment. + */ +public MazeGridPanel() { + super(); + initialize(); +} + + +/** + * MazeGridPanel constructor comment. + * @param layout java.awt.LayoutManager + */ +public MazeGridPanel(java.awt.LayoutManager layout) { + super(layout); + initialize(); +} + + +/** + * MazeGridPanel constructor comment. + * @param layout java.awt.LayoutManager + * @param isDoubleBuffered boolean + */ +public MazeGridPanel(java.awt.LayoutManager layout, boolean isDoubleBuffered) { + super(layout, isDoubleBuffered); + initialize(); +} + + +/** + * MazeGridPanel constructor comment. + * @param isDoubleBuffered boolean + */ +public MazeGridPanel(boolean isDoubleBuffered) { + super(isDoubleBuffered); + initialize(); +} + + +protected void initialize() { + setMinimumSize(new Dimension(gridWidth * minCellWidth, gridHeight * minCellHeight)); + setMaximumSize(new Dimension(gridWidth * maxCellWidth, gridHeight * maxCellHeight)); + setPreferredSize(new Dimension(gridWidth * prefCellWidth, gridHeight * prefCellHeight)); +} + + +public void paint(Graphics g) { + //System.out.println(new java.util.Date() + " - painting screen"); + int screenWidth = getWidth(); + int screenHeight = getHeight(); + g.setColor(Color.black); + g.fillRect(0, 0, screenWidth, screenHeight); + g.setColor(Color.white); + screenWidth -= 2; + screenHeight -= 2; + for (int x=0; x <= gridWidth; x++) { + int xPos = (screenWidth * x) / gridWidth; + g.drawLine(xPos, 0, xPos, screenHeight); + xPos++; + g.drawLine(xPos, 0, xPos, screenHeight); + } + for (int y=0; y <= gridHeight; y++) { + int yPos = (screenHeight * y) / gridHeight; + g.drawLine(0, yPos, screenWidth, yPos); + yPos++; + g.drawLine(0, yPos, screenWidth, yPos); + } + + MazeDomain maze = MazeDomain.getInstance(); + if (maze.getMap() == null) return; + + int cellWidth = screenWidth / gridWidth - 2; + int cellHeight = screenHeight / gridHeight - 2; + for (int x=0; x + * Creation date: (10/6/01 11:29:16 PM) + * @author: Rob Greene + * @version: RJG 10/08/2001 00:10:56 + */ +public class WindowCloseAdapter extends WindowAdapter implements ActionListener { + /** + * WindowCloseAdapter constructor comment. + */ + public WindowCloseAdapter() { + super(); + } + + /** + * Perform the close action. + * + * Creation date: (10/6/01 11:32:38 PM) + */ + public void actionPerformed(ActionEvent e) { + System.exit(0); + } + + /** + * Close the system down. + * + * Creation date: (10/6/01 11:29:36 PM) + */ + public void windowClosed(WindowEvent e) { + System.exit(0); + } +} \ No newline at end of file diff --git a/src/main/java/a2geek/games/mousemaze2001/domain/DomainEvent.java b/src/main/java/a2geek/games/mousemaze2001/domain/DomainEvent.java new file mode 100644 index 0000000..5fe83ef --- /dev/null +++ b/src/main/java/a2geek/games/mousemaze2001/domain/DomainEvent.java @@ -0,0 +1,41 @@ +package a2geek.games.mousemaze2001.domain; +/** + * A DomainEvent is passed to DomainListeners. + * + * Creation date: (10/22/01 9:58:14 PM) + * @author: Rob Greene + * @version: RJG 10/22/2001 23:31:31 + */ +public class DomainEvent { + private Object source; + private String event; + +/** + * DomainEvent constructor comment. + */ +public DomainEvent(Object theSource, String theEvent) { + super(); + source = theSource; + event = theEvent; +} + + +/** + * Retrieve the event that occurred. + * + * Creation date: (10/22/01 10:00:08 PM) + */ +public String getEvent() { + return event; +} + + +/** + * Retrieve the source of this DomainEvent. + * + * Creation date: (10/22/01 9:59:45 PM) + */ +public Object getSource() { + return source; +} +} \ No newline at end of file diff --git a/src/main/java/a2geek/games/mousemaze2001/domain/DomainListener.java b/src/main/java/a2geek/games/mousemaze2001/domain/DomainListener.java new file mode 100644 index 0000000..d799010 --- /dev/null +++ b/src/main/java/a2geek/games/mousemaze2001/domain/DomainListener.java @@ -0,0 +1,18 @@ +package a2geek.games.mousemaze2001.domain; +/** + * A DomainListener identifies an object that wants to know that + * something has happened in the domain. + * + * Creation date: (10/22/01 9:55:37 PM) + * @author: Rob Greene + * @version: RJG 10/22/2001 23:31:31 + */ +public interface DomainListener { +/** + * A DomainListener will receive a domainChanged event + * when the domain state has been modified. + * + * Creation date: (10/22/01 9:56:33 PM) + */ +public void domainChanged(DomainEvent domainEvent); +} \ No newline at end of file diff --git a/src/main/java/a2geek/games/mousemaze2001/domain/GameSettings.java b/src/main/java/a2geek/games/mousemaze2001/domain/GameSettings.java new file mode 100644 index 0000000..1283d0d --- /dev/null +++ b/src/main/java/a2geek/games/mousemaze2001/domain/GameSettings.java @@ -0,0 +1,439 @@ +package a2geek.games.mousemaze2001.domain; +import java.io.*; +import java.util.*; +/** + * Represents all the configurable information of the game. + * + * Creation date: (10/27/01 2:39:27 PM) + * @author: Rob Greene + * @version: RJG 10/29/2001 22:40:54 + */ +public class GameSettings { + private static final String BASE_PATH = "/settings/%s"; + /* + * Indicates if the mouse is able to shoot. + */ + private boolean shootingMouse; + /* + * Number of bombs added per level. Set to 0 for none. + */ + private int bombsPerLevel; + /* + * Maximum number of bombs to have per level. + * Note: Not used by game itself, used by preferences screen. + */ + private int maxBombsPerLevel; + /* + * Range that robots can "see" or target the mouse. When the mouse + * is within this range, the robot may shoot. + */ + private int robotVisibilityRange; + /* + * Maximum robot visibility range. + * Note: Not used by game itself, used by preferences screen. + */ + private int maxRobotVisibilityRange; + /* + * Longest shot that a robot can take. + */ + private int robotShotRange; + /* + * Maximum shot range that can be chosen. + * Note: Not used by game itself, used by preferences screen. + */ + private int maxRobotShotRange; + /* + * Can robots only shoot at their maximum range? + * (For example, maybe the mouse gets "too close" and under the gun.) + */ + private boolean fixedRobotShotRange; + /* + * When the mouse is within shooting range, this is the percent chance that + * the robot will actually shoot. + */ + private int robotShootFrequency; + /* + * Should the game use animated images, or does that annoy the player? + */ + private boolean animatedImages; + /* + * How frequently should the robot drop mines? + */ + private int robotMineFrequency; + /* + * Cheat: Game is too short, lets make it go on forever! + */ + private boolean unlimitedGameLevels; + /* + * Cheat: Game is too hard, mouse is always reincarnated. + */ + private boolean unlimitedLives; + /* + * Allow robots have shielding. + */ + private boolean shieldedRobots; + +/** + * GameSettings constructor comment. + */ +public GameSettings() { + super(); +} + + +/** + * GameSettings constructor comment. + */ +public GameSettings(GameSettings other) { + super(); + this.setAnimatedImages(other.isAnimatedImages()); + this.setBombsPerLevel(other.getBombsPerLevel()); + this.setFixedRobotShotRange(other.isFixedRobotShotRange()); + this.setMaxBombsPerLevel(other.getMaxBombsPerLevel()); + this.setMaxRobotShotRange(other.getMaxRobotShotRange()); + this.setMaxRobotVisibilityRange(other.getMaxRobotVisibilityRange()); + this.setRobotMineFrequency(other.getRobotMineFrequency()); + this.setRobotShootFrequency(other.getRobotShootFrequency()); + this.setRobotShotRange(other.getRobotShotRange()); + this.setRobotVisibilityRange(other.getRobotVisibilityRange()); + this.setShootingMouse(other.isShootingMouse()); + this.setUnlimitedGameLevels(other.isUnlimitedGameLevels()); + this.setUnlimitedLives(other.isUnlimitedLives()); + this.setShieldedRobots(other.isShieldedRobots()); +} + + +/** + * Retrieve the number of bombs per level. + * + * Creation date: (10/27/01 2:51:10 PM) + * @return int + */ +public int getBombsPerLevel() { + return bombsPerLevel; +} + + +/** + * Get the maximum bombs per level. + * + * Creation date: (10/27/01 2:51:10 PM) + * @return int + */ +public int getMaxBombsPerLevel() { + return maxBombsPerLevel; +} + + +/** + * Get the maximum robot shot range. + * + * Creation date: (10/27/01 2:51:10 PM) + * @return int + */ +public int getMaxRobotShotRange() { + return maxRobotShotRange; +} + + +/** + * Get the maximum robot visibility range. + * + * Creation date: (10/27/01 2:51:10 PM) + * @return int + */ +public int getMaxRobotVisibilityRange() { + return maxRobotVisibilityRange; +} + + +/** + * Get the robot mining frequency. + * + * Creation date: (10/27/01 2:51:10 PM) + * @return int + */ +public int getRobotMineFrequency() { + return robotMineFrequency; +} + + +/** + * Get the robot shooting frequency. + * + * Creation date: (10/27/01 2:51:10 PM) + * @return int + */ +public int getRobotShootFrequency() { + return robotShootFrequency; +} + + +/** + * Get the range of a robot shot. + * + * Creation date: (10/27/01 2:51:10 PM) + * @return int + */ +public int getRobotShotRange() { + return robotShotRange; +} + + +/** + * Get the range a robot can see. + * + * Creation date: (10/27/01 2:51:10 PM) + * @return int + */ +public int getRobotVisibilityRange() { + return robotVisibilityRange; +} + + +/** + * Are there animated images? + * + * Creation date: (10/27/01 2:51:10 PM) + * @return boolean + */ +public boolean isAnimatedImages() { + return animatedImages; +} + + +/** + * Do the robots have a fixed shot range? + * + * Creation date: (10/27/01 2:51:10 PM) + * @return boolean + */ +public boolean isFixedRobotShotRange() { + return fixedRobotShotRange; +} + + +/** + * Answer if the robots have shielding. + * + * Creation date: (10/29/01 10:05:30 PM) + */ +public boolean isShieldedRobots() { + return shieldedRobots; +} + + +/** + * Can this mouse shoot? + * + * Creation date: (10/27/01 2:51:10 PM) + * @return boolean + */ +public boolean isShootingMouse() { + return shootingMouse; +} + + +/** + * Are we too good for the game? + * + * Creation date: (10/27/01 2:51:10 PM) + * @return boolean + */ +public boolean isUnlimitedGameLevels() { + return unlimitedGameLevels; +} + + +/** + * Are we cheating? + * + * Creation date: (10/27/01 2:51:10 PM) + * @return boolean + */ +public boolean isUnlimitedLives() { + return unlimitedLives; +} + + +/** + * Load the game settings from a Properties file. + * + * Creation date: (10/27/01 11:21:59 PM) + */ +public void load(String filename) { + Properties props = new Properties(); + try { + props.load(getClass().getResourceAsStream(String.format(BASE_PATH,filename))); + } catch (IOException ex) { + // ignore - default settings are set + } + setAnimatedImages(new Boolean(props.getProperty("animatedImages","true")).booleanValue()); + setBombsPerLevel(Integer.parseInt(props.getProperty("bombsPerLevel","2"))); + setFixedRobotShotRange(new Boolean(props.getProperty("fixedRobotShotRange","true")).booleanValue()); + setMaxBombsPerLevel(Integer.parseInt(props.getProperty("maxBombsPerLevel","5"))); + setMaxRobotShotRange(Integer.parseInt(props.getProperty("maxRobotShotRange","4"))); + setMaxRobotVisibilityRange(Integer.parseInt(props.getProperty("maxRobotVisibilityRange","5"))); + setRobotMineFrequency(Integer.parseInt(props.getProperty("robotMineFrequency","20"))); + setRobotShootFrequency(Integer.parseInt(props.getProperty("robotShootFrequency","80"))); + setRobotShotRange(Integer.parseInt(props.getProperty("robotShotRange","2"))); + setRobotVisibilityRange(Integer.parseInt(props.getProperty("robotVisibilityRange","4"))); + setShootingMouse(new Boolean(props.getProperty("shootingMouse","true")).booleanValue()); + setUnlimitedGameLevels(new Boolean(props.getProperty("unlimitedGameLevels","false")).booleanValue()); + setUnlimitedLives(new Boolean(props.getProperty("unlimitedLives","false")).booleanValue()); + setShieldedRobots(new Boolean(props.getProperty("shieldedRobots","false")).booleanValue()); +} + + +/** + * Set the animated images flag. + * + * Creation date: (10/27/01 2:51:10 PM) + * @param newAnimatedImages boolean + */ +public void setAnimatedImages(boolean newAnimatedImages) { + animatedImages = newAnimatedImages; +} + + +/** + * Set the number of bombs per level. + * + * Creation date: (10/27/01 2:51:10 PM) + * @param newBombsPerLevel int + */ +public void setBombsPerLevel(int newBombsPerLevel) { + bombsPerLevel = newBombsPerLevel; +} + + +/** + * Set the fixed range of the robots. + * + * Creation date: (10/27/01 2:51:10 PM) + * @param newFixedRobotShotRange boolean + */ +public void setFixedRobotShotRange(boolean newFixedRobotShotRange) { + fixedRobotShotRange = newFixedRobotShotRange; +} + + +/** + * Set the maximum bombs allowed per level. + * + * Creation date: (10/27/01 2:51:10 PM) + * @param newMaxBombsPerLevel int + */ +public void setMaxBombsPerLevel(int newMaxBombsPerLevel) { + maxBombsPerLevel = newMaxBombsPerLevel; +} + + +/** + * Set the maximum robot shot range. + * + * Creation date: (10/27/01 2:51:10 PM) + * @param newMaxRobotShotRange int + */ +public void setMaxRobotShotRange(int newMaxRobotShotRange) { + maxRobotShotRange = newMaxRobotShotRange; +} + + +/** + * Set the maximum robot visibility range. + * + * Creation date: (10/27/01 2:51:10 PM) + * @param newMaxRobotVisibilityRange int + */ +public void setMaxRobotVisibilityRange(int newMaxRobotVisibilityRange) { + maxRobotVisibilityRange = newMaxRobotVisibilityRange; +} + + +/** + * Set the robot mining frequency. + * + * Creation date: (10/27/01 2:51:10 PM) + * @param newRobotMineFrequency int + */ +public void setRobotMineFrequency(int newRobotMineFrequency) { + robotMineFrequency = newRobotMineFrequency; +} + + +/** + * Set the robot shooting frequency. + * + * Creation date: (10/27/01 2:51:10 PM) + * @param newRobotShootFrequency int + */ +public void setRobotShootFrequency(int newRobotShootFrequency) { + robotShootFrequency = newRobotShootFrequency; +} + + +/** + * Set the robot shooting distance. + * + * Creation date: (10/27/01 2:51:10 PM) + * @param newRobotShotRange int + */ +public void setRobotShotRange(int newRobotShotRange) { + robotShotRange = newRobotShotRange; +} + + +/** + * Set the robot visibility range. + * + * Creation date: (10/27/01 2:51:10 PM) + * @param newRobotVisibilityRange int + */ +public void setRobotVisibilityRange(int newRobotVisibilityRange) { + robotVisibilityRange = newRobotVisibilityRange; +} + + +/** + * Set if the robots have shielding. + * + * Creation date: (10/29/01 10:05:57 PM) + */ +public void setShieldedRobots(boolean newShieldedRobots) { + shieldedRobots = newShieldedRobots; +} + + +/** + * Tell me if this mouse is Rambo. + * + * Creation date: (10/27/01 2:51:10 PM) + * @param newShootingMouse boolean + */ +public void setShootingMouse(boolean newShootingMouse) { + shootingMouse = newShootingMouse; +} + + +/** + * Way cool game, but way too easy. + * + * Creation date: (10/27/01 2:51:10 PM) + * @param newUnlimitedGameLevels boolean + */ +public void setUnlimitedGameLevels(boolean newUnlimitedGameLevels) { + unlimitedGameLevels = newUnlimitedGameLevels; +} + + +/** + * Way cool game, but way too hard. + * + * Creation date: (10/27/01 2:51:10 PM) + * @param newUnlimitedLives boolean + */ +public void setUnlimitedLives(boolean newUnlimitedLives) { + unlimitedLives = newUnlimitedLives; +} +} \ No newline at end of file diff --git a/src/main/java/a2geek/games/mousemaze2001/domain/MazeDomain.java b/src/main/java/a2geek/games/mousemaze2001/domain/MazeDomain.java new file mode 100644 index 0000000..545a967 --- /dev/null +++ b/src/main/java/a2geek/games/mousemaze2001/domain/MazeDomain.java @@ -0,0 +1,735 @@ +package a2geek.games.mousemaze2001.domain; +import java.applet.Applet; +import java.applet.AudioClip; +import java.awt.*; +import java.util.*; +import javax.swing.event.ChangeListener; + +import a2geek.games.mousemaze2001.mazeobjects.*; +import a2geek.games.mousemaze2001.threads.*; + +/** + * Contain the MouseMaze domain in a singleton instance. + * Basically, all map related items are here. + * + * Creation date: (10/14/01 9:35:03 PM) + * @author: Rob Greene + * @version: RJG 11/29/2001 22:42:21 + */ +public class MazeDomain { + private static final String BASE_PATH = "/sounds/%s"; + private static MazeDomain instance = null; + private MazeObject[][] map = null; + private int mapWidth = 14; + private int mapHeight = 9; + private int mapLevel = 1; + private int totalMice = 3; + private int lives; + private int kills; + private Point mousePoint = new Point(); + private Point exitPoint = new Point(); + private Vector robots = new Vector(); + private MazeObject mouse = new AnimatedMouse(); + private MazeObject bomb = new AnimatedBomb(); + private MazeObject exit = new Exit(); + private MazeObject mine = new Mine(); + private Vector domainListeners = new Vector(); + private String pauseMessage = null; + private boolean paused = false; + private int animationSequence = 0; + private GameSettings gameSettings; + + private AudioClip moveSound; + private AudioClip hitSound; + +/** + * MazeDomain constructor comment. + */ +protected MazeDomain() { + super(); + + moveSound = Applet.newAudioClip(getClass().getResource(String.format(BASE_PATH,"clickfast.wav"))); + hitSound = Applet.newAudioClip(getClass().getResource(String.format(BASE_PATH,"boing.wav"))); +} + + +/** + * Add a DomainListener. + * + * Creation date: (10/22/01 9:49:44 PM) + */ +public void addDomainListener(DomainListener domainListener) { + domainListeners.add(domainListener); +} + + +/** + * Determine if there are any explosions on the screen. + * After explosions have disappered, checks to see if the terminate + * message should be sent. This allows the message to be displayed + * stating that the game is over. + * + * Creation date: (10/26/01 12:12:54 PM) + */ +public boolean areExplosionsPresent() { + for (int x=0; x 5) { + notifyDomainListeners("terminate"); + } + return false; +} + + +/** + * Answer if a mouse is able to shoot in this game. + * + * Creation date: (10/28/01 1:32:27 PM) + */ +public boolean canMouseShoot() { + return gameSettings.isShootingMouse(); +} + + +/** + * Erase current domain as it relates to a specific game. + * + * Creation date: (11/5/01 10:29:06 PM) + */ +public void clear() { + map = null; + mapLevel = 1; + lives = 0; + kills = 0; + mousePoint = new Point(); + exitPoint = new Point(); + robots = new Vector(); + pauseMessage = null; + paused = false; + animationSequence = 0; +} + + +/** + * Initiate the game over sequence. + * + * Creation date: (10/26/01 12:54:32 PM) + */ +public void endGame() { + lives = 0; + notifyDomainListeners("gameOver"); +} + + +/** + * Provide random bomb explosions. + * + * Creation date: (10/26/01 12:38:22 PM) + */ +public void explodeBombsRandomly() { + if (isPaused()) return; + Random random = new Random(); + int x = random.nextInt(getMapWidth()-1); + int y = random.nextInt(getMapHeight()-1); + if (isBomb(x,y)) { + setMazeObject(x,y,null); + BombExplosionThread bombExplosion = new BombExplosionThread(new Point(x,y)); + bombExplosion.start(); + } +} + + +/** + * Generate a map. + * + * Creation date: (10/14/01 10:01:32 PM) + */ +public void generateMap() { + if (mapWidth > 0 && mapHeight > 0 && mapLevel > 0) { + setPause(true); + // setup information + MazeObject[][] oldMap = map; + map = new MazeObject[mapWidth][mapHeight]; + int midPoint = (mapHeight + 1) / 2 - 1; + // place mouse + setMazeObject(0, midPoint, mouse); + // place exit + exitPoint = new Point(mapWidth-1, midPoint); + setMazeObject(exitPoint, exit); + // place robots + if (getLevel() >= 5) { + placeRobot(0, 0); + placeRobot(0, mapHeight-1); + } + for (int i=1; i<=Math.min(getLevel(),4); i++) { + placeRobot(mapWidth-1, midPoint-i); + placeRobot(mapWidth-1, midPoint+i); + } + // place bombs + int bombs = mapLevel * gameSettings.getBombsPerLevel(); + Random random = new Random(); + while (bombs > 0) { + int x = random.nextInt(mapWidth); + int y = random.nextInt(mapHeight); + if (getMazeObject(x,y) == null) { + setMazeObject(x,y,bomb); + bombs--; + } + } + if (oldMap != null) { + LevelTranslationThread thread = new LevelTranslationThread("Welcome to level " + getLevel() + "!", map); + map = oldMap; + thread.start(); + } + } +} + + +/** + * Retrieve the current animation sequence. + * + * Creation date: (10/26/01 10:59:35 PM) + */ +public int getAnimationSequence() { + return animationSequence; +} + + +/** + * Get game settings. + * + * Creation date: (10/28/01 12:43:41 PM) + */ +public GameSettings getGameSettings() { + if (gameSettings == null) { + gameSettings = new GameSettings(); + gameSettings.load("default.properties"); + } + return gameSettings; +} + + +/** + * Retrieve the singleton instance. + * + * Creation date: (10/14/01 9:36:19 PM) + */ +public static MazeDomain getInstance() { + if (instance == null) { + instance = new MazeDomain(); + } + return instance; +} + + +/** + * Retrieve the number of robots killed. + * + * Creation date: (10/25/01 10:47:06 PM) + */ +public int getKills() { + return kills; +} + + +public int getLevel() { + return mapLevel; +} + + +/** + * Return the number of mouse lives left. + * + * Creation date: (10/25/01 11:24:01 PM) + */ +public int getLives() { + return lives; +} + + +/** + * Retrieve the current map. + * + * Creation date: (10/14/01 9:35:25 PM) + */ +public MazeObject[][] getMap() { + return map; +} + + +/** + * Retrieve map height. + * + * Creation date: (10/14/01 10:11:27 PM) + */ +public int getMapHeight() { + return mapHeight; +} + + +/** + * Retrieve map width. + * + * Creation date: (10/14/01 10:11:53 PM) + */ +public int getMapWidth() { + return mapWidth; +} + + +/** + * Get MazeObject. + * + * Creation date: (10/14/01 10:10:05 PM) + */ +public MazeObject getMazeObject(int x, int y) { + MazeObject mazeObject = null; + if (map != null) { + mazeObject = map[x][y]; + } + return mazeObject; +} + + +/** + * Get a MazeObject. + * + * Creation date: (10/21/01 3:49:44 PM) + */ +public MazeObject getMazeObject(Point pt) { + return getMazeObject(pt.x,pt.y); +} + + +public Point getMouseLocation() { + return mousePoint; +} + + +public String getPauseMessage() { + return pauseMessage; +} + + +/** + * Return the number of living robots. + * + * Creation date: (10/22/01 10:45:58 PM) + */ +public int getRobotCount() { + if (robots == null) return 0; + return robots.size(); +} + + +/** + * Retrieve the number of mouse lives. + * + * Creation date: (10/24/01 10:27:45 PM) + * @return int + */ +public int getTotalMice() { + return totalMice; +} + + +/** + * Increment the animation sequence. + * + * Creation date: (10/26/01 10:59:55 PM) + */ +public void incrementAnimationSequence() { + animationSequence++; +} + + +/** + * Test if a cell has a bomb. + * + * Creation date: (10/23/01 10:24:36 PM) + */ +public boolean isBomb(int x, int y) { + return getMazeObject(x,y) == bomb; +} + + +/** + * Answers true if the game has ended. + * This is used by other threads to force termination. + * + * Creation date: (10/26/01 11:05:40 PM) + */ +public boolean isGameOver() { + return (lives < 1); +} + + +public boolean isPaused() { + return paused; +} + + +/** + * Test if a point is a valid cell location. + * + * Creation date: (10/23/01 10:26:22 PM) + */ +public boolean isValidPoint(int x, int y) { + return (x >= 0 && x < mapWidth && y >= 0 && y < mapHeight); +} + + +/** + * Test if a point is a valid cell location. + * + * Creation date: (10/23/01 10:26:22 PM) + */ +public boolean isValidPoint(Point pt) { + return isValidPoint(pt.x, pt.y); +} + + +public void moveMouse(int dx, int dy) { + if (isPaused()) return; + if (mousePoint == null) return; + Point pt = new Point(mousePoint); + pt.translate(dx,dy); + + if (isValidPoint(pt) == false) return; + + if (getMazeObject(pt) == exit) { // end of level + moveSound.play(); + setMazeObject(mousePoint, null); + mousePoint = null; + if (gameSettings.isUnlimitedGameLevels() || getLevel() <= 5) { + setLevel(getLevel()+1); + generateMap(); + } else { + notifyDomainListeners("gameWon"); + } + } else if (getMazeObject(pt) == null) { // a valid move + moveSound.play(); + setMazeObject(mousePoint, null); + setMazeObject(pt, mouse); + } else if (getMazeObject(pt) == mine) { // ouch, that hurts! + setMazeObject(mousePoint, null); + setMazeObject(pt, mouse); + Thread explosion = new ExplosionThread(pt); + explosion.start(); + } else { + hitSound.play(); + } +} + + +/** + * Provide robot AI. + * An external thread will trigger this logic. + * + * Creation date: (10/22/01 10:47:15 PM) + * @return moved status (true == moved) + */ +public boolean moveRobot(AnimatedRobot robot) { + if (isPaused()) return true; + if (mousePoint == null) return false; + Point robotPoint = robot.getLocation(); + int dx = (mousePoint.x < robotPoint.x ? -1 : 0) + (mousePoint.x > robotPoint.x ? 1 : 0); + int dy = (mousePoint.y < robotPoint.y ? -1 : 0) + (mousePoint.y > robotPoint.y ? 1 : 0); + Random random = new Random(); + // determine if the robot will drop a mine + boolean willDropMine = (random.nextInt(100) < gameSettings.getRobotMineFrequency()); + MazeObject replacementObject = (willDropMine ? mine : null); + // try real move + Point pt = new Point(robotPoint); + pt.translate(dx,dy); + if (isValidPoint(pt) && getMazeObject(pt) == null) { + setMazeObject(robotPoint, replacementObject); + robotPoint.translate(dx,dy); // need to keep object intact! + setMazeObject(robotPoint, robot); + notifyDomainListeners("robot"); + // attempt to shoot... + robotShoot(robotPoint); + return true; + } else if (isValidPoint(pt) && getMazeObject(pt) == mouse) { + return false; + } + // try random move + dx = random.nextInt(3) - 1; + dy = random.nextInt(3) - 1; + pt = new Point(robotPoint); + pt.translate(dx,dy); + if (isValidPoint(pt) && getMazeObject(pt) == null) { + setMazeObject(robotPoint, replacementObject); + robotPoint.translate(dx,dy); // need to keep object intact! + setMazeObject(robotPoint, robot); + notifyDomainListeners("robot"); + // attempt to shoot... + robotShoot(robotPoint); + return true; + } + // shucks... + return false; +} + + +/** + * Invoke this method to start a new game. + * + * Creation date: (10/22/01 10:12:50 PM) + */ +public void newGame() { + setLevel(1); + lives = getTotalMice(); + kills = 0; + notifyDomainListeners("newGame"); + generateMap(); +} + + +/** + * Notify all change listeners. + * + * Creation date: (10/22/01 9:51:10 PM) + */ +protected void notifyDomainListeners(String event) { + Enumeration listeners = domainListeners.elements(); + DomainEvent domainEvent = new DomainEvent(this, event); + while (listeners.hasMoreElements()) { + DomainListener listener = (DomainListener) listeners.nextElement(); + listener.domainChanged(domainEvent); + } +} + + +/** + * Place a robot onto the maze. Used as a helper by generateMap. + * + * Creation date: (10/30/01 9:46:21 PM) + */ +protected void placeRobot(int x, int y) { + //System.out.println("Creating new robot at " + x + "," + y + "."); + int shieldLevels = (getGameSettings().isShieldedRobots() ? 2 : 0); + Point point = new Point(x, y); + AnimatedRobot robot = new AnimatedRobot(point, shieldLevels); + setMazeObject(point, robot); + robots.add(robot); +} + + +/** + * Remove a DomainListener. + * + * Creation date: (10/22/01 9:50:42 PM) + */ +public void removeDomainListener(DomainListener domainListener) { + domainListeners.remove(domainListener); +} + + +/** + * Control robot shooting. + * + * Creation date: (10/28/01 1:43:21 PM) + */ +protected void robotShoot(Point robotPoint) { + Random random = new Random(); + int distance = (int)robotPoint.distance(mousePoint); + boolean closeEnough = distance < gameSettings.getRobotVisibilityRange(); + boolean randomChance = random.nextInt(100) < gameSettings.getRobotShootFrequency(); + if (closeEnough && randomChance) { + int range; + if (gameSettings.isFixedRobotShotRange()) { + range = gameSettings.getRobotShotRange(); + } else { + range = random.nextInt(gameSettings.getRobotShotRange()); + } + int dx = (mousePoint.x < robotPoint.x ? -range : 0) + (mousePoint.x > robotPoint.x ? range : 0); + int dy = (mousePoint.y < robotPoint.y ? -range : 0) + (mousePoint.y > robotPoint.y ? range : 0); + Point pt = new Point(robotPoint); + pt.translate(dx,dy); + if (isValidPoint(pt)) { + MazeObject mazeObject = getMazeObject(pt); + if (mazeObject != null && mazeObject.isRobot() == false) { + Thread explosion = new ExplosionThread(pt); + explosion.start(); + } + } + } +} + + +/** + * Set the game settings. + * + * Creation date: (10/28/01 12:44:51 PM) + */ +public void setGameSettings(GameSettings newSettings) { + gameSettings = newSettings; +} + + +/** + * Choose a level. + * + * Creation date: (10/14/01 10:00:05 PM) + */ +public void setLevel(int level) { + // set new level + mapLevel = level; + notifyDomainListeners("level"); + // kill off any robots + if (robots != null) { + for (int i=0; i 0) { + setMazeObject(pt, null); + mousePoint = new Point(0,mapHeight/2); + setMazeObject(mousePoint, mouse); + notifyDomainListeners("mouseKilled"); + } else { + endGame(); + } + } + } + return pt; +} + + +/** + * Ensure that map is in sync. + * + * Creation date: (10/29/01 10:28:31 PM) + */ +public void synchronizeMap() { + if (getLives() > 0) setMazeObject(mousePoint, mouse); + setMazeObject(exitPoint, exit); + for (int i=0; iRob Greene + * @version: RJG 10/31/2001 22:12:32 + */ +public class ImageManager { + private static final String BASE_PATH = "/images/%s"; + private static ImageManager instance = null; + private Hashtable images = new Hashtable(); + +/** + * ImageManager constructor comment. + */ +protected ImageManager() { + super(); +} + + +/** + * Retrieve an image from the images table. + * If the image has not been loaded, it is loaded. + * + * Creation date: (10/31/01 8:51:13 PM) + */ +public Image getImage(String imageName) { + Image image = (Image) images.get(imageName); + if (image == null) { + image = loadImage(imageName); + } + return image; +} + + +/** + * Retrieve the singleton instance of this class and + * initialize the class. + * + * Creation date: (10/31/01 7:34:49 PM) + */ +public static synchronized ImageManager getInstance() { + if (instance == null) { + instance = new ImageManager(); + instance.initialize(); + } + return instance; +} + + +/** + * Initialize the class by preloading images. + * + * Creation date: (10/31/01 7:36:07 PM) + */ +protected void initialize() { + Properties properties = new Properties(); + String resourceName = String.format(BASE_PATH, "ImageManager.properties"); + InputStream inputStream = getClass().getResourceAsStream(resourceName); + if (inputStream != null) { + try { + properties.load(inputStream); + Enumeration elements = properties.keys(); + while (elements.hasMoreElements()) { + String imageName = (String) elements.nextElement(); + //if (imageName.startsWith("#") == false && imageName.length() > 0) { + loadImage(imageName); + //} + } + } catch (IOException ex) { + log("initialize", "Unable to load " + resourceName, ex); + } + } +} + + +/** + * Test if the requested images have completed loading. + * + * Creation date: (10/31/01 8:52:50 PM) + */ +public boolean isDoneLoading() { + Toolkit toolkit = Toolkit.getDefaultToolkit(); + Enumeration elements = images.elements(); + while (elements.hasMoreElements()) { + Image image = (Image) elements.nextElement(); + if (image.getHeight(null) == -1 || image.getWidth(null) == -1) { + return false; + } + } + return true; +} + + +/** + * Load an image into the images table. + * + * Creation date: (10/31/01 7:36:40 PM) + */ +protected Image loadImage(String imageName) { + Toolkit toolkit = Toolkit.getDefaultToolkit(); + URL url = getClass().getResource(String.format(BASE_PATH,imageName)); + Image image = null; + try { + image = toolkit.createImage((ImageProducer) url.getContent()); + images.put(imageName, image); + } catch (IOException ex) { + log("loadImage", "Unable to load " + imageName, ex); + } + return image; +} + + +/** + * Log errors. + * + * Creation date: (10/31/01 9:07:18 PM) + */ +protected void log(String methodName, String description, Exception exception) { + System.out.println(new Date() + " ImageManager." + methodName + ":"); + System.out.println(" " + description); + exception.printStackTrace(System.out); +} +} \ No newline at end of file diff --git a/src/main/java/a2geek/games/mousemaze2001/mazeobjects/AnimatedBomb.java b/src/main/java/a2geek/games/mousemaze2001/mazeobjects/AnimatedBomb.java new file mode 100644 index 0000000..b751c3b --- /dev/null +++ b/src/main/java/a2geek/games/mousemaze2001/mazeobjects/AnimatedBomb.java @@ -0,0 +1,41 @@ +package a2geek.games.mousemaze2001.mazeobjects; +/** + * Provide an animated bomb. + * + * Creation date: (10/26/01 11:01:35 PM) + * @author: Rob Greene + * @version: RJG 10/27/2001 01:02:48 + */ +public class AnimatedBomb extends AnimatedMouseMazeImageObject { +/** + * AnimatedMine constructor comment. + */ +public AnimatedBomb() { + super(); +} + + +/** + * Answers with the image names for this object. + * + * Creation date: (10/26/01 11:01:35 PM) + */ +protected String[] getImageNames() { + return new String[] { + "OriginalBomb0.gif", + "OriginalBomb1.gif", + "OriginalBomb2.gif", + "OriginalBomb3.gif" + }; +} + + +/** + * Returns true if this is a bomb. + * + * Creation date: (10/14/01 9:43:56 PM) + */ +public boolean isBomb() { + return true; +} +} \ No newline at end of file diff --git a/src/main/java/a2geek/games/mousemaze2001/mazeobjects/AnimatedMazeImageObject.java b/src/main/java/a2geek/games/mousemaze2001/mazeobjects/AnimatedMazeImageObject.java new file mode 100644 index 0000000..39886f8 --- /dev/null +++ b/src/main/java/a2geek/games/mousemaze2001/mazeobjects/AnimatedMazeImageObject.java @@ -0,0 +1,70 @@ +package a2geek.games.mousemaze2001.mazeobjects; +import java.net.*; + +import a2geek.games.mousemaze2001.images.ImageManager; + +import java.io.*; +import java.awt.image.*; +import java.awt.*; + +/** + * Represents a MazeObject which is Image based and is animated. (Basically, a 'tile'.) + * + * Creation date: (10/23/01 9:31:27 PM) + * @author: Rob Greene + * @version: RJG 10/31/2001 22:12:32 + */ +public abstract class AnimatedMazeImageObject extends MazeObject { + private Image[] images = null; + +/** + * MazeImageObject constructor comment. + */ +public AnimatedMazeImageObject() { + super(); + ImageManager imageManager = ImageManager.getInstance(); + String[] names = getImageNames(); + images = new Image[names.length]; + for (int i=0; iRob Greene + * @version: RJG 10/27/2001 01:02:48 + */ +public class AnimatedMouse extends AnimatedMouseMazeImageObject { +/** + * AnimatedMouse constructor comment. + */ +public AnimatedMouse() { + super(); +} + + +/** + * Answers with the image names for this object. + * + * Creation date: (10/27/01 12:22:59 AM) + */ +protected String[] getImageNames() { + return new String[] { + "OriginalMouse0.gif", + "OriginalMouse1.gif", + "OriginalMouse2.gif", + "OriginalMouse3.gif" + }; +} + + +/** + * Returns true if this is the mouse. + * + * Creation date: (10/14/01 9:43:11 PM) + */ +public boolean isMouse() { + return true; +} +} \ No newline at end of file diff --git a/src/main/java/a2geek/games/mousemaze2001/mazeobjects/AnimatedMouseMazeImageObject.java b/src/main/java/a2geek/games/mousemaze2001/mazeobjects/AnimatedMouseMazeImageObject.java new file mode 100644 index 0000000..b1cf478 --- /dev/null +++ b/src/main/java/a2geek/games/mousemaze2001/mazeobjects/AnimatedMouseMazeImageObject.java @@ -0,0 +1,31 @@ +package a2geek.games.mousemaze2001.mazeobjects; + +import a2geek.games.mousemaze2001.domain.MazeDomain; + +/** + * Provides the generic base-class for the MouseMaze 2001 games. + * + * Creation date: (10/26/01 10:58:46 PM) + * @author: Rob Greene + * @version: RJG 10/27/2001 01:02:48 + */ +public abstract class AnimatedMouseMazeImageObject extends AnimatedMazeImageObject { +/** + * AnimatedMouseMazeImageObject constructor comment. + */ +public AnimatedMouseMazeImageObject() { + super(); +} + + +/** + * Provides the animation sequence. + * This just needs to be an integer - not necessarily in the valid range, as + * modulo arithmetic will be used. + * + * Creation date: (10/26/01 10:55:18 PM) + */ +protected int getAnimationSequence() { + return MazeDomain.getInstance().getAnimationSequence(); +} +} \ No newline at end of file diff --git a/src/main/java/a2geek/games/mousemaze2001/mazeobjects/AnimatedRobot.java b/src/main/java/a2geek/games/mousemaze2001/mazeobjects/AnimatedRobot.java new file mode 100644 index 0000000..8f9b52a --- /dev/null +++ b/src/main/java/a2geek/games/mousemaze2001/mazeobjects/AnimatedRobot.java @@ -0,0 +1,192 @@ +package a2geek.games.mousemaze2001.mazeobjects; +import java.awt.Point; + +import a2geek.games.mousemaze2001.domain.MazeDomain; + +/** + * Represents the animated robot. + * + * Creation date: (10/27/01 12:08:56 AM) + * @author: Rob Greene + * @version: RJG 10/31/2001 22:12:32 + */ +public class AnimatedRobot extends AnimatedMouseMazeImageObject { + private static int idCounter = 0; + private int id; + private Point location; + private int shieldLevel; + private Thread controlThread; + +/** + * AnimatedRobot constructor comment. + */ +public AnimatedRobot(Point location, int shieldLevel) { + super(); + id = idCounter++; + setLocation(location); + setShieldLevel(shieldLevel); + createControlThread(); + controlThread.start(); +} + + +/** + * Create the control thread. + * + * Creation date: (10/29/01 10:55:38 PM) + */ +protected void createControlThread() { + controlThread = new Thread() { + private void log(String message) { + //System.out.println(new java.util.Date() + " (" + id + ") - " + message); + } + public void run() { + MazeDomain domain = MazeDomain.getInstance(); + log("Robot thread started."); + while (getInstance().isAlive()) { + if (domain.isGameOver()) break; + log("Robot alive at " + location.x + "," + location.y); + try { + if (getInstance() != null) { + domain.moveRobot(getInstance()); + sleep(1250); + } + } catch (InterruptedException ex) { + ex.printStackTrace(System.out); + } + } + log("Robot died."); + } + }; + controlThread.setDaemon(true); +} + + +/** + * Decrease the robots shield level. + * + * Creation date: (10/29/01 7:48:53 PM) + */ +public void decreaseShieldLevel() { + shieldLevel--; +} + + +/** + * Provides the animation sequence. + * This just needs to be an integer - not necessarily in the valid range, as + * modulo arithmetic will be used. + * + * Creation date: (10/26/01 10:55:18 PM) + */ +protected int getAnimationSequence() { + return (super.getAnimationSequence() % 4) + (shieldLevel * 4); +} + + +/** + * Answers with the image names for this object. + * + * Creation date: (10/27/01 12:08:56 AM) + */ +protected java.lang.String[] getImageNames() { + return new String[] { + "OriginalRobot0.gif", + "OriginalRobot1.gif", + "OriginalRobot2.gif", + "OriginalRobot3.gif", + "OriginalRobot0shield1.gif", + "OriginalRobot1shield1.gif", + "OriginalRobot2shield1.gif", + "OriginalRobot3shield1.gif", + "OriginalRobot0shield2.gif", + "OriginalRobot1shield2.gif", + "OriginalRobot2shield2.gif", + "OriginalRobot3shield2.gif" + }; +} + + +/** + * Internal hook for control thread. + * + * Creation date: (10/29/01 11:00:57 PM) + */ +protected AnimatedRobot getInstance() { + return this; +} + + +/** + * Retrieve the Robots current position. + * + * Creation date: (10/29/01 7:47:51 PM) + * @return java.awt.Point + */ +public Point getLocation() { + return location; +} + + +/** + * Retrieve the robots current shield level. + * + * Creation date: (10/29/01 7:47:51 PM) + * @return int + */ +public int getShieldLevel() { + return shieldLevel; +} + + +/** + * Answers true if this robot is still alive. + * + * Creation date: (10/29/01 9:38:38 PM) + */ +public boolean isAlive() { + return (shieldLevel >= 0); +} + + +/** + * Returns true if this is a robot. + * + * Creation date: (10/14/01 9:42:51 PM) + */ +public boolean isRobot() { + return true; +} + + +/** + * Kill this robot. + * + * Creation date: (10/29/01 11:04:18 PM) + */ +public void kill() { + shieldLevel = -1; +} + + +/** + * Set the robots current location. + * + * Creation date: (10/29/01 7:47:51 PM) + * @param newLocation java.awt.Point + */ +public void setLocation(Point newLocation) { + location = newLocation; +} + + +/** + * Set the robots current shield level. + * + * Creation date: (10/29/01 7:47:51 PM) + * @param newShieldLevel int + */ +public void setShieldLevel(int newShieldLevel) { + shieldLevel = newShieldLevel; +} +} \ No newline at end of file diff --git a/src/main/java/a2geek/games/mousemaze2001/mazeobjects/ColoredMazeObject.java b/src/main/java/a2geek/games/mousemaze2001/mazeobjects/ColoredMazeObject.java new file mode 100644 index 0000000..6b7ced2 --- /dev/null +++ b/src/main/java/a2geek/games/mousemaze2001/mazeobjects/ColoredMazeObject.java @@ -0,0 +1,42 @@ +package a2geek.games.mousemaze2001.mazeobjects; +import java.awt.*; + +/** + * Will draw the MazeObject in a solid color. + * + * Creation date: (10/23/01 9:37:10 PM) + * @author: Rob Greene + * @version: RJG 10/23/2001 23:16:23 + */ +public abstract class ColoredMazeObject extends MazeObject { +/** + * ColoredMazeObject constructor comment. + */ +public ColoredMazeObject() { + super(); +} + + +/** + * Returns true if this is an explosion. + * + * Creation date: (10/14/01 9:42:51 PM) + */ +public boolean isExplosion() { + return true; +} + + +/** + * Draw image on screen. + * It is expected that the region to be drawn has been clipped. + * See Graphics.create for more details. + * + * Creation date: (10/14/01 9:45:16 PM) + */ +public void paint(Graphics g) { + Rectangle rect = g.getClipBounds(); + g.setColor(getBackground()); + g.fillRect(0, 0, rect.width, rect.height); +} +} \ No newline at end of file diff --git a/src/main/java/a2geek/games/mousemaze2001/mazeobjects/Exit.java b/src/main/java/a2geek/games/mousemaze2001/mazeobjects/Exit.java new file mode 100644 index 0000000..483c2b9 --- /dev/null +++ b/src/main/java/a2geek/games/mousemaze2001/mazeobjects/Exit.java @@ -0,0 +1,52 @@ +package a2geek.games.mousemaze2001.mazeobjects; +import java.awt.*; +/** + * Represents the exit. + * + * Creation date: (10/14/01 10:32:40 PM) + * @author: Rob Greene + * @version: RJG 10/24/2001 22:58:13 + */ +public class Exit extends MazeImageObject { +/** + * Exit constructor comment. + */ +public Exit() { + super(); +} + + +/** + * Answers with the image name of this object. + * + * Creation date: (10/14/01 10:32:40 PM) + */ +protected String getImageName() { + return "OriginalExit.gif"; +} + + +/** + * Returns true if this is an exit. + * + * Creation date: (10/14/01 9:43:27 PM) + */ +public boolean isExit() { + return true; +} + + +/** + * Draw image on screen. + * It is expected that the region to be drawn has been clipped. + * See Graphics.create for more details. + * + * Creation date: (10/14/01 9:45:16 PM) + */ +public void paint(Graphics g) { + Rectangle rect = g.getClipBounds(); + g.setColor(Color.white); + g.fillRect(0,0,rect.width,rect.height); + super.paint(g); +} +} \ No newline at end of file diff --git a/src/main/java/a2geek/games/mousemaze2001/mazeobjects/GreenTile.java b/src/main/java/a2geek/games/mousemaze2001/mazeobjects/GreenTile.java new file mode 100644 index 0000000..3ae4011 --- /dev/null +++ b/src/main/java/a2geek/games/mousemaze2001/mazeobjects/GreenTile.java @@ -0,0 +1,27 @@ +package a2geek.games.mousemaze2001.mazeobjects; +import java.awt.*; +/** + * Insert the type's description here. + * + * Creation date: (10/23/01 9:38:56 PM) + * @author: Rob Greene + * @version: RJG 10/23/2001 23:16:23 + */ +public class GreenTile extends ColoredMazeObject { +/** + * GreenTile constructor comment. + */ +public GreenTile() { + super(); +} + + +/** + * Retrieve the background color of this tile. + * + * Creation date: (10/23/01 9:50:07 PM) + */ +public Color getBackground() { + return Color.green; +} +} \ No newline at end of file diff --git a/src/main/java/a2geek/games/mousemaze2001/mazeobjects/InvertedMouse.java b/src/main/java/a2geek/games/mousemaze2001/mazeobjects/InvertedMouse.java new file mode 100644 index 0000000..8a7a9a0 --- /dev/null +++ b/src/main/java/a2geek/games/mousemaze2001/mazeobjects/InvertedMouse.java @@ -0,0 +1,39 @@ +package a2geek.games.mousemaze2001.mazeobjects; + +import a2geek.games.mousemaze2001.mazeobjects.*; + +/** + * Represents the inverted mouse image used for the life indicator. + * + * Creation date: (10/27/01 12:56:35 AM) + * @author: Rob Greene + * @version: RJG 10/29/2001 23:31:16 + */ +public class InvertedMouse extends MazeImageObject { +/** + * InvertedMouse constructor comment. + */ +public InvertedMouse() { + super(); +} + + +/** + * Answers with the image name of this object. + * + * Creation date: (10/14/01 10:31:56 PM) + */ +protected String getImageName() { + return "InvertedMouse.gif"; +} + + +/** + * Returns true if this is the mouse. + * + * Creation date: (10/14/01 9:43:11 PM) + */ +public boolean isMouse() { + return true; +} +} \ No newline at end of file diff --git a/src/main/java/a2geek/games/mousemaze2001/mazeobjects/MazeImageObject.java b/src/main/java/a2geek/games/mousemaze2001/mazeobjects/MazeImageObject.java new file mode 100644 index 0000000..423a656 --- /dev/null +++ b/src/main/java/a2geek/games/mousemaze2001/mazeobjects/MazeImageObject.java @@ -0,0 +1,72 @@ +package a2geek.games.mousemaze2001.mazeobjects; +import java.net.*; + +import a2geek.games.mousemaze2001.images.ImageManager; + +import java.io.*; +import java.awt.image.*; +import java.awt.*; + +/** + * Represents a MazeObject which is Image based. (Basically, a 'tile'.) + * + * Creation date: (10/23/01 9:31:27 PM) + * @author: Rob Greene + * @version: RJG 10/31/2001 22:12:32 + */ +public abstract class MazeImageObject extends MazeObject { + private Image image = null; + +/** + * MazeImageObject constructor comment. + */ +public MazeImageObject() { + super(); + image = ImageManager.getInstance().getImage(getImageName()); +} + + +/** + * Return the height of the image. + * + * Creation date: (10/27/01 12:47:15 AM) + */ +public int getHeight() { + return image.getHeight(null); +} + + +/** + * Answers with the image name of this object. + * + * Creation date: (10/14/01 9:41:15 PM) + */ +protected abstract String getImageName(); + + +/** + * Return the width of the image. + * + * Creation date: (10/27/01 12:47:15 AM) + */ +public int getWidth() { + return image.getWidth(null); +} + + +/** + * Draw image on screen. + * It is expected that the region to be drawn has been clipped. + * See Graphics.create for more details. + * + * Creation date: (10/14/01 9:45:16 PM) + */ +public void paint(Graphics g) { + if (image != null) { + Rectangle rect = g.getClipBounds(); + int x = (rect.width - image.getWidth(null)) / 2; + int y = (rect.height - image.getHeight(null)) / 2; + g.drawImage(image, x, x, null); + } +} +} \ No newline at end of file diff --git a/src/main/java/a2geek/games/mousemaze2001/mazeobjects/MazeObject.java b/src/main/java/a2geek/games/mousemaze2001/mazeobjects/MazeObject.java new file mode 100644 index 0000000..529a73b --- /dev/null +++ b/src/main/java/a2geek/games/mousemaze2001/mazeobjects/MazeObject.java @@ -0,0 +1,89 @@ +package a2geek.games.mousemaze2001.mazeobjects; +import java.awt.*; + +/** + * Represents a maze object. + * + * Creation date: (10/14/01 9:38:50 PM) + * @author: Rob Greene + * @version: RJG 10/23/2001 23:16:23 + */ +public abstract class MazeObject extends Canvas { +/** + * MazeObject constructor comment. + */ +public MazeObject() { + super(); +} + + +/** + * Returns true if this is a bomb. + * + * Creation date: (10/14/01 9:43:27 PM) + */ +public boolean isBomb() { + return false; +} + + +/** + * Returns true if this is an exit. + * + * Creation date: (10/14/01 9:43:27 PM) + */ +public boolean isExit() { + return false; +} + + +/** + * Returns true if this is an explosion. + * + * Creation date: (10/14/01 9:42:51 PM) + */ +public boolean isExplosion() { + return false; +} + + +/** + * Returns true if this is a mine. + * + * Creation date: (10/14/01 9:43:56 PM) + */ +public boolean isMine() { + return false; +} + + +/** + * Returns true if this is the mouse. + * + * Creation date: (10/14/01 9:43:11 PM) + */ +public boolean isMouse() { + return false; +} + + +/** + * Returns true if this is a robot. + * + * Creation date: (10/14/01 9:42:51 PM) + */ +public boolean isRobot() { + return false; +} + + +/** + * Draw image on screen. + * It is expected that the region to be drawn has been clipped. + * See Graphics.create for more details. + * + * Creation date: (10/14/01 9:45:16 PM) + */ +public void paint(Graphics g) { +} +} \ No newline at end of file diff --git a/src/main/java/a2geek/games/mousemaze2001/mazeobjects/Mine.java b/src/main/java/a2geek/games/mousemaze2001/mazeobjects/Mine.java new file mode 100644 index 0000000..85e1baf --- /dev/null +++ b/src/main/java/a2geek/games/mousemaze2001/mazeobjects/Mine.java @@ -0,0 +1,36 @@ +package a2geek.games.mousemaze2001.mazeobjects; +/** + * Represents a mine. + * + * Creation date: (10/22/01 11:23:56 PM) + * @author: Rob Greene + * @version: RJG 10/23/2001 23:16:23 + */ +public class Mine extends MazeImageObject { +/** + * Mine constructor comment. + */ +public Mine() { + super(); +} + + +/** + * Answers with the image name of this object. + * + * Creation date: (10/22/01 11:23:56 PM) + */ +protected String getImageName() { + return "OriginalMine.gif"; +} + + +/** + * Returns true if this is a mine. + * + * Creation date: (10/14/01 9:43:56 PM) + */ +public boolean isMine() { + return true; +} +} \ No newline at end of file diff --git a/src/main/java/a2geek/games/mousemaze2001/mazeobjects/PurpleTile.java b/src/main/java/a2geek/games/mousemaze2001/mazeobjects/PurpleTile.java new file mode 100644 index 0000000..4179111 --- /dev/null +++ b/src/main/java/a2geek/games/mousemaze2001/mazeobjects/PurpleTile.java @@ -0,0 +1,29 @@ +package a2geek.games.mousemaze2001.mazeobjects; +import java.awt.*; + +/** + * Purple (cyan) explosion tile. + * + * Creation date: (10/23/01 9:39:30 PM) + * @author: Rob Greene + * @version: RJG 10/23/2001 23:16:23 + */ +public class PurpleTile extends ColoredMazeObject { +/** + * PurpleTile constructor comment. + */ +public PurpleTile() { + super(); + setBackground(Color.cyan); +} + + +/** + * Retrieve the background color of this tile. + * + * Creation date: (10/23/01 9:50:07 PM) + */ +public Color getBackground() { + return Color.magenta; +} +} \ No newline at end of file diff --git a/src/main/java/a2geek/games/mousemaze2001/threads/AnimationThread.java b/src/main/java/a2geek/games/mousemaze2001/threads/AnimationThread.java new file mode 100644 index 0000000..797663b --- /dev/null +++ b/src/main/java/a2geek/games/mousemaze2001/threads/AnimationThread.java @@ -0,0 +1,39 @@ +package a2geek.games.mousemaze2001.threads; + +import a2geek.games.mousemaze2001.MouseMaze2001; +import a2geek.games.mousemaze2001.domain.MazeDomain; + +/** + * Insert the type's description here. + * + * Creation date: (10/27/01 12:38:44 AM) + * @author: Rob Greene + * @version: RJG 10/27/2001 01:02:48 + */ +public class AnimationThread extends Thread { +/** + * AnimationThread constructor comment. + */ +public AnimationThread() { + super("AnimationThread"); +} + + +/** + * Provide animation. + * + * Creation date: (10/27/01 12:38:59 AM) + */ +public void run() { + MazeDomain domain = MazeDomain.getInstance(); + MouseMaze2001 game = MouseMaze2001.getInstance(); + while (domain.isGameOver() == false) { + try { + sleep(250); + } catch (InterruptedException ex) { + } + domain.incrementAnimationSequence(); + game.repaintNeeded(); + } +} +} \ No newline at end of file diff --git a/src/main/java/a2geek/games/mousemaze2001/threads/BombExplosionThread.java b/src/main/java/a2geek/games/mousemaze2001/threads/BombExplosionThread.java new file mode 100644 index 0000000..ecfdc00 --- /dev/null +++ b/src/main/java/a2geek/games/mousemaze2001/threads/BombExplosionThread.java @@ -0,0 +1,58 @@ +package a2geek.games.mousemaze2001.threads; +import java.util.*; + +import a2geek.games.mousemaze2001.domain.MazeDomain; + +import java.awt.*; + +/** + * This thread sets up the bomb explosion and creates multiple explosion threads. + * + * Creation date: (10/23/01 10:08:07 PM) + * @author: Rob Greene + * @version: RJG 10/24/2001 22:58:13 + */ +public class BombExplosionThread extends Thread { + private int delay = 400; + private Point pt = null; + private int maxSize = 4; + +/** + * ExplosionThread constructor comment. + */ +public BombExplosionThread(Point pt) { + super("BombExplosionThread"); + this.pt = pt; +} + + +/** + * Perform the threadded process to generate bomb explosions. + * Generates the initial bomb explosion and then delayed rings around that point. + *

+ * Creation date: (10/23/01 10:08:07 PM) + */ +public void run() { + try { + MazeDomain domain = MazeDomain.getInstance(); + Random random = new Random(); + int size = random.nextInt(maxSize-2)+2; + for (int i=0; i + * To implement a pausable thread, extend the ControlledThread and implement process. + * Don't forget to set a default delay in your constructor, if appropriate! + *

+ * Creation date: (10/20/01 9:08:13 PM) + * @author: Rob Greene + * @version: RJG 10/29/2001 22:40:54 + */ +public abstract class ControlledThread implements Runnable { + private boolean running = false; + private boolean paused = false; + private Thread thread; + private long delay; + +/** + * ControlledThread constructor. + */ +public ControlledThread() { + super(); + thread = new Thread(this, getThreadName()); + thread.setDaemon(true); +} + + +/** + * Retrieve the delay that the thread will use. + *

+ * Creation date: (10/20/01 9:42:01 PM) + * @return long + */ +public final long getDelay() { + return delay; +} + + +/** + * Returns the name of this thread. By default, it will be the class name. + * + * Creation date: (10/21/01 2:24:36 PM) + */ +protected String getThreadName() { + String className = getClass().getName(); + int pos = className.lastIndexOf(".") + 1; + if (pos > -1) return className.substring(pos); + else return className; +} + + +/** + * Returns true if the thread is paused. + * Note that this does not indicate if the thread is actually running. + *

+ * Creation date: (10/20/01 10:20:37 PM) + */ +public final boolean isPaused() { + return paused; +} + + +/** + * Returns true if this thread is actively running. + * Note that this does not indicate if the thread has been paused. + *

+ * Creation date: (10/20/01 10:21:07 PM) + */ +public final boolean isRunning() { + return running; +} + + +/** + * Perform the threadded process. + *

+ * Creation date: (10/20/01 10:21:40 PM) + */ +protected abstract void process(); + + +/** + * Resume a paused thread. + * Note that the thread must be in a running state. + *

+ * Creation date: (10/20/01 10:22:13 PM) + */ +public synchronized final void resume() { + paused = false; + notifyAll(); +} + + +/** + * This is the thread control loop. + * To customize, implement the process method. + *

+ * Creation date: (10/20/01 10:22:32 PM) + */ +public final void run() { + while (isRunning()) { + try { + process(); // <-- customize here!! + synchronized(this) { + while (isRunning() && isPaused()) { + wait(); + } + } + thread.sleep(getDelay()); + } catch (Exception ex) { + System.out.println("Exception in " + getThreadName()); + ex.printStackTrace(System.out); + } + } + paused = false; + running = false; +} + + +/** + * Set the delay used in the control thread. + *

+ * Creation date: (10/20/01 9:42:01 PM) + * @param newDelay long + */ +public final void setDelay(long newDelay) { + delay = newDelay; +} + + +/** + * Start the thread. + *

+ * Creation date: (10/20/01 10:24:37 PM) + */ +public final void start() { + if (isRunning()) { + resume(); + } else { + running = true; + paused = false; + thread.start(); + } +} + + +/** + * Stop the thread. + *

+ * Creation date: (10/20/01 10:24:46 PM) + */ +public synchronized final void stop() { + running = false; + notifyAll(); +} + + +/** + * Suspend the thread. + *

+ * Creation date: (10/20/01 10:24:58 PM) + */ +public final void suspend() { + paused = true; +} +} \ No newline at end of file diff --git a/src/main/java/a2geek/games/mousemaze2001/threads/ExplosionThread.java b/src/main/java/a2geek/games/mousemaze2001/threads/ExplosionThread.java new file mode 100644 index 0000000..c4d5083 --- /dev/null +++ b/src/main/java/a2geek/games/mousemaze2001/threads/ExplosionThread.java @@ -0,0 +1,55 @@ +package a2geek.games.mousemaze2001.threads; +import java.awt.*; + +import a2geek.games.mousemaze2001.MouseMaze2001; +import a2geek.games.mousemaze2001.domain.MazeDomain; +import a2geek.games.mousemaze2001.mazeobjects.*; + +/** + * This thread runs until the explosion effect is done. + * + * Creation date: (10/23/01 10:08:07 PM) + * @author: Rob Greene + * @version: RJG 10/29/2001 22:40:54 + */ +public class ExplosionThread extends Thread { + private int delay = 100; + private int loops = 3; + private Point pt = null; + +/** + * ExplosionThread constructor comment. + */ +public ExplosionThread(Point pt) { + super("ExplosionThread"); + this.pt = pt; + this.setPriority(2); +} + + +/** + * Perform the threadded process. + *

+ * Creation date: (10/23/01 10:08:07 PM) + */ +public void run() { + try { + MazeDomain domain = MazeDomain.getInstance(); + domain.shoot(pt); + for (int i=0; iRob Greene + * @version: RJG 10/31/2001 22:12:32 + */ +public class GameDelayThread extends Thread { + private int delay; + +/** + * GameDelayThread constructor comment. + */ +public GameDelayThread(String message) { + this(message, 250); +} + + +/** + * GameDelayThread constructor comment. + */ +public GameDelayThread(String message, int delay) { + super(); + MazeDomain.getInstance().setPause(message); + MouseMaze2001.getInstance().repaintNeeded(); + this.delay = delay; +} + + +/** + * Pause for a short period of time and then disable the game pause. + * + * Creation date: (10/25/01 11:49:16 PM) + */ +public void run() { + try { + sleep(delay); + while (MazeDomain.getInstance().areExplosionsPresent()) { + sleep(50); + } + } catch (InterruptedException ex) { + int i = 0; + // ignore + } + MazeDomain.getInstance().setPause(null); +} +} \ No newline at end of file diff --git a/src/main/java/a2geek/games/mousemaze2001/threads/GameThread.java b/src/main/java/a2geek/games/mousemaze2001/threads/GameThread.java new file mode 100644 index 0000000..7ea2289 --- /dev/null +++ b/src/main/java/a2geek/games/mousemaze2001/threads/GameThread.java @@ -0,0 +1,32 @@ +package a2geek.games.mousemaze2001.threads; +import java.awt.Point; +import java.util.*; + +import a2geek.games.mousemaze2001.domain.MazeDomain; + +/** + * Provide AI for MouseMaze game. + * + * Creation date: (10/21/01 2:00:35 PM) + * @author: Rob Greene + * @version: RJG 10/29/2001 23:31:16 + */ +public class GameThread extends ControlledThread { +/** + * GameThread constructor comment. + */ +public GameThread() { + super(); + setDelay(300); +} + + +/** + * Perform the threadded process. + *

+ * Creation date: (10/21/01 2:00:35 PM) + */ +protected void process() { + MazeDomain.getInstance().explodeBombsRandomly(); +} +} \ No newline at end of file diff --git a/src/main/java/a2geek/games/mousemaze2001/threads/IntroThread.java b/src/main/java/a2geek/games/mousemaze2001/threads/IntroThread.java new file mode 100644 index 0000000..c431f8c --- /dev/null +++ b/src/main/java/a2geek/games/mousemaze2001/threads/IntroThread.java @@ -0,0 +1,32 @@ +package a2geek.games.mousemaze2001.threads; + +import a2geek.games.mousemaze2001.IntroPanel; + +/** + * Manage the Intro (demo) control thread. + *

+ * Creation date: (10/20/01 9:08:13 PM) + * @author: Rob Greene + * @version: RJG 10/23/2001 23:16:23 + */ +public class IntroThread extends ControlledThread { +/** + * IntroThread constructor comment. + */ +public IntroThread() { + super(); + setDelay(15); +} + + +/** + * Instruct the IntroPanel to perform another "tick". + *

+ * Creation date: (10/20/01 10:25:15 PM) + */ +protected void process() { + IntroPanel introPanel = IntroPanel.getInstance(); + introPanel.incrementTicker(); + introPanel.repaint(); +} +} \ No newline at end of file diff --git a/src/main/java/a2geek/games/mousemaze2001/threads/LevelTranslationThread.java b/src/main/java/a2geek/games/mousemaze2001/threads/LevelTranslationThread.java new file mode 100644 index 0000000..f25d149 --- /dev/null +++ b/src/main/java/a2geek/games/mousemaze2001/threads/LevelTranslationThread.java @@ -0,0 +1,68 @@ +package a2geek.games.mousemaze2001.threads; + +import a2geek.games.mousemaze2001.MouseMaze2001; +import a2geek.games.mousemaze2001.domain.MazeDomain; +import a2geek.games.mousemaze2001.mazeobjects.*; + +/** + * This thread will pause the game while the map is redrawn; semi artistically. + * + * Creation date: (10/25/01 11:45:57 PM) + * @author: Rob Greene + * @version: RJG 11/05/2001 22:35:58 + */ +public class LevelTranslationThread extends Thread { + private int delay; + private MazeObject[][] newMap; + +/** + * LevelTranslationThread constructor comment. + */ +public LevelTranslationThread(String message, MazeObject[][] map) { + this(message, 5, map); +} + + +/** + * LevelTranslationThread constructor comment. + */ +public LevelTranslationThread(String message, int delay, MazeObject[][] map) { + super(); + MazeDomain.getInstance().setPause(message); + MouseMaze2001.getInstance().repaintNeeded(); + this.newMap = map; + this.delay = delay; +} + + +/** + * Pause for a short period of time and then disable the game pause. + * + * Creation date: (10/25/01 11:49:16 PM) + */ +public void run() { + MazeDomain domain = MazeDomain.getInstance(); + MouseMaze2001 controller = MouseMaze2001.getInstance(); + GreenTile greenTile = new GreenTile(); + PurpleTile purpleTile = new PurpleTile(); + try { + for (int x=0; xRob Greene + * @version: RJG 10/31/2001 22:12:32 + */ +public class RepaintThread implements Runnable { + private Component component; + private Thread thread; + private int delay; + private boolean repaintNeeded; + +/** + * RepaintThread constructor. + */ +public RepaintThread(Component theComponent) { + super(); + thread = new Thread(this, "RepaintThread"); + thread.setDaemon(true); + component = theComponent; + delay = 50; + thread.setPriority(thread.getPriority()-1); +} + + +/** + * Retrieve the current delay used by the RepaintThread. + * + * Creation date: (10/24/01 9:12:16 PM) + * @return int + */ +public int getDelay() { + return delay; +} + + +/** + * Tell the RepaintThread that a repaint needs to occur. + * + * Creation date: (10/24/01 9:19:23 PM) + */ +public synchronized void repaintNeeded() { + //System.out.println(new java.util.Date() + " + repaint received"); + repaintNeeded = true; + notifyAll(); +} + + +/** + * Control the RepaintThread. + * + * Creation date: (10/24/01 9:15:14 PM) + */ +public void run() { + while (true) { + try { + if (repaintNeeded) { + repaintNeeded = false; + component.repaint(); + } + thread.sleep(getDelay()); + synchronized(this) { + wait(); + } + } catch (Exception ex) { + break; + } + } +} + + +/** + * Set the delay to be used by the RepaintThread. + * + * Creation date: (10/24/01 9:12:16 PM) + * @param newDelay int + */ +public void setDelay(int newDelay) { + delay = newDelay; +} + + +/** + * Start the thread. + *

+ * Creation date: (10/20/01 10:24:37 PM) + */ +public void start() { + thread.start(); +} +} \ No newline at end of file diff --git a/src/main/resources/images/CancelButton.gif b/src/main/resources/images/CancelButton.gif new file mode 100644 index 0000000..1ed4c91 Binary files /dev/null and b/src/main/resources/images/CancelButton.gif differ diff --git a/src/main/resources/images/DefaultButton.gif b/src/main/resources/images/DefaultButton.gif new file mode 100644 index 0000000..adf1c98 Binary files /dev/null and b/src/main/resources/images/DefaultButton.gif differ diff --git a/src/main/resources/images/EasyButton.gif b/src/main/resources/images/EasyButton.gif new file mode 100644 index 0000000..4512c1d Binary files /dev/null and b/src/main/resources/images/EasyButton.gif differ diff --git a/src/main/resources/images/HardButton.gif b/src/main/resources/images/HardButton.gif new file mode 100644 index 0000000..d018875 Binary files /dev/null and b/src/main/resources/images/HardButton.gif differ diff --git a/src/main/resources/images/ImageManager.properties b/src/main/resources/images/ImageManager.properties new file mode 100644 index 0000000..45dfa3b --- /dev/null +++ b/src/main/resources/images/ImageManager.properties @@ -0,0 +1,52 @@ +# Logo +MouseMazeLogo.gif + +# Buttons +CancelButton.gif +DefaultButton.gif +EasyButton.gif +HardButton.gif +OkButton.gif +PreferencesButton.gif +QuitButton.gif +StartButton.gif + +# Intro sequence images +OriginalMouseMazeGameShot.gif +OriginalMouseMazeHelp.gif +OriginalMouseMazeLogo.gif +OriginalMouseMazeWin.gif + +# Mouse used for lives left +InvertedMouse.gif + +# Static game images +OriginalBomb.gif +OriginalExit.gif +OriginalMine.gif +OriginalMouse.gif +OriginalRobot.gif +OriginalSkull.gif + +# Animated game image sequences +OriginalBomb0.gif +OriginalBomb1.gif +OriginalBomb2.gif +OriginalBomb3.gif +OriginalMouse0.gif +OriginalMouse1.gif +OriginalMouse2.gif +OriginalMouse3.gif +OriginalMouse4.gif +OriginalRobot0.gif +OriginalRobot0shield1.gif +OriginalRobot0shield2.gif +OriginalRobot1.gif +OriginalRobot1shield1.gif +OriginalRobot1shield2.gif +OriginalRobot2.gif +OriginalRobot2shield1.gif +OriginalRobot2shield2.gif +OriginalRobot3.gif +OriginalRobot3shield1.gif +OriginalRobot3shield2.gif diff --git a/src/main/resources/images/InvertedMouse.gif b/src/main/resources/images/InvertedMouse.gif new file mode 100644 index 0000000..91c109b Binary files /dev/null and b/src/main/resources/images/InvertedMouse.gif differ diff --git a/src/main/resources/images/MouseMazeLogo.gif b/src/main/resources/images/MouseMazeLogo.gif new file mode 100644 index 0000000..cc67aee Binary files /dev/null and b/src/main/resources/images/MouseMazeLogo.gif differ diff --git a/src/main/resources/images/OkButton.gif b/src/main/resources/images/OkButton.gif new file mode 100644 index 0000000..3809cb4 Binary files /dev/null and b/src/main/resources/images/OkButton.gif differ diff --git a/src/main/resources/images/OriginalBomb.gif b/src/main/resources/images/OriginalBomb.gif new file mode 100644 index 0000000..d5abb4c Binary files /dev/null and b/src/main/resources/images/OriginalBomb.gif differ diff --git a/src/main/resources/images/OriginalBomb0.gif b/src/main/resources/images/OriginalBomb0.gif new file mode 100644 index 0000000..d5abb4c Binary files /dev/null and b/src/main/resources/images/OriginalBomb0.gif differ diff --git a/src/main/resources/images/OriginalBomb1.gif b/src/main/resources/images/OriginalBomb1.gif new file mode 100644 index 0000000..52c045a Binary files /dev/null and b/src/main/resources/images/OriginalBomb1.gif differ diff --git a/src/main/resources/images/OriginalBomb2.gif b/src/main/resources/images/OriginalBomb2.gif new file mode 100644 index 0000000..3b29cb7 Binary files /dev/null and b/src/main/resources/images/OriginalBomb2.gif differ diff --git a/src/main/resources/images/OriginalBomb3.gif b/src/main/resources/images/OriginalBomb3.gif new file mode 100644 index 0000000..b83d9f2 Binary files /dev/null and b/src/main/resources/images/OriginalBomb3.gif differ diff --git a/src/main/resources/images/OriginalExit.gif b/src/main/resources/images/OriginalExit.gif new file mode 100644 index 0000000..bb64607 Binary files /dev/null and b/src/main/resources/images/OriginalExit.gif differ diff --git a/src/main/resources/images/OriginalMine.gif b/src/main/resources/images/OriginalMine.gif new file mode 100644 index 0000000..8b68f5d Binary files /dev/null and b/src/main/resources/images/OriginalMine.gif differ diff --git a/src/main/resources/images/OriginalMouse.gif b/src/main/resources/images/OriginalMouse.gif new file mode 100644 index 0000000..9fbaa65 Binary files /dev/null and b/src/main/resources/images/OriginalMouse.gif differ diff --git a/src/main/resources/images/OriginalMouse0.gif b/src/main/resources/images/OriginalMouse0.gif new file mode 100644 index 0000000..9fbaa65 Binary files /dev/null and b/src/main/resources/images/OriginalMouse0.gif differ diff --git a/src/main/resources/images/OriginalMouse1.gif b/src/main/resources/images/OriginalMouse1.gif new file mode 100644 index 0000000..5635409 Binary files /dev/null and b/src/main/resources/images/OriginalMouse1.gif differ diff --git a/src/main/resources/images/OriginalMouse2.gif b/src/main/resources/images/OriginalMouse2.gif new file mode 100644 index 0000000..e6a1fee Binary files /dev/null and b/src/main/resources/images/OriginalMouse2.gif differ diff --git a/src/main/resources/images/OriginalMouse3.gif b/src/main/resources/images/OriginalMouse3.gif new file mode 100644 index 0000000..26301b9 Binary files /dev/null and b/src/main/resources/images/OriginalMouse3.gif differ diff --git a/src/main/resources/images/OriginalMouse4.gif b/src/main/resources/images/OriginalMouse4.gif new file mode 100644 index 0000000..a120c73 Binary files /dev/null and b/src/main/resources/images/OriginalMouse4.gif differ diff --git a/src/main/resources/images/OriginalMouseMazeGameShot.gif b/src/main/resources/images/OriginalMouseMazeGameShot.gif new file mode 100644 index 0000000..fe1585f Binary files /dev/null and b/src/main/resources/images/OriginalMouseMazeGameShot.gif differ diff --git a/src/main/resources/images/OriginalMouseMazeHelp.gif b/src/main/resources/images/OriginalMouseMazeHelp.gif new file mode 100644 index 0000000..324ed36 Binary files /dev/null and b/src/main/resources/images/OriginalMouseMazeHelp.gif differ diff --git a/src/main/resources/images/OriginalMouseMazeLogo.gif b/src/main/resources/images/OriginalMouseMazeLogo.gif new file mode 100644 index 0000000..e2fe039 Binary files /dev/null and b/src/main/resources/images/OriginalMouseMazeLogo.gif differ diff --git a/src/main/resources/images/OriginalMouseMazeWin.gif b/src/main/resources/images/OriginalMouseMazeWin.gif new file mode 100644 index 0000000..db3a427 Binary files /dev/null and b/src/main/resources/images/OriginalMouseMazeWin.gif differ diff --git a/src/main/resources/images/OriginalPlayer.gif b/src/main/resources/images/OriginalPlayer.gif new file mode 100644 index 0000000..237af01 Binary files /dev/null and b/src/main/resources/images/OriginalPlayer.gif differ diff --git a/src/main/resources/images/OriginalRobot.gif b/src/main/resources/images/OriginalRobot.gif new file mode 100644 index 0000000..4d46528 Binary files /dev/null and b/src/main/resources/images/OriginalRobot.gif differ diff --git a/src/main/resources/images/OriginalRobot0.gif b/src/main/resources/images/OriginalRobot0.gif new file mode 100644 index 0000000..5e5d712 Binary files /dev/null and b/src/main/resources/images/OriginalRobot0.gif differ diff --git a/src/main/resources/images/OriginalRobot0shield1.gif b/src/main/resources/images/OriginalRobot0shield1.gif new file mode 100644 index 0000000..29e89a2 Binary files /dev/null and b/src/main/resources/images/OriginalRobot0shield1.gif differ diff --git a/src/main/resources/images/OriginalRobot0shield2.gif b/src/main/resources/images/OriginalRobot0shield2.gif new file mode 100644 index 0000000..dbe31bb Binary files /dev/null and b/src/main/resources/images/OriginalRobot0shield2.gif differ diff --git a/src/main/resources/images/OriginalRobot1.gif b/src/main/resources/images/OriginalRobot1.gif new file mode 100644 index 0000000..0b170e1 Binary files /dev/null and b/src/main/resources/images/OriginalRobot1.gif differ diff --git a/src/main/resources/images/OriginalRobot1shield1.gif b/src/main/resources/images/OriginalRobot1shield1.gif new file mode 100644 index 0000000..74a287c Binary files /dev/null and b/src/main/resources/images/OriginalRobot1shield1.gif differ diff --git a/src/main/resources/images/OriginalRobot1shield2.gif b/src/main/resources/images/OriginalRobot1shield2.gif new file mode 100644 index 0000000..0fed1f4 Binary files /dev/null and b/src/main/resources/images/OriginalRobot1shield2.gif differ diff --git a/src/main/resources/images/OriginalRobot2.gif b/src/main/resources/images/OriginalRobot2.gif new file mode 100644 index 0000000..09c1394 Binary files /dev/null and b/src/main/resources/images/OriginalRobot2.gif differ diff --git a/src/main/resources/images/OriginalRobot2shield1.gif b/src/main/resources/images/OriginalRobot2shield1.gif new file mode 100644 index 0000000..04d0065 Binary files /dev/null and b/src/main/resources/images/OriginalRobot2shield1.gif differ diff --git a/src/main/resources/images/OriginalRobot2shield2.gif b/src/main/resources/images/OriginalRobot2shield2.gif new file mode 100644 index 0000000..d994f39 Binary files /dev/null and b/src/main/resources/images/OriginalRobot2shield2.gif differ diff --git a/src/main/resources/images/OriginalRobot3.gif b/src/main/resources/images/OriginalRobot3.gif new file mode 100644 index 0000000..a05fd5a Binary files /dev/null and b/src/main/resources/images/OriginalRobot3.gif differ diff --git a/src/main/resources/images/OriginalRobot3shield1.gif b/src/main/resources/images/OriginalRobot3shield1.gif new file mode 100644 index 0000000..3ede296 Binary files /dev/null and b/src/main/resources/images/OriginalRobot3shield1.gif differ diff --git a/src/main/resources/images/OriginalRobot3shield2.gif b/src/main/resources/images/OriginalRobot3shield2.gif new file mode 100644 index 0000000..7ccb0b6 Binary files /dev/null and b/src/main/resources/images/OriginalRobot3shield2.gif differ diff --git a/src/main/resources/images/OriginalSkull.gif b/src/main/resources/images/OriginalSkull.gif new file mode 100644 index 0000000..52d2b4c Binary files /dev/null and b/src/main/resources/images/OriginalSkull.gif differ diff --git a/src/main/resources/images/PreferencesButton.gif b/src/main/resources/images/PreferencesButton.gif new file mode 100644 index 0000000..aee1601 Binary files /dev/null and b/src/main/resources/images/PreferencesButton.gif differ diff --git a/src/main/resources/images/QuitButton.gif b/src/main/resources/images/QuitButton.gif new file mode 100644 index 0000000..df8090b Binary files /dev/null and b/src/main/resources/images/QuitButton.gif differ diff --git a/src/main/resources/images/StartButton.gif b/src/main/resources/images/StartButton.gif new file mode 100644 index 0000000..b6ae110 Binary files /dev/null and b/src/main/resources/images/StartButton.gif differ diff --git a/src/main/resources/images/robot.gif b/src/main/resources/images/robot.gif new file mode 100644 index 0000000..54011ea Binary files /dev/null and b/src/main/resources/images/robot.gif differ diff --git a/src/main/resources/settings/default.properties b/src/main/resources/settings/default.properties new file mode 100644 index 0000000..f1a5e3e --- /dev/null +++ b/src/main/resources/settings/default.properties @@ -0,0 +1,14 @@ +animatedImages=true +bombsPerLevel=2 +fixedRobotShotRange=true +maxBombsPerLevel=5 +maxRobotShotRange=4 +maxRobotVisibilityRange=5 +robotMineFrequency=10 +robotShootFrequency=80 +robotShotRange=2 +robotVisibilityRange=4 +shootingMouse=true +unlimitedGameLevels=false +unlimitedLives=false +shieldedRobots=true \ No newline at end of file diff --git a/src/main/resources/settings/easy.properties b/src/main/resources/settings/easy.properties new file mode 100644 index 0000000..d414639 --- /dev/null +++ b/src/main/resources/settings/easy.properties @@ -0,0 +1,14 @@ +animatedImages=true +bombsPerLevel=1 +fixedRobotShotRange=true +maxBombsPerLevel=5 +maxRobotShotRange=4 +maxRobotVisibilityRange=5 +robotMineFrequency=5 +robotShootFrequency=30 +robotShotRange=1 +robotVisibilityRange=2 +shootingMouse=true +unlimitedGameLevels=false +unlimitedLives=false +shieldedRobots=false \ No newline at end of file diff --git a/src/main/resources/settings/hard.properties b/src/main/resources/settings/hard.properties new file mode 100644 index 0000000..a3e3250 --- /dev/null +++ b/src/main/resources/settings/hard.properties @@ -0,0 +1,14 @@ +animatedImages=true +bombsPerLevel=4 +fixedRobotShotRange=false +maxBombsPerLevel=5 +maxRobotShotRange=4 +maxRobotVisibilityRange=5 +robotMineFrequency=40 +robotShootFrequency=90 +robotShotRange=3 +robotVisibilityRange=4 +shootingMouse=true +unlimitedGameLevels=false +unlimitedLives=false +shieldedRobots=true diff --git a/src/main/resources/sounds/boing.wav b/src/main/resources/sounds/boing.wav new file mode 100644 index 0000000..a640363 Binary files /dev/null and b/src/main/resources/sounds/boing.wav differ diff --git a/src/main/resources/sounds/clickfast.wav b/src/main/resources/sounds/clickfast.wav new file mode 100644 index 0000000..8657d4e Binary files /dev/null and b/src/main/resources/sounds/clickfast.wav differ diff --git a/src/main/resources/sounds/explode.wav b/src/main/resources/sounds/explode.wav new file mode 100644 index 0000000..63f0389 Binary files /dev/null and b/src/main/resources/sounds/explode.wav differ diff --git a/src/main/resources/sounds/explosion.wav b/src/main/resources/sounds/explosion.wav new file mode 100644 index 0000000..1084c23 Binary files /dev/null and b/src/main/resources/sounds/explosion.wav differ diff --git a/src/main/resources/sounds/explosion2.wav b/src/main/resources/sounds/explosion2.wav new file mode 100644 index 0000000..442dc90 Binary files /dev/null and b/src/main/resources/sounds/explosion2.wav differ