1 package se
.umu
.cs
.dit06ajnajs
;
3 import java
.awt
.AlphaComposite
;
4 import java
.awt
.BorderLayout
;
6 import java
.awt
.Graphics2D
;
7 import java
.awt
.Graphics
;
9 import java
.awt
.event
.ActionListener
;
10 import java
.awt
.event
.MouseListener
;
11 import java
.awt
.event
.WindowListener
;
12 import java
.awt
.geom
.Rectangle2D
;
13 import java
.awt
.image
.BufferedImage
;
14 import java
.util
.logging
.Logger
;
16 import javax
.swing
.BoxLayout
;
17 import javax
.swing
.JComponent
;
18 import javax
.swing
.JFrame
;
19 import javax
.swing
.JLabel
;
20 import javax
.swing
.JMenu
;
21 import javax
.swing
.JMenuBar
;
22 import javax
.swing
.JMenuItem
;
23 import javax
.swing
.JOptionPane
;
24 import javax
.swing
.JPanel
;
25 import javax
.swing
.JTextArea
;
27 import java
.util
.EventListener
;
28 import javax
.swing
.JButton
;
29 import javax
.swing
.DefaultListModel
;
31 import se
.umu
.cs
.dit06ajnajs
.agent
.AgentPrototypeFactory
;
32 import javax
.swing
.JList
;
33 import javax
.swing
.ListSelectionModel
;
34 import se
.umu
.cs
.dit06ajnajs
.agent
.Unit
;
35 import javax
.swing
.SwingUtilities
;
37 import se
.umu
.cs
.dit06ajnajs
.level
.MapSquare
;
40 * ATDView is the view of this game, it creates a JFrame and fills it with
41 * menues and components that make up the entire interface of this game.
43 * @author Anton Johansson (dit06ajn@cs.umu.se)
44 * @author Andreas Jakobsson (dit06ajs@cs.umu.se)
47 public class ATDView
{
48 private static Logger logger
= Logger
.getLogger("AntiTD");
50 private ATDModel model
;
54 private JTextArea scoreboard
;
55 private JLabel messageLabel
;
56 //private JLabel scoreboard;
58 private GameComponent gameComponent
;
59 private Graphics2D gameGraphics
;
62 private JMenuItem newGameMenuItem
;
63 private JMenuItem restartLevelMenuItem
;
64 private JMenuItem pausMenuItem
;
65 private JMenuItem muteMenuItem
;
66 private JMenuItem quitMenuItem
;
67 private JMenuItem helpMenuItem
;
68 private JMenuItem aboutMenuItem
;
71 private JButton releaseUnitsButton
;
73 private JList unitList
;
76 * Creates a new <code>ATDView</code> instance. Saves the supplied model as
77 * a field and calls createAndShowGUI().
79 * @param model The model used for this game. Used to get information from.
81 public ATDView(ATDModel model
) {
87 * Create and show GUI used by this application.
89 private void createAndShowGUI() {
90 this.gameComponent
= new GameComponent();
92 JPanel mainPanel
= new JPanel(new BorderLayout());
94 mainPanel
.add(createControlPanel(), BorderLayout
.EAST
);
95 mainPanel
.add(createMenu(), BorderLayout
.NORTH
);
96 mainPanel
.add(gameComponent
, BorderLayout
.CENTER
);
98 this.frame
= new JFrame();
99 frame
.setTitle("AntiTD");
100 frame
.add(mainPanel
);
102 frame
.setVisible(true);
106 * Creates the JPanel containg Components to control the game.
108 * @return The JPanel containg Components to control the game.
110 private JPanel
createControlPanel() {
111 JPanel resultPanel
= new JPanel(new BorderLayout());
114 DefaultListModel unitTypesListModel
= new DefaultListModel();
115 AgentPrototypeFactory factory
= AgentPrototypeFactory
.getInstance();
116 for (String type
: factory
.getUnitTypes()) {
117 Unit unit
= factory
.createUnit(type
);
118 unitTypesListModel
.addElement(unit
);
120 this.unitList
= new JList(unitTypesListModel
);
121 unitList
.setSelectionMode(ListSelectionModel
.SINGLE_SELECTION
);
122 // Set one index as selected
123 unitList
.setSelectedIndex(0);
124 resultPanel
.add(unitList
, BorderLayout
.NORTH
);
126 JPanel shopPanel
= new JPanel();
128 shopPanel
.setLayout(new BoxLayout(shopPanel
, BoxLayout
.Y_AXIS
));
130 scoreboard
= new JTextArea("Credit:\t0\nScore:\t0\nCleared Units:\t0/0",1,10);
131 scoreboard
.setOpaque(false);
132 scoreboard
.setEditable(false);
135 this.messageLabel
= new JLabel();
136 resultPanel
.add(messageLabel
, BorderLayout
.CENTER
);
139 this.releaseUnitsButton
= new JButton("Release Units");
141 shopPanel
.add(scoreboard
);
142 shopPanel
.add(releaseUnitsButton
);
144 resultPanel
.add(shopPanel
, BorderLayout
.SOUTH
);
149 * Creates the MenuBar used by this application.
151 * @return The MenuBar used by this application.
153 private JMenuBar
createMenu() {
154 JMenuBar menubar
= new JMenuBar();
157 JMenu antiTDMenu
= new JMenu("AntiTD");
159 // TODO change name depending on if a game is running or not.
160 this.newGameMenuItem
= new JMenuItem("New Game");
161 antiTDMenu
.add(newGameMenuItem
);
163 this.restartLevelMenuItem
= new JMenuItem("Restart level");
164 antiTDMenu
.add(restartLevelMenuItem
);
166 this.pausMenuItem
= new JMenuItem("Pause");
167 antiTDMenu
.add(pausMenuItem
);
169 this.muteMenuItem
= new JMenuItem("Mute");
170 antiTDMenu
.add(muteMenuItem
);
172 this.quitMenuItem
= new JMenuItem("Quit");
173 antiTDMenu
.add(quitMenuItem
);
176 JMenu helpMenu
= new JMenu("Help");
178 this.helpMenuItem
= new JMenuItem("Help");
179 helpMenu
.add(helpMenuItem
);
181 this.aboutMenuItem
= new JMenuItem("About");
182 helpMenu
.add(aboutMenuItem
);
184 // Add menus to menubar
185 menubar
.add(antiTDMenu
);
186 menubar
.add(helpMenu
);
191 * Returns the Graphics used to update visual information about Agents in
194 * @return The Graphics used by Agents on the Level.
196 public Graphics
getGameGraphics() {
201 * Returns the type of the currently selected Unit.
203 * @return Type of the currently selected Unit.
205 public String
getSelectedUnitType() {
206 return ((Unit
) this.unitList
.getSelectedValue()).getType();
210 * Updates the backgroundimage used, for example when MapSquare are changed
213 public void updateBackgroundImage() {
214 this.gameComponent
.updateBackgroundImage();
218 * Updates the backgroundimage with new information from supplied MapSquare,
219 * for example when MapSquare are changed during gameplay.
221 * @param square A MapSquare with new informatin to be painted.
223 public void updateBackgroundImage(MapSquare square
) {
224 this.gameComponent
.updateBackgroundImage(square
);
228 * Calls repaint on the GameComponent.
230 public void repaintGame() {
231 gameComponent
.repaint();
235 * Update and repaint Pause menu information.
237 public void updatePauseMenu(final String TEXT
) {
238 SwingUtilities
.invokeLater(new Runnable() {
240 ATDView
.this.pausMenuItem
.setText(TEXT
);
246 * Update and repaint Pause menu information.
248 public void updateMuteMenu(final String TEXT
) {
249 SwingUtilities
.invokeLater(new Runnable() {
251 ATDView
.this.muteMenuItem
.setText(TEXT
);
257 * Prints a message to messageLabel, previous message is erased.
259 public void printMessage(final String TEXT
) {
260 SwingUtilities
.invokeLater(new Runnable() {
262 ATDView
.this.messageLabel
.setText(TEXT
);
268 * Updates the numbers on the scoreboard
270 public void updateScoreboard() {
271 SwingUtilities
.invokeLater(new Runnable() {
273 scoreboard
.setText("Credit:\t" + model
.getCredit() + "\n" +
274 "Score:\t" + model
.getScore() + "\n" +
275 "Cleared units:\t" + model
.getNumOfClearedUnits()
276 + "/" + model
.getUnitsToWin());
281 public String
promtForHighScoreEntry() {
282 String message
= "Want to send in a highscore, what's your username?";
283 String title
= "Enter highscore";
284 String result
= JOptionPane
.showInputDialog(
285 frame
, message
, title
, JOptionPane
.PLAIN_MESSAGE
);
290 * Prompts user to play next level or restart current level
291 * @return 0 for option next level
292 * @return 1 for option restart current level
294 public int showLevelCompleteDialog() {
295 String title
= "Level completed";
296 String message
= "Congratulations! You have completed this level.";
297 String
[] options
= new String
[2];
298 options
[0] = "Next level";
299 options
[1] = "Restart level";
301 int index
= JOptionPane
.showOptionDialog(frame
,
304 JOptionPane
.YES_NO_OPTION
,
305 JOptionPane
.QUESTION_MESSAGE
,
306 null, //do not use a custom Icon
307 options
, //the titles of buttons
308 options
[0]); //default button title
313 * Prompts user to start a new game or quit application
314 * @return 0 for option new game
315 * @return 1 for option quit application
318 public int showLevelLostDialog() {
319 String title
= "Level lost";
320 String message
= "You failed to complete the level.\n" +
321 "Play a new game or quit application";
322 String
[] options
= new String
[2];
323 options
[0] = "Play new game";
324 options
[1] = "Quit application";
326 int index
= JOptionPane
.showOptionDialog(frame
,
329 JOptionPane
.YES_NO_OPTION
,
330 JOptionPane
.QUESTION_MESSAGE
,
331 null, //do not use a custom Icon
332 options
, //the titles of buttons
333 options
[0]); //default button title
338 public void showAboutDialog() {
339 // TODO Auto-generated method stub
340 String title
= "About";
341 String message
= "*** Anti-tower Defence (alfa) ***" +
342 "\n\nCreated by:\n" +
343 "Andreas Jakobsson (dit06ajs@cs.umu.se)\n" +
344 "Anton Johansson (dit06ajn@cs.umu.se)";
345 JOptionPane
.showMessageDialog(frame
,
348 JOptionPane
.INFORMATION_MESSAGE
,
352 public void showHelpDialog() {
353 // TODO Auto-generated method stub
354 String title
= "Help";
355 JTextArea message
= new JTextArea("Instructions\n" +
356 "The goal for Anti-tower Defence is to release units " +
357 "from start squares in such a way that they reach goal " +
358 "squares without being killed by towers. When enough " +
359 "units has made it to goal squares you have completed " +
361 message
.setOpaque(false);
362 message
.setEditable(false);
363 message
.setLineWrap(true);
364 JOptionPane
.showMessageDialog(frame
,
367 JOptionPane
.INFORMATION_MESSAGE
,
372 * GameComponent is the componenent on which the Level and all Units and
375 private class GameComponent
extends JComponent
{
376 private Image backgroundImage
;
377 // TODO: Se if its possible to change to Image
378 private BufferedImage gameImage
;
383 public GameComponent() {
385 this.width
= (int) model
.getMapDimension().getWidth();
386 this.height
= (int) model
.getMapDimension().getHeight();
387 this.setPreferredSize(model
.getMapDimension());
390 this.backgroundImage
= model
.getMapImage();
393 this.gameImage
= new BufferedImage(width
, height
,
394 BufferedImage
.TYPE_INT_ARGB
);
395 ATDView
.this.gameGraphics
= gameImage
.createGraphics();
398 public void updateBackgroundImage() {
399 this.backgroundImage
= model
.getMapImage();
402 public void updateBackgroundImage(MapSquare square
) {
403 Graphics g
= this.backgroundImage
.getGraphics();
408 * Ovverrides standard paintComponent, used to only repaint information
409 * about Unit and Tower information.
411 * @param g The Graphics used to update visual information.
414 public void paintComponent(Graphics g
) {
415 logger
.fine("paintComponent: " + Thread
.currentThread().toString());
417 // Draw backgroundImage
418 g
.drawImage(backgroundImage
, 0, 0, null);
420 // Draw gameImage which should contain updated information from
422 g
.drawImage(gameImage
, 0, 0, null);
424 // Clear gameImage image with a big transparent rectangle.
425 Color transparent
= new Color(0, 0, 0, 0);
426 gameGraphics
.setColor(transparent
);
427 gameGraphics
.setComposite(AlphaComposite
.Src
);
428 gameGraphics
.fill(new Rectangle2D
.Double(0, 0, width
, height
));
432 /* Set Listener methods ******************************/
434 // TODO: Good way to not cast and not be to specific?
435 public void addClosingListener(EventListener el
) {
436 this.quitMenuItem
.addActionListener((ActionListener
) el
);
437 this.frame
.addWindowListener((WindowListener
) el
);
440 // Set menu item listeners
441 public void addNewGameMenuItemListener(ActionListener al
) {
442 this.newGameMenuItem
.addActionListener(al
);
445 public void addRestartLevelMenuItemListener(ActionListener al
) {
446 this.restartLevelMenuItem
.addActionListener(al
);
449 public void addPauseMenuItemListener(ActionListener al
) {
450 this.pausMenuItem
.addActionListener(al
);
453 public void addMuteMenuItemListener(ActionListener al
) {
454 this.muteMenuItem
.addActionListener(al
);
457 public void addHelpMenuItemListener(ActionListener al
) {
458 this.helpMenuItem
.addActionListener(al
);
461 public void addAboutMenuItemListener(ActionListener al
) {
462 this.aboutMenuItem
.addActionListener(al
);
466 public void addReleaseUnitListener(ActionListener al
) {
467 this.releaseUnitsButton
.addActionListener(al
);
470 public void addMapListener(MouseListener ml
) {
471 gameComponent
.addMouseListener(ml
);