Committing historical code from 2001 with minor tweaks to make function
in maven.
|
@ -0,0 +1,4 @@
|
||||||
|
/target/
|
||||||
|
/.classpath
|
||||||
|
/.project
|
||||||
|
/.settings/
|
After Width: | Height: | Size: 66 KiB |
After Width: | Height: | Size: 941 B |
After Width: | Height: | Size: 895 B |
After Width: | Height: | Size: 10 KiB |
After Width: | Height: | Size: 5.3 KiB |
After Width: | Height: | Size: 889 B |
After Width: | Height: | Size: 914 B |
After Width: | Height: | Size: 924 B |
After Width: | Height: | Size: 941 B |
After Width: | Height: | Size: 5.7 KiB |
|
@ -0,0 +1,46 @@
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<groupId>a2geek.games</groupId>
|
||||||
|
<artifactId>mouse-maze-2001</artifactId>
|
||||||
|
<version>1.9.0-FINAL</version>
|
||||||
|
<name>Mouse Maze 2001</name>
|
||||||
|
<description>A recreation of a game developed in 1983.</description>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.source>1.8</maven.compiler.source>
|
||||||
|
<maven.compiler.target>1.8</maven.compiler.target>
|
||||||
|
<maven.shade.version>2.4.3</maven.shade.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-shade-plugin</artifactId>
|
||||||
|
<version>${maven.shade.version}</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<phase>package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>shade</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<transformers>
|
||||||
|
<transformer
|
||||||
|
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
|
||||||
|
<manifestEntries>
|
||||||
|
<Main-Class>a2geek.games.mousemaze2001.MouseMaze2001</Main-Class>
|
||||||
|
<Implementation-Title>Mouse Maze 2001</Implementation-Title>
|
||||||
|
<Implementation-Version>${project.version}</Implementation-Version>
|
||||||
|
</manifestEntries>
|
||||||
|
</transformer>
|
||||||
|
</transformers>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
|
@ -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: <a href='mailto:greener@charter.net'>Rob Greene</a>
|
||||||
|
* @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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -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: <a href='mailto:greener@charter.net'>Rob Greene</a>
|
||||||
|
* @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<imageNames.length; i++) {
|
||||||
|
originalImages[i] = imageManager.getImage(imageNames[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// create scaled images (except #0)
|
||||||
|
MediaTracker tracker = new MediaTracker(this);
|
||||||
|
scaledImages = new Image[originalImages.length];
|
||||||
|
for (int i=0; i<originalImages.length; i++) {
|
||||||
|
Image scaled = originalImages[i];
|
||||||
|
int width = scaled.getWidth(null) / 2;
|
||||||
|
if (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<lines; i++) {
|
||||||
|
String line = story[i];
|
||||||
|
if (line.startsWith("&")) {
|
||||||
|
int shape = Integer.parseInt(line.substring(1))-1;
|
||||||
|
if (shape >= 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<keys.length; i++) {
|
||||||
|
String key = keys[i];
|
||||||
|
if (key != null) {
|
||||||
|
int width = metrics.stringWidth(key);
|
||||||
|
if (width > maxWidth) maxWidth = width;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int padding = 6;
|
||||||
|
for (int i=0; i<keys.length; i++) {
|
||||||
|
String key = keys[i];
|
||||||
|
if (key != null) {
|
||||||
|
int x0 = x + (i%3)*(maxWidth + padding*2);
|
||||||
|
g.setColor(new Color(0xafafaf));
|
||||||
|
g.fillRoundRect(x0-padding,y-padding,maxWidth+padding,fontHeight+padding,padding*2,padding*2);
|
||||||
|
g.setColor(Color.white);
|
||||||
|
g.drawRoundRect(x0-padding,y-padding,maxWidth+padding,fontHeight+padding,padding*2,padding*2);
|
||||||
|
g.setColor(Color.black);
|
||||||
|
int width = metrics.stringWidth(key);
|
||||||
|
x0 += (maxWidth - width) / 2;
|
||||||
|
g.drawString(key, x0-(padding/2), y+fontAscent-(padding/2));
|
||||||
|
if (i%3 == 2) {
|
||||||
|
y+= fontHeight + padding*2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
y+= fontHeight;
|
||||||
|
g.setColor(Color.blue);
|
||||||
|
title = "Press Escape to end game";
|
||||||
|
stringWidth = metrics.stringWidth(title);
|
||||||
|
g.drawString(title, (screenWidth - stringWidth) / 2, y);
|
||||||
|
y+= fontHeight;
|
||||||
|
title = "Press 'P' to pause the game";
|
||||||
|
stringWidth = metrics.stringWidth(title);
|
||||||
|
g.drawString(title, (screenWidth - stringWidth) / 2, y);
|
||||||
|
|
||||||
|
if (ticker > 1000) {
|
||||||
|
nextStage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void resetTicker() {
|
||||||
|
ticker= 0;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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: <a href='mailto:greener@charter.net'>Rob Greene</a>
|
||||||
|
* @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<maze.getMapWidth(); x++) {
|
||||||
|
int x0 = (screenWidth * x) / gridWidth + 2;
|
||||||
|
for (int y=0; y<maze.getMapHeight(); y++) {
|
||||||
|
int y0 = (screenHeight * y) / gridHeight + 2;
|
||||||
|
MazeObject object = maze.getMazeObject(x,y);
|
||||||
|
if (object != null) {
|
||||||
|
Graphics cell = g.create(x0,y0,cellWidth+1,cellHeight+1);
|
||||||
|
if (object instanceof AnimatedRobot) {
|
||||||
|
AnimatedRobot robot = (AnimatedRobot) object;
|
||||||
|
if (robot.isAlive() == false) continue;
|
||||||
|
}
|
||||||
|
object.paint(cell);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String message = maze.getPauseMessage();
|
||||||
|
if (maze.isPaused()) {
|
||||||
|
//System.out.println(new java.util.Date() + " - showing message = " + message);
|
||||||
|
Font font = new Font(g.getFont().getName(), Font.BOLD, 20);
|
||||||
|
g.setFont(font);
|
||||||
|
FontMetrics metrics = g.getFontMetrics();
|
||||||
|
int fontHeight = metrics.getAscent();
|
||||||
|
int stringWidth = metrics.stringWidth(message);
|
||||||
|
int xText = (screenWidth - stringWidth) / 2;
|
||||||
|
int yText = (screenHeight - fontHeight) / 2;
|
||||||
|
int xBox = xText - 15;
|
||||||
|
int yBox = yText - 15;
|
||||||
|
int xWidth = stringWidth + 30;
|
||||||
|
int yHeight = fontHeight + 30;
|
||||||
|
g.setColor(Color.blue);
|
||||||
|
g.fillRoundRect(xBox,yBox,xWidth,yHeight,15,15);
|
||||||
|
g.setColor(Color.white);
|
||||||
|
g.drawRoundRect(xBox,yBox,xWidth,yHeight,15,15);
|
||||||
|
g.setColor(Color.white);
|
||||||
|
g.drawString(message, xText, yText + fontHeight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
package a2geek.games.mousemaze2001;
|
||||||
|
import java.awt.*;
|
||||||
|
import javax.swing.*;
|
||||||
|
|
||||||
|
import a2geek.games.mousemaze2001.domain.*;
|
||||||
|
import a2geek.games.mousemaze2001.mazeobjects.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display the number of lives graphically.
|
||||||
|
*
|
||||||
|
* Creation date: (10/27/01 12:42:11 AM)
|
||||||
|
* @author: <a href='mailto:greener@charter.net'>Rob Greene</a>
|
||||||
|
* @version: RJG 10/27/2001 01:02:48
|
||||||
|
*/
|
||||||
|
public class MouseLivesPanel extends JPanel {
|
||||||
|
InvertedMouse mouse = new InvertedMouse();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MouseLivesPanel constructor comment.
|
||||||
|
*/
|
||||||
|
public MouseLivesPanel() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display the number of mouse lives.
|
||||||
|
*
|
||||||
|
* Creation date: (10/27/01 12:43:13 AM)
|
||||||
|
*/
|
||||||
|
public void paint(Graphics g) {
|
||||||
|
super.paint(g);
|
||||||
|
Rectangle rect = g.getClipBounds();
|
||||||
|
int lives = MazeDomain.getInstance().getLives();
|
||||||
|
for (int i=0; i<lives; i++) {
|
||||||
|
int x = mouse.getWidth() * i;
|
||||||
|
int y = ((int)rect.getHeight() - mouse.getHeight()) / 2;
|
||||||
|
Graphics mg = g.create(x,y,mouse.getWidth(),mouse.getHeight());
|
||||||
|
mouse.paint(mg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,535 @@
|
||||||
|
package a2geek.games.mousemaze2001;
|
||||||
|
import java.awt.*;
|
||||||
|
import javax.swing.*;
|
||||||
|
|
||||||
|
import a2geek.games.mousemaze2001.domain.*;
|
||||||
|
import a2geek.games.mousemaze2001.images.*;
|
||||||
|
import a2geek.games.mousemaze2001.threads.*;
|
||||||
|
|
||||||
|
import java.awt.event.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mouse Maze 2001!
|
||||||
|
*
|
||||||
|
* Creation date: (10/9/01 10:02:39 PM)
|
||||||
|
* @author: <a href='mailto:greener@charter.net'>Rob Greene</a>
|
||||||
|
* @version: RJG 11/05/2001 22:35:58
|
||||||
|
*/
|
||||||
|
public class MouseMaze2001 extends JFrame implements ActionListener, KeyListener, DomainListener {
|
||||||
|
private static MouseMaze2001 instance = new MouseMaze2001();
|
||||||
|
private static final String OK = "ok";
|
||||||
|
private static final String CANCEL = "cancel";
|
||||||
|
private static final String START = "start";
|
||||||
|
private static final String QUIT = "quit";
|
||||||
|
private static final String PREFERENCES = "preferences";
|
||||||
|
|
||||||
|
private JPanel infoPanel = null;
|
||||||
|
private CardLayout infoCardPages = null;
|
||||||
|
private JPanel infoCardPanel = null;
|
||||||
|
private JPanel logoPanel = null;
|
||||||
|
private JPanel controlPanel = null;
|
||||||
|
private JPanel gameInfoPanel = null;
|
||||||
|
private JPanel gameCardPanel = null;
|
||||||
|
private MouseLivesPanel mouseLivesPanel = null;
|
||||||
|
private JLabel robotsCountLabel = null;
|
||||||
|
private JLabel levelCountLabel = null;
|
||||||
|
private IntroPanel introPanel = null;
|
||||||
|
private MazeGridPanel mazePanel = null;
|
||||||
|
private CardLayout gameCardPages = null;
|
||||||
|
private IntroThread introThread = new IntroThread();
|
||||||
|
private GameThread gameThread = new GameThread();
|
||||||
|
private RepaintThread repaintThread = null;
|
||||||
|
private JPanel preferencesControlPanel = null;
|
||||||
|
private GameSettingsPanel gameSettingsPanel = null;
|
||||||
|
private ImageManager imageManager = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MouseMaze2001Layout constructor comment.
|
||||||
|
*/
|
||||||
|
public MouseMaze2001() {
|
||||||
|
Package pkg = getClass().getPackage();
|
||||||
|
String title = pkg.getImplementationTitle();
|
||||||
|
if (title == null) {
|
||||||
|
title = "Mouse Maze 2001";
|
||||||
|
}
|
||||||
|
String version = pkg.getImplementationVersion();
|
||||||
|
if (version == null) {
|
||||||
|
version = "PROTOTYPE";
|
||||||
|
}
|
||||||
|
setTitle(String.format("%s - %s", title, version));
|
||||||
|
|
||||||
|
setResizable(false);
|
||||||
|
setSize(500,200);
|
||||||
|
centerWindow();
|
||||||
|
|
||||||
|
ImageManager.getInstance(); // toggle image loading
|
||||||
|
getContentPane().add(new Component() {
|
||||||
|
public void paint(Graphics g) {
|
||||||
|
String message = "Please wait, loading images...";
|
||||||
|
int screenHeight = getHeight();
|
||||||
|
int screenWidth = getWidth();
|
||||||
|
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 + fontHeight;
|
||||||
|
g.setColor(Color.black);
|
||||||
|
g.fillRect(0,0,screenWidth,screenHeight);
|
||||||
|
g.setColor(Color.green);
|
||||||
|
g.drawString(message, x, y);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Thread thread = new Thread() {
|
||||||
|
public void run() {
|
||||||
|
ImageManager imageManager = ImageManager.getInstance();
|
||||||
|
while (imageManager.isDoneLoading() == false) {
|
||||||
|
try {
|
||||||
|
sleep(100);
|
||||||
|
} catch (InterruptedException ex) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
layoutScreen();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
thread.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invoked when an action occurs.
|
||||||
|
*/
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
String command = START; // default if called from elsewhere (yup, a hack)
|
||||||
|
MazeDomain domain = MazeDomain.getInstance();
|
||||||
|
if (e != null) {
|
||||||
|
command = e.getActionCommand();
|
||||||
|
}
|
||||||
|
if (START.equals(command)) {
|
||||||
|
if (introThread.isPaused()) {
|
||||||
|
gameThread.suspend();
|
||||||
|
introThread.resume();
|
||||||
|
gameCardPages.show(gameCardPanel, getPreviewPanelName());
|
||||||
|
infoCardPages.show(infoCardPanel, getPreviewPanelName());
|
||||||
|
domain.clear();
|
||||||
|
} else {
|
||||||
|
if (!gameThread.isRunning()) {
|
||||||
|
gameThread.start(); // yes, a total hack
|
||||||
|
gameThread.suspend();
|
||||||
|
domain.addDomainListener(this);
|
||||||
|
}
|
||||||
|
introThread.suspend();
|
||||||
|
gameThread.resume();
|
||||||
|
gameCardPages.show(gameCardPanel, getPlayPanelName());
|
||||||
|
infoCardPages.show(infoCardPanel, getPlayPanelName());
|
||||||
|
mazePanel.requestFocus();
|
||||||
|
domain.newGame();
|
||||||
|
if (domain.getGameSettings().isAnimatedImages()) {
|
||||||
|
AnimationThread animationThread = new AnimationThread();
|
||||||
|
animationThread.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (PREFERENCES.equals(command)) {
|
||||||
|
infoCardPages.show(infoCardPanel, getPreferencesPanelName());
|
||||||
|
gameCardPages.show(gameCardPanel, getPreferencesPanelName());
|
||||||
|
gameSettingsPanel.setCurrentSettings(MazeDomain.getInstance().getGameSettings());
|
||||||
|
} else if (OK.equals(command)) {
|
||||||
|
domain.setGameSettings(gameSettingsPanel.getCurrentSettings());
|
||||||
|
infoCardPages.show(infoCardPanel, getPreviewPanelName());
|
||||||
|
gameCardPages.show(gameCardPanel, getPreviewPanelName());
|
||||||
|
} else if (CANCEL.equals(command)) {
|
||||||
|
infoCardPages.show(infoCardPanel, getPreviewPanelName());
|
||||||
|
gameCardPages.show(gameCardPanel, getPreviewPanelName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Center the current window.
|
||||||
|
*
|
||||||
|
* Creation date: (10/31/01 10:02:47 PM)
|
||||||
|
*/
|
||||||
|
public void centerWindow() {
|
||||||
|
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
|
||||||
|
Dimension windowSize = getSize();
|
||||||
|
Point point = new Point();
|
||||||
|
point.x = (screenSize.width - windowSize.width) / 2;
|
||||||
|
point.y = (screenSize.height - windowSize.height) / 2;
|
||||||
|
setLocation(point);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected void createControlPanel() {
|
||||||
|
JButton startButton = createImageButton("StartButton.gif", START);
|
||||||
|
JButton preferencesButton = createImageButton("PreferencesButton.gif", PREFERENCES);
|
||||||
|
JPanel topButtons = new JPanel(new GridLayout(2,1));
|
||||||
|
topButtons.add(startButton);
|
||||||
|
topButtons.add(preferencesButton);
|
||||||
|
|
||||||
|
JButton quitButton = createImageButton("QuitButton.gif", QUIT, new WindowCloseAdapter());
|
||||||
|
|
||||||
|
controlPanel = new JPanel(new BorderLayout());
|
||||||
|
controlPanel.add(topButtons, BorderLayout.NORTH);
|
||||||
|
controlPanel.add(quitButton, BorderLayout.SOUTH);
|
||||||
|
controlPanel.setBackground(Color.white);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected void createGameInfoPanel() {
|
||||||
|
JLabel aHackForTheDamnFontName = new JLabel();
|
||||||
|
String theDamnFontName = aHackForTheDamnFontName.getFont().getName();
|
||||||
|
Font font = new Font(theDamnFontName, Font.BOLD, 20);
|
||||||
|
|
||||||
|
JLabel miceText = new JLabel("Mice:");
|
||||||
|
miceText.setFont(font);
|
||||||
|
miceText.setForeground(Color.blue);
|
||||||
|
JLabel levelText = new JLabel("Level:");
|
||||||
|
levelText.setFont(font);
|
||||||
|
levelText.setForeground(Color.blue);
|
||||||
|
JLabel robotsText = new JLabel("Robots:");
|
||||||
|
robotsText.setFont(font);
|
||||||
|
robotsText.setForeground(Color.blue);
|
||||||
|
|
||||||
|
mouseLivesPanel = new MouseLivesPanel();
|
||||||
|
mouseLivesPanel.setBackground(Color.white);
|
||||||
|
levelCountLabel = new JLabel("0");
|
||||||
|
levelCountLabel.setFont(font);
|
||||||
|
levelCountLabel.setForeground(Color.blue);
|
||||||
|
robotsCountLabel = new JLabel("0");
|
||||||
|
robotsCountLabel.setFont(font);
|
||||||
|
robotsCountLabel.setForeground(Color.blue);
|
||||||
|
|
||||||
|
gameInfoPanel = new JPanel(new GridLayout(3,2));
|
||||||
|
gameInfoPanel.add(miceText);
|
||||||
|
gameInfoPanel.add(mouseLivesPanel);
|
||||||
|
gameInfoPanel.add(levelText);
|
||||||
|
gameInfoPanel.add(levelCountLabel);
|
||||||
|
gameInfoPanel.add(robotsText);
|
||||||
|
gameInfoPanel.add(robotsCountLabel);
|
||||||
|
gameInfoPanel.setBackground(Color.white);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.getImage(resourceName)));
|
||||||
|
button.setActionCommand(commandString);
|
||||||
|
button.setBackground(Color.white);
|
||||||
|
button.addActionListener(actionListener);
|
||||||
|
return button;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected void createInfoPanel() {
|
||||||
|
createLogoPanel();
|
||||||
|
createControlPanel();
|
||||||
|
createGameInfoPanel();
|
||||||
|
createPreferencesControlPanel();
|
||||||
|
|
||||||
|
infoCardPages = new CardLayout();
|
||||||
|
infoCardPanel = new JPanel(infoCardPages);
|
||||||
|
infoCardPanel.add(getPreviewPanelName(), controlPanel);
|
||||||
|
infoCardPanel.add(getPlayPanelName(), gameInfoPanel);
|
||||||
|
infoCardPanel.add(getPreferencesPanelName(), preferencesControlPanel);
|
||||||
|
|
||||||
|
JPanel nestedPanel = new JPanel(new BorderLayout());
|
||||||
|
nestedPanel.setBackground(Color.white);
|
||||||
|
nestedPanel.add(logoPanel, BorderLayout.NORTH);
|
||||||
|
nestedPanel.add(infoCardPanel, BorderLayout.CENTER);
|
||||||
|
|
||||||
|
// apparantly these need to be separate panels...
|
||||||
|
JPanel dividerPanel = new JPanel();
|
||||||
|
dividerPanel.setBackground(Color.white);
|
||||||
|
JPanel dividerPanel2 = new JPanel();
|
||||||
|
dividerPanel2.setBackground(Color.white);
|
||||||
|
JPanel dividerPanel3 = new JPanel();
|
||||||
|
dividerPanel3.setBackground(Color.white);
|
||||||
|
JPanel dividerPanel4 = new JPanel();
|
||||||
|
dividerPanel4.setBackground(Color.white);
|
||||||
|
|
||||||
|
Dimension size = new Dimension(logoPanel.getWidth(), -1);
|
||||||
|
infoPanel = new JPanel(new BorderLayout());
|
||||||
|
infoPanel.setMaximumSize(size);
|
||||||
|
infoPanel.add(dividerPanel, BorderLayout.WEST);
|
||||||
|
infoPanel.add(dividerPanel2, BorderLayout.EAST);
|
||||||
|
infoPanel.add(dividerPanel3, BorderLayout.SOUTH);
|
||||||
|
infoPanel.add(dividerPanel4, BorderLayout.NORTH);
|
||||||
|
infoPanel.add(nestedPanel, BorderLayout.CENTER);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected void createLogoPanel() {
|
||||||
|
logoPanel = new JPanel(new FlowLayout());
|
||||||
|
ImageCanvas logo = new ImageCanvas("MouseMazeLogo.gif");
|
||||||
|
logo.setColor(Color.white);
|
||||||
|
logoPanel.add(logo);
|
||||||
|
logoPanel.setBackground(Color.white);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected void createPreferencesControlPanel() {
|
||||||
|
JButton okButton = createImageButton("OkButton.gif", OK);
|
||||||
|
JButton cancelButton = createImageButton("CancelButton.gif", CANCEL);
|
||||||
|
|
||||||
|
preferencesControlPanel = new JPanel(new BorderLayout());
|
||||||
|
preferencesControlPanel.add(okButton, BorderLayout.NORTH);
|
||||||
|
preferencesControlPanel.add(cancelButton, BorderLayout.SOUTH);
|
||||||
|
preferencesControlPanel.setBackground(Color.white);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Act upon domain changed events.
|
||||||
|
*
|
||||||
|
* Creation date: (10/22/01 10:06:09 PM)
|
||||||
|
*/
|
||||||
|
public void domainChanged(DomainEvent domainEvent) {
|
||||||
|
String event = domainEvent.getEvent();
|
||||||
|
MazeDomain domain = MazeDomain.getInstance();
|
||||||
|
if ("terminate".equals(event)) {
|
||||||
|
actionPerformed(null); // cheap game over
|
||||||
|
}
|
||||||
|
if ("robotShot".equals(event) || "newGame".equals(event)) {
|
||||||
|
robotsCountLabel.setText(Integer.toString(domain.getKills()));
|
||||||
|
robotsCountLabel.repaint();
|
||||||
|
}
|
||||||
|
if ("mouseKilled".equals(event)) {
|
||||||
|
mouseLivesPanel.repaint();
|
||||||
|
GameDelayThread thread = new GameDelayThread("Ouch!",500);
|
||||||
|
thread.start();
|
||||||
|
}
|
||||||
|
if ("level".equals(event)) {
|
||||||
|
//GameDelayThread thread = new GameDelayThread("Welcome to level " + domain.getLevel() + "!",1000);
|
||||||
|
//thread.start();
|
||||||
|
levelCountLabel.setText(Integer.toString(domain.getLevel()));
|
||||||
|
levelCountLabel.repaint();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ("newGame".equals(event)) {
|
||||||
|
GameDelayThread thread = new GameDelayThread("Good Luck!",500);
|
||||||
|
thread.start();
|
||||||
|
levelCountLabel.setText(Integer.toString(domain.getLevel()));
|
||||||
|
levelCountLabel.repaint();
|
||||||
|
mouseLivesPanel.repaint();
|
||||||
|
}
|
||||||
|
if ("gameOver".equals(event)) {
|
||||||
|
GameDelayThread thread = new GameDelayThread("Game Over",2000);
|
||||||
|
thread.start();
|
||||||
|
mouseLivesPanel.repaint();
|
||||||
|
} else if ("gameWon".equals(event)) {
|
||||||
|
GameDelayThread thread = new GameDelayThread("You have won Mouse Maze!",3000);
|
||||||
|
thread.start();
|
||||||
|
}
|
||||||
|
repaintNeeded();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static MouseMaze2001 getInstance() {
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected String getPlayPanelName() {
|
||||||
|
return "play";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected String getPreferencesPanelName() {
|
||||||
|
return "preferences";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected String getPreviewPanelName() {
|
||||||
|
return "preview";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invoked when a key has been pressed.
|
||||||
|
*/
|
||||||
|
public void keyPressed(KeyEvent e) {
|
||||||
|
switch (e.getKeyCode()) {
|
||||||
|
case KeyEvent.VK_LEFT:
|
||||||
|
MazeDomain.getInstance().moveMouse(-1,0);
|
||||||
|
repaintNeeded();
|
||||||
|
break;
|
||||||
|
case KeyEvent.VK_RIGHT:
|
||||||
|
MazeDomain.getInstance().moveMouse(1,0);
|
||||||
|
repaintNeeded();
|
||||||
|
break;
|
||||||
|
case KeyEvent.VK_UP:
|
||||||
|
MazeDomain.getInstance().moveMouse(0,-1);
|
||||||
|
repaintNeeded();
|
||||||
|
break;
|
||||||
|
case KeyEvent.VK_DOWN:
|
||||||
|
MazeDomain.getInstance().moveMouse(0,1);
|
||||||
|
repaintNeeded();
|
||||||
|
break;
|
||||||
|
case KeyEvent.VK_HOME:
|
||||||
|
MazeDomain.getInstance().moveMouse(-1,-1);
|
||||||
|
repaintNeeded();
|
||||||
|
break;
|
||||||
|
case KeyEvent.VK_PAGE_UP:
|
||||||
|
MazeDomain.getInstance().moveMouse(1,-1);
|
||||||
|
repaintNeeded();
|
||||||
|
break;
|
||||||
|
case KeyEvent.VK_END:
|
||||||
|
MazeDomain.getInstance().moveMouse(-1,1);
|
||||||
|
repaintNeeded();
|
||||||
|
break;
|
||||||
|
case KeyEvent.VK_PAGE_DOWN:
|
||||||
|
MazeDomain.getInstance().moveMouse(1,1);
|
||||||
|
repaintNeeded();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invoked when a key has been released.
|
||||||
|
*/
|
||||||
|
public void keyReleased(KeyEvent e) {
|
||||||
|
switch (e.getKeyCode()) {
|
||||||
|
case KeyEvent.VK_ESCAPE:
|
||||||
|
MazeDomain.getInstance().endGame();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invoked when a key has been typed.
|
||||||
|
* This event occurs when a key press is followed by a key release.
|
||||||
|
*/
|
||||||
|
public void keyTyped(KeyEvent e) {
|
||||||
|
char ch = Character.toUpperCase(e.getKeyChar());
|
||||||
|
MazeDomain domain = MazeDomain.getInstance();
|
||||||
|
int dx = 0;
|
||||||
|
int dy = 0;
|
||||||
|
if (domain.canMouseShoot()) {
|
||||||
|
switch (ch) {
|
||||||
|
case 'Q': dx = -1;
|
||||||
|
dy = -1;
|
||||||
|
break;
|
||||||
|
case 'W': dx = 0;
|
||||||
|
dy = -1;
|
||||||
|
break;
|
||||||
|
case 'E': dx = 1;
|
||||||
|
dy = -1;
|
||||||
|
break;
|
||||||
|
case 'A': dx = -1;
|
||||||
|
dy = 0;
|
||||||
|
break;
|
||||||
|
case 'D': dx = 1;
|
||||||
|
dy = 0;
|
||||||
|
break;
|
||||||
|
case 'Z': dx = -1;
|
||||||
|
dy = 1;
|
||||||
|
break;
|
||||||
|
case 'X': dx = 0;
|
||||||
|
dy = 1;
|
||||||
|
break;
|
||||||
|
case 'C': dx = 1;
|
||||||
|
dy = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
switch (ch) {
|
||||||
|
case 'P': if (domain.isPaused()) {
|
||||||
|
domain.setPause(null);
|
||||||
|
} else {
|
||||||
|
domain.setPause("Game is paused");
|
||||||
|
}
|
||||||
|
repaintNeeded();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (dx != 0 || dy != 0) {
|
||||||
|
Point pt = new Point(domain.getMouseLocation());
|
||||||
|
pt.translate(dx,dy);
|
||||||
|
if (domain.isValidPoint(pt)) {
|
||||||
|
Thread explosion = new ExplosionThread(pt);
|
||||||
|
explosion.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Layout the actual MouseMaze screen.
|
||||||
|
*
|
||||||
|
* Creation date: (10/31/01 9:38:13 PM)
|
||||||
|
*/
|
||||||
|
protected void layoutScreen() {
|
||||||
|
setVisible(false);
|
||||||
|
MazeDomain domain = MazeDomain.getInstance();
|
||||||
|
imageManager = ImageManager.getInstance();
|
||||||
|
|
||||||
|
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
|
||||||
|
addWindowListener(new WindowCloseAdapter());
|
||||||
|
|
||||||
|
createInfoPanel();
|
||||||
|
|
||||||
|
introPanel = IntroPanel.getInstance();
|
||||||
|
mazePanel = new MazeGridPanel();
|
||||||
|
gameSettingsPanel = new GameSettingsPanel();
|
||||||
|
gameCardPages = new CardLayout();
|
||||||
|
gameCardPanel = new JPanel(gameCardPages);
|
||||||
|
gameCardPanel.add(getPreviewPanelName(), introPanel);
|
||||||
|
gameCardPanel.add(getPlayPanelName(), mazePanel);
|
||||||
|
gameCardPanel.add(getPreferencesPanelName(), gameSettingsPanel);
|
||||||
|
|
||||||
|
getContentPane().removeAll();
|
||||||
|
getContentPane().setLayout(new BorderLayout());
|
||||||
|
getContentPane().add(BorderLayout.CENTER, gameCardPanel);
|
||||||
|
getContentPane().add(BorderLayout.EAST, infoPanel);
|
||||||
|
pack();
|
||||||
|
centerWindow();
|
||||||
|
setVisible(true);
|
||||||
|
|
||||||
|
mazePanel.addKeyListener(this);
|
||||||
|
|
||||||
|
introThread.start();
|
||||||
|
|
||||||
|
repaintThread = new RepaintThread(mazePanel);
|
||||||
|
repaintThread.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start the program
|
||||||
|
*
|
||||||
|
* Creation date: (10/9/01 10:04:11 PM)
|
||||||
|
* @param args java.lang.String[]
|
||||||
|
*/
|
||||||
|
public static void main(String[] args) {
|
||||||
|
instance.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tell the RepaintThread that a repaint is needed.
|
||||||
|
*
|
||||||
|
* Creation date: (10/24/01 9:20:23 PM)
|
||||||
|
*/
|
||||||
|
public void repaintNeeded() {
|
||||||
|
//System.out.println(new java.util.Date() + " - repaint requested");
|
||||||
|
repaintThread.repaintNeeded();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
package a2geek.games.mousemaze2001;
|
||||||
|
|
||||||
|
import java.awt.event.*;
|
||||||
|
import javax.swing.event.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generic adapter which shuts down the application.
|
||||||
|
* <p>
|
||||||
|
* Creation date: (10/6/01 11:29:16 PM)
|
||||||
|
* @author: <a href='mailto:greener@charter.net'>Rob Greene</a>
|
||||||
|
* @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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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: <a href='mailto:greener@charter.net'>Rob Greene</a>
|
||||||
|
* @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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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: <a href='mailto:greener@charter.net'>Rob Greene</a>
|
||||||
|
* @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);
|
||||||
|
}
|
|
@ -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: <a href='mailto:greener@charter.net'>Rob Greene</a>
|
||||||
|
* @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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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: <a href='mailto:greener@charter.net'>Rob Greene</a>
|
||||||
|
* @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<getMapWidth(); x++) {
|
||||||
|
for (int y=0; y<getMapHeight(); y++) {
|
||||||
|
MazeObject mazeObject = getMazeObject(x,y);
|
||||||
|
if (mazeObject != null && mazeObject.isExplosion()) return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// no explosions, check on mouse -- if dead, send terminate message
|
||||||
|
// yes, it is a bit of a hack.
|
||||||
|
if (getLives() <= 0) {
|
||||||
|
notifyDomainListeners("terminate");
|
||||||
|
}
|
||||||
|
// if we are at the end of the game, terminate also
|
||||||
|
if (!gameSettings.isUnlimitedGameLevels() && getLevel() > 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<robots.size(); i++) {
|
||||||
|
AnimatedRobot robot = (AnimatedRobot) robots.elementAt(i);
|
||||||
|
robot.kill();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// erase existing locations
|
||||||
|
robots = new Vector();
|
||||||
|
mousePoint = new Point();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the current map.
|
||||||
|
*
|
||||||
|
* Creation date: (10/14/01 9:35:25 PM)
|
||||||
|
*/
|
||||||
|
public void setMap(MazeObject[][] newMap) {
|
||||||
|
map = newMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Place a MazeObject into the map.
|
||||||
|
*
|
||||||
|
* Creation date: (10/30/01 9:37:53 PM)
|
||||||
|
*/
|
||||||
|
public synchronized void setMazeObject(int x, int y, MazeObject mazeObject) {
|
||||||
|
if (mazeObject == mouse) mousePoint.setLocation(x,y);
|
||||||
|
map[x][y] = mazeObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void setMazeObject(Point pt, MazeObject mazeObject) {
|
||||||
|
setMazeObject(pt.x,pt.y,mazeObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set maze size.
|
||||||
|
*
|
||||||
|
* Creation date: (10/14/01 9:56:04 PM)
|
||||||
|
*/
|
||||||
|
public void setMazeSize(int width, int height) {
|
||||||
|
mapWidth = width;
|
||||||
|
mapHeight = height;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void setPause(String message) {
|
||||||
|
//System.out.println(new java.util.Date() + " - pause message = " + message);
|
||||||
|
setPause(message != null);
|
||||||
|
pauseMessage = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the paused flag.
|
||||||
|
*
|
||||||
|
* Creation date: (11/5/01 10:20:27 PM)
|
||||||
|
*/
|
||||||
|
public void setPause(boolean pausedFlag) {
|
||||||
|
paused = pausedFlag;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the number of mouse lives.
|
||||||
|
*
|
||||||
|
* Creation date: (10/24/01 10:27:45 PM)
|
||||||
|
* @param newMice int
|
||||||
|
*/
|
||||||
|
public void setTotalMice(int newTotalMice) {
|
||||||
|
totalMice = newTotalMice;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shoot in a particular direction.
|
||||||
|
*
|
||||||
|
* Creation date: (10/22/01 11:12:01 PM)
|
||||||
|
*/
|
||||||
|
protected Point shoot(int dx, int dy) {
|
||||||
|
if (mousePoint == null) return null;
|
||||||
|
Point pt = new Point(mousePoint);
|
||||||
|
pt.translate(dx,dy);
|
||||||
|
return shoot(pt);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shoot at specified cell.
|
||||||
|
* This is used by the ExplosionThread when a Robot is hit.
|
||||||
|
*
|
||||||
|
* Creation date: (10/23/01 10:56:57 PM)
|
||||||
|
*/
|
||||||
|
public Point shoot(Point pt) {
|
||||||
|
if (!isPaused() && isValidPoint(pt)) {
|
||||||
|
MazeObject mazeObject = getMazeObject(pt);
|
||||||
|
if (mazeObject == null) {
|
||||||
|
// ignore these!
|
||||||
|
} else if (mazeObject.isRobot()) {
|
||||||
|
AnimatedRobot robot = (AnimatedRobot) mazeObject;
|
||||||
|
robot.decreaseShieldLevel();
|
||||||
|
if (robot.isAlive() == false) {
|
||||||
|
robots.remove(mazeObject);
|
||||||
|
setMazeObject(pt,null);
|
||||||
|
kills++;
|
||||||
|
notifyDomainListeners("robotShot");
|
||||||
|
}
|
||||||
|
} else if (mazeObject.isBomb()) {
|
||||||
|
setMazeObject(pt, null);
|
||||||
|
BombExplosionThread bombExplosion = new BombExplosionThread(pt);
|
||||||
|
bombExplosion.start();
|
||||||
|
} else if (mazeObject.isMouse()) {
|
||||||
|
if (!gameSettings.isUnlimitedLives()) lives--;
|
||||||
|
if (lives > 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; i<robots.size(); i++) {
|
||||||
|
AnimatedRobot robot = (AnimatedRobot) robots.elementAt(i);
|
||||||
|
setMazeObject(robot.getLocation(), robot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
package a2geek.games.mousemaze2001.images;
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.image.*;
|
||||||
|
|
||||||
|
import a2geek.games.mousemaze2001.images.*;
|
||||||
|
|
||||||
|
public class ImageCanvas extends Canvas {
|
||||||
|
private Image fImage;
|
||||||
|
private int fWidth;
|
||||||
|
private int fHeight;
|
||||||
|
private Color color;
|
||||||
|
public void setColor(Color newColor) {
|
||||||
|
color = newColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ImageCanvas(String filename) {
|
||||||
|
fImage = ImageManager.getInstance().getImage(filename);
|
||||||
|
|
||||||
|
if (fImage != null) {
|
||||||
|
fWidth = fImage.getWidth(this);
|
||||||
|
fHeight = fImage.getHeight(this);
|
||||||
|
} else {
|
||||||
|
fWidth = 20;
|
||||||
|
fHeight = 20;
|
||||||
|
}
|
||||||
|
setSize(fWidth, fHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void paint(Graphics g) {
|
||||||
|
paintBackground(g);
|
||||||
|
if (fImage != null) {
|
||||||
|
g.drawImage(fImage, 0, 0, fWidth, fHeight, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void paintBackground(java.awt.Graphics g) {
|
||||||
|
g.setColor(color);
|
||||||
|
g.fillRect(0, 0, getBounds().width, getBounds().height);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,137 @@
|
||||||
|
package a2geek.games.mousemaze2001.images;
|
||||||
|
import java.awt.image.ImageProducer;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.awt.Toolkit;
|
||||||
|
import java.awt.Image;
|
||||||
|
import java.awt.MediaTracker;
|
||||||
|
import java.util.*;
|
||||||
|
import java.io.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provide Image management for a system.
|
||||||
|
* This brings two benefits: All images are centrally located within this class and
|
||||||
|
* do not go away with a discarded class. The Image manager can be configured to preload
|
||||||
|
* images in a threaded background process.
|
||||||
|
* All images are keyed by filename.
|
||||||
|
*
|
||||||
|
* Creation date: (10/31/01 7:30:21 PM)
|
||||||
|
* @author: <a href='mailto:greener@charter.net'>Rob Greene</a>
|
||||||
|
* @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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
package a2geek.games.mousemaze2001.mazeobjects;
|
||||||
|
/**
|
||||||
|
* Provide an animated bomb.
|
||||||
|
*
|
||||||
|
* Creation date: (10/26/01 11:01:35 PM)
|
||||||
|
* @author: <a href='mailto:greener@charter.net'>Rob Greene</a>
|
||||||
|
* @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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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: <a href='mailto:greener@charter.net'>Rob Greene</a>
|
||||||
|
* @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; i<names.length; i++) {
|
||||||
|
images[i] = imageManager.getImage(names[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 abstract int getAnimationSequence();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Answers with the image names for this object.
|
||||||
|
*
|
||||||
|
* Creation date: (10/14/01 9:41:15 PM)
|
||||||
|
*/
|
||||||
|
protected abstract String[] getImageNames();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 (images == null) return;
|
||||||
|
int sequence = getAnimationSequence() % images.length;
|
||||||
|
Image image = images[sequence];
|
||||||
|
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, y, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
package a2geek.games.mousemaze2001.mazeobjects;
|
||||||
|
/**
|
||||||
|
* Represents the animated mouse.
|
||||||
|
*
|
||||||
|
* Creation date: (10/27/01 12:22:59 AM)
|
||||||
|
* @author: <a href='mailto:greener@charter.net'>Rob Greene</a>
|
||||||
|
* @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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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: <a href='mailto:greener@charter.net'>Rob Greene</a>
|
||||||
|
* @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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -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: <a href='mailto:greener@charter.net'>Rob Greene</a>
|
||||||
|
* @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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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: <a href='mailto:greener@charter.net'>Rob Greene</a>
|
||||||
|
* @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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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: <a href='mailto:greener@charter.net'>Rob Greene</a>
|
||||||
|
* @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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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: <a href='mailto:greener@charter.net'>Rob Greene</a>
|
||||||
|
* @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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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: <a href='mailto:greener@charter.net'>Rob Greene</a>
|
||||||
|
* @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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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: <a href='mailto:greener@charter.net'>Rob Greene</a>
|
||||||
|
* @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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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: <a href='mailto:greener@charter.net'>Rob Greene</a>
|
||||||
|
* @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) {
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
package a2geek.games.mousemaze2001.mazeobjects;
|
||||||
|
/**
|
||||||
|
* Represents a mine.
|
||||||
|
*
|
||||||
|
* Creation date: (10/22/01 11:23:56 PM)
|
||||||
|
* @author: <a href='mailto:greener@charter.net'>Rob Greene</a>
|
||||||
|
* @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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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: <a href='mailto:greener@charter.net'>Rob Greene</a>
|
||||||
|
* @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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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: <a href='mailto:greener@charter.net'>Rob Greene</a>
|
||||||
|
* @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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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: <a href='mailto:greener@charter.net'>Rob Greene</a>
|
||||||
|
* @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.
|
||||||
|
* <p>
|
||||||
|
* 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<size; i++) {
|
||||||
|
for (int dx=-i; dx<=i; dx++) {
|
||||||
|
for (int dy=-i; dy<=i; dy++) {
|
||||||
|
if (dx == i || dx == -i || dy == i || dy == -i) {
|
||||||
|
Point at = new Point(pt);
|
||||||
|
at.translate(dx,dy);
|
||||||
|
if (domain.isValidPoint(at)) {
|
||||||
|
ExplosionThread explosion = new ExplosionThread(at);
|
||||||
|
explosion.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sleep(delay);
|
||||||
|
}
|
||||||
|
} catch (InterruptedException ex) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,169 @@
|
||||||
|
package a2geek.games.mousemaze2001.threads;
|
||||||
|
/**
|
||||||
|
* A ControlledThread is a pseudo-Thread which allows thread-safe suspending/resuming and
|
||||||
|
* stoppping/restarting. Technically, this class implements runnable. All methods, except
|
||||||
|
* process are marked as final because it is assumed that you do not want to mess around
|
||||||
|
* with the threading.
|
||||||
|
* <p>
|
||||||
|
* To implement a pausable thread, extend the ControlledThread and implement process.
|
||||||
|
* Don't forget to set a default delay in your constructor, if appropriate!
|
||||||
|
* <p>
|
||||||
|
* Creation date: (10/20/01 9:08:13 PM)
|
||||||
|
* @author: <a href='mailto:greener@charter.net'>Rob Greene</a>
|
||||||
|
* @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.
|
||||||
|
* <p>
|
||||||
|
* 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.
|
||||||
|
* <p>
|
||||||
|
* 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.
|
||||||
|
* <p>
|
||||||
|
* Creation date: (10/20/01 10:21:07 PM)
|
||||||
|
*/
|
||||||
|
public final boolean isRunning() {
|
||||||
|
return running;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform the threadded process.
|
||||||
|
* <p>
|
||||||
|
* 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.
|
||||||
|
* <p>
|
||||||
|
* 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.
|
||||||
|
* <p>
|
||||||
|
* 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.
|
||||||
|
* <p>
|
||||||
|
* Creation date: (10/20/01 9:42:01 PM)
|
||||||
|
* @param newDelay long
|
||||||
|
*/
|
||||||
|
public final void setDelay(long newDelay) {
|
||||||
|
delay = newDelay;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start the thread.
|
||||||
|
* <p>
|
||||||
|
* 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.
|
||||||
|
* <p>
|
||||||
|
* Creation date: (10/20/01 10:24:46 PM)
|
||||||
|
*/
|
||||||
|
public synchronized final void stop() {
|
||||||
|
running = false;
|
||||||
|
notifyAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Suspend the thread.
|
||||||
|
* <p>
|
||||||
|
* Creation date: (10/20/01 10:24:58 PM)
|
||||||
|
*/
|
||||||
|
public final void suspend() {
|
||||||
|
paused = true;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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: <a href='mailto:greener@charter.net'>Rob Greene</a>
|
||||||
|
* @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.
|
||||||
|
* <p>
|
||||||
|
* Creation date: (10/23/01 10:08:07 PM)
|
||||||
|
*/
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
MazeDomain domain = MazeDomain.getInstance();
|
||||||
|
domain.shoot(pt);
|
||||||
|
for (int i=0; i<loops; i++) {
|
||||||
|
domain.setMazeObject(pt, new GreenTile());
|
||||||
|
MouseMaze2001.getInstance().repaintNeeded();
|
||||||
|
sleep(delay);
|
||||||
|
domain.setMazeObject(pt, new PurpleTile());
|
||||||
|
MouseMaze2001.getInstance().repaintNeeded();
|
||||||
|
sleep(delay);
|
||||||
|
}
|
||||||
|
domain.setMazeObject(pt, null);
|
||||||
|
// ensure map is put back in order... specifically, if the mouse
|
||||||
|
// was shot in its starting square, it needs to be placed there!
|
||||||
|
domain.synchronizeMap();
|
||||||
|
MouseMaze2001.getInstance().repaintNeeded();
|
||||||
|
} catch (InterruptedException ex) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
package a2geek.games.mousemaze2001.threads;
|
||||||
|
|
||||||
|
import a2geek.games.mousemaze2001.MouseMaze2001;
|
||||||
|
import a2geek.games.mousemaze2001.domain.MazeDomain;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This thread will pause the game for a short period of time, displaying a message
|
||||||
|
* on the screen.
|
||||||
|
*
|
||||||
|
* Creation date: (10/25/01 11:45:57 PM)
|
||||||
|
* @author: <a href='mailto:greener@charter.net'>Rob Greene</a>
|
||||||
|
* @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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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: <a href='mailto:greener@charter.net'>Rob Greene</a>
|
||||||
|
* @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.
|
||||||
|
* <p>
|
||||||
|
* Creation date: (10/21/01 2:00:35 PM)
|
||||||
|
*/
|
||||||
|
protected void process() {
|
||||||
|
MazeDomain.getInstance().explodeBombsRandomly();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
package a2geek.games.mousemaze2001.threads;
|
||||||
|
|
||||||
|
import a2geek.games.mousemaze2001.IntroPanel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Manage the Intro (demo) control thread.
|
||||||
|
* <p>
|
||||||
|
* Creation date: (10/20/01 9:08:13 PM)
|
||||||
|
* @author: <a href='mailto:greener@charter.net'>Rob Greene</a>
|
||||||
|
* @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".
|
||||||
|
* <p>
|
||||||
|
* Creation date: (10/20/01 10:25:15 PM)
|
||||||
|
*/
|
||||||
|
protected void process() {
|
||||||
|
IntroPanel introPanel = IntroPanel.getInstance();
|
||||||
|
introPanel.incrementTicker();
|
||||||
|
introPanel.repaint();
|
||||||
|
}
|
||||||
|
}
|
|
@ -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: <a href='mailto:greener@charter.net'>Rob Greene</a>
|
||||||
|
* @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; x<domain.getMapWidth(); x++) {
|
||||||
|
for (int y=0; y<domain.getMapHeight(); y++) {
|
||||||
|
domain.setMazeObject(x, y, greenTile);
|
||||||
|
controller.repaint();
|
||||||
|
sleep(delay);
|
||||||
|
domain.setMazeObject(x, y, purpleTile);
|
||||||
|
controller.repaint();
|
||||||
|
sleep(delay);
|
||||||
|
domain.setMazeObject(x, y, newMap[x][y]);
|
||||||
|
controller.repaint();
|
||||||
|
sleep(delay);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (InterruptedException ex) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
domain.setMap(newMap); // in case thread was interrupted
|
||||||
|
domain.setPause(null);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,98 @@
|
||||||
|
package a2geek.games.mousemaze2001.threads;
|
||||||
|
import java.awt.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A RepaintThread manages repainting of the screen. This gives all threads in a program
|
||||||
|
* the ability to repaint the screen without having multiple threads repainting at the same
|
||||||
|
* time. In addition, the RepaintThread will pause for a short period of time after a
|
||||||
|
* screen has been repainted to ensure that the CPU is not over-taxed.
|
||||||
|
*
|
||||||
|
* Creation date: (10/24/01 9:09:07 PM)
|
||||||
|
* @author: <a href='mailto:greener@charter.net'>Rob Greene</a>
|
||||||
|
* @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.
|
||||||
|
* <p>
|
||||||
|
* Creation date: (10/20/01 10:24:37 PM)
|
||||||
|
*/
|
||||||
|
public void start() {
|
||||||
|
thread.start();
|
||||||
|
}
|
||||||
|
}
|
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.1 KiB |
|
@ -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
|
After Width: | Height: | Size: 914 B |
After Width: | Height: | Size: 4.8 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 941 B |
After Width: | Height: | Size: 941 B |
After Width: | Height: | Size: 947 B |
After Width: | Height: | Size: 956 B |
After Width: | Height: | Size: 950 B |
After Width: | Height: | Size: 895 B |
After Width: | Height: | Size: 889 B |
After Width: | Height: | Size: 914 B |
After Width: | Height: | Size: 914 B |
After Width: | Height: | Size: 910 B |
After Width: | Height: | Size: 911 B |
After Width: | Height: | Size: 909 B |
After Width: | Height: | Size: 913 B |
After Width: | Height: | Size: 10 KiB |
After Width: | Height: | Size: 5.3 KiB |
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 5.7 KiB |
After Width: | Height: | Size: 903 B |
After Width: | Height: | Size: 924 B |
After Width: | Height: | Size: 926 B |
After Width: | Height: | Size: 979 B |
After Width: | Height: | Size: 979 B |
After Width: | Height: | Size: 931 B |
After Width: | Height: | Size: 979 B |
After Width: | Height: | Size: 979 B |
After Width: | Height: | Size: 933 B |
After Width: | Height: | Size: 979 B |
After Width: | Height: | Size: 979 B |
After Width: | Height: | Size: 927 B |
After Width: | Height: | Size: 976 B |
After Width: | Height: | Size: 976 B |
After Width: | Height: | Size: 941 B |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 6.2 KiB |
|
@ -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
|
|
@ -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
|
|
@ -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
|