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
;
39 public class ATDView
{
40 private static Logger logger
= Logger
.getLogger("AntiTD");
42 private ATDModel model
;
46 private JTextArea scoreboard
;
47 private JLabel messageLabel
;
48 //private JLabel scoreboard;
50 private GameComponent gameComponent
;
51 private Graphics2D gameGraphics
;
54 private JMenuItem newGameMenuItem
;
55 private JMenuItem restartLevelMenuItem
;
56 private JMenuItem pausMenuItem
;
57 private JMenuItem muteMenuItem
;
58 private JMenuItem quitMenuItem
;
59 private JMenuItem helpMenuItem
;
60 private JMenuItem aboutMenuItem
;
63 private JButton releaseUnitsButton
;
65 private JList unitList
;
67 public ATDView(ATDModel model
) {
73 * Create and show GUI used by this application.
75 private void createAndShowGUI() {
76 this.gameComponent
= new GameComponent();
78 JPanel mainPanel
= new JPanel(new BorderLayout());
80 mainPanel
.add(createControlPanel(), BorderLayout
.EAST
);
81 mainPanel
.add(createMenu(), BorderLayout
.NORTH
);
82 mainPanel
.add(gameComponent
, BorderLayout
.CENTER
);
84 this.frame
= new JFrame();
85 frame
.setTitle("AntiTD");
88 frame
.setVisible(true);
92 * Creates the JPanel containg Components to control the game.
94 * @return The JPanel containg Components to control the game.
96 private JPanel
createControlPanel() {
97 JPanel resultPanel
= new JPanel(new BorderLayout());
100 DefaultListModel unitTypesListModel
= new DefaultListModel();
101 AgentPrototypeFactory factory
= AgentPrototypeFactory
.getInstance();
102 for (String type
: factory
.getUnitTypes()) {
103 Unit unit
= factory
.createUnit(type
);
104 unitTypesListModel
.addElement(unit
);
106 this.unitList
= new JList(unitTypesListModel
);
107 unitList
.setSelectionMode(ListSelectionModel
.SINGLE_SELECTION
);
108 // Set one index as selected
109 unitList
.setSelectedIndex(0);
110 resultPanel
.add(unitList
, BorderLayout
.NORTH
);
112 JPanel shopPanel
= new JPanel();
114 shopPanel
.setLayout(new BoxLayout(shopPanel
, BoxLayout
.Y_AXIS
));
116 scoreboard
= new JTextArea("Credit:\t0\nScore:\t0\nCleared Units:\t0/0",1,10);
117 scoreboard
.setOpaque(false);
118 scoreboard
.setEditable(false);
121 this.messageLabel
= new JLabel();
122 resultPanel
.add(messageLabel
, BorderLayout
.CENTER
);
125 this.releaseUnitsButton
= new JButton("Release Units");
127 shopPanel
.add(scoreboard
);
128 shopPanel
.add(releaseUnitsButton
);
130 resultPanel
.add(shopPanel
, BorderLayout
.SOUTH
);
135 * Creates the MenuBar used by this application.
137 * @return The MenuBar used by this application.
139 private JMenuBar
createMenu() {
140 JMenuBar menubar
= new JMenuBar();
143 JMenu antiTDMenu
= new JMenu("AntiTD");
145 // TODO change name depending on if a game is running or not.
146 this.newGameMenuItem
= new JMenuItem("New Game");
147 antiTDMenu
.add(newGameMenuItem
);
149 this.restartLevelMenuItem
= new JMenuItem("Restart level");
150 antiTDMenu
.add(restartLevelMenuItem
);
152 this.pausMenuItem
= new JMenuItem("Pause");
153 antiTDMenu
.add(pausMenuItem
);
155 this.muteMenuItem
= new JMenuItem("Mute");
156 antiTDMenu
.add(muteMenuItem
);
158 this.quitMenuItem
= new JMenuItem("Quit");
159 antiTDMenu
.add(quitMenuItem
);
162 JMenu helpMenu
= new JMenu("Help");
164 this.helpMenuItem
= new JMenuItem("Help");
165 helpMenu
.add(helpMenuItem
);
167 this.aboutMenuItem
= new JMenuItem("About");
168 helpMenu
.add(aboutMenuItem
);
170 // Add menus to menubar
171 menubar
.add(antiTDMenu
);
172 menubar
.add(helpMenu
);
177 * Returns the Graphics used to update visual information about Agents in
180 * @return The Graphics used by Agents on the Level.
182 public Graphics
getGameGraphics() {
186 public String
getSelectedUnitType() {
187 return ((Unit
) this.unitList
.getSelectedValue()).getType();
191 * Updates the backgroundimage used, for example when MapSquare are changed
194 public void updateBackgroundImage() {
195 this.gameComponent
.updateBackgroundImage();
199 * Updates the backgroundimage with new information from supplied MapSquare,
200 * for example when MapSquare are changed during gameplay.
202 * @param square A MapSquare with new informatin to be painted.
204 public void updateBackgroundImage(MapSquare square
) {
205 this.gameComponent
.updateBackgroundImage(square
);
209 * Calls repaint on the GameComponent.
211 public void repaintGame() {
212 gameComponent
.repaint();
216 * Update and repaint Pause menu information.
218 public void updatePauseMenu(final String TEXT
) {
219 SwingUtilities
.invokeLater(new Runnable() {
221 ATDView
.this.pausMenuItem
.setText(TEXT
);
227 * Update and repaint Pause menu information.
229 public void updateMuteMenu(final String TEXT
) {
230 SwingUtilities
.invokeLater(new Runnable() {
232 ATDView
.this.muteMenuItem
.setText(TEXT
);
238 * Prints a message to messageLabel, previous message is erased.
240 public void printMessage(final String TEXT
) {
241 SwingUtilities
.invokeLater(new Runnable() {
243 ATDView
.this.messageLabel
.setText(TEXT
);
249 * Updates the numbers on the scoreboard
251 public void updateScoreboard() {
252 SwingUtilities
.invokeLater(new Runnable() {
254 scoreboard
.setText("Credit:\t" + model
.getCredit() + "\n" +
255 "Score:\t" + model
.getScore() + "\n" +
256 "Cleared units:\t" + model
.getNumOfClearedUnits()
257 + "/" + model
.getUnitsToWin());
262 public String
promtForHighScoreEntry() {
263 String message
= "Want to send in a highscore, what's your username?";
264 String title
= "Enter highscore";
265 String result
= JOptionPane
.showInputDialog(
266 frame
, message
, title
, JOptionPane
.PLAIN_MESSAGE
);
271 * Prompts user to play next level or restart current level
272 * @return 0 for option next level
273 * @return 1 for option restart current level
275 public int showLevelCompleteDialog() {
276 String title
= "Level completed";
277 String message
= "Congratulations! You have completed this level.";
278 String
[] options
= new String
[2];
279 options
[0] = "Next level";
280 options
[1] = "Restart level";
282 int index
= JOptionPane
.showOptionDialog(frame
,
285 JOptionPane
.YES_NO_OPTION
,
286 JOptionPane
.QUESTION_MESSAGE
,
287 null, //do not use a custom Icon
288 options
, //the titles of buttons
289 options
[0]); //default button title
294 * Prompts user to start a new game or quit application
295 * @return 0 for option new game
296 * @return 1 for option quit application
299 public int showLevelLostDialog() {
300 String title
= "Level lost";
301 String message
= "You failed to complete the level.\n" +
302 "Play a new game or quit application";
303 String
[] options
= new String
[2];
304 options
[0] = "Play new game";
305 options
[1] = "Quit application";
307 int index
= JOptionPane
.showOptionDialog(frame
,
310 JOptionPane
.YES_NO_OPTION
,
311 JOptionPane
.QUESTION_MESSAGE
,
312 null, //do not use a custom Icon
313 options
, //the titles of buttons
314 options
[0]); //default button title
319 public void showAboutDialog() {
320 // TODO Auto-generated method stub
321 String title
= "About";
322 String message
= "*** Anti-tower Defence (alfa) ***" +
323 "\n\nCreated by:\n" +
324 "Andreas Jakobsson (dit06ajs@cs.umu.se)\n" +
325 "Anton Johansson (dit06ajn@cs.umu.se)";
326 JOptionPane
.showMessageDialog(frame
,
329 JOptionPane
.INFORMATION_MESSAGE
,
333 public void showHelpDialog() {
334 // TODO Auto-generated method stub
335 String title
= "Help";
336 JTextArea message
= new JTextArea("Instructions\n" +
337 "The goal for Anti-tower Defence is to release units " +
338 "from start squares in such a way that they reach goal " +
339 "squares without being killed by towers. When enough " +
340 "units has made it to goal squares you have completed " +
342 message
.setOpaque(false);
343 message
.setEditable(false);
344 message
.setLineWrap(true);
345 JOptionPane
.showMessageDialog(frame
,
348 JOptionPane
.INFORMATION_MESSAGE
,
353 * GameComponent is the componenent on which the Level and all Units and
356 private class GameComponent
extends JComponent
{
357 private Image backgroundImage
;
358 // TODO: Se if its possible to change to Image
359 private BufferedImage gameImage
;
364 public GameComponent() {
366 this.width
= (int) model
.getMapDimension().getWidth();
367 this.height
= (int) model
.getMapDimension().getHeight();
368 this.setPreferredSize(model
.getMapDimension());
371 this.backgroundImage
= model
.getMapImage();
374 this.gameImage
= new BufferedImage(width
, height
,
375 BufferedImage
.TYPE_INT_ARGB
);
376 ATDView
.this.gameGraphics
= gameImage
.createGraphics();
379 public void updateBackgroundImage() {
380 this.backgroundImage
= model
.getMapImage();
383 public void updateBackgroundImage(MapSquare square
) {
384 Graphics g
= this.backgroundImage
.getGraphics();
389 * Ovverrides standard paintComponent, used to only repaint information
390 * about Unit and Tower information.
392 * @param g The Graphics used to update visual information.
395 public void paintComponent(Graphics g
) {
396 logger
.fine("paintComponent: " + Thread
.currentThread().toString());
398 g
.drawImage(backgroundImage
, 0, 0, null);
400 // Should contain updated information from Controller
401 g
.drawImage(gameImage
, 0, 0, null);
403 // Clear gameImage image with a big transparent rectangle.
404 Color transparent
= new Color(0, 0, 0, 0);
405 gameGraphics
.setColor(transparent
);
406 gameGraphics
.setComposite(AlphaComposite
.Src
);
407 gameGraphics
.fill(new Rectangle2D
.Double(0, 0, width
, height
));
411 /* Set Listener methods ******************************/
413 // TODO: Good way to not cast and not be to specific?
414 public void addClosingListener(EventListener el
) {
415 this.quitMenuItem
.addActionListener((ActionListener
) el
);
416 this.frame
.addWindowListener((WindowListener
) el
);
419 // Set menu item listeners
420 public void addNewGameMenuItemListener(ActionListener al
) {
421 this.newGameMenuItem
.addActionListener(al
);
424 public void addRestartLevelMenuItemListener(ActionListener al
) {
425 this.restartLevelMenuItem
.addActionListener(al
);
428 public void addPauseMenuItemListener(ActionListener al
) {
429 this.pausMenuItem
.addActionListener(al
);
432 public void addMuteMenuItemListener(ActionListener al
) {
433 this.muteMenuItem
.addActionListener(al
);
436 public void addHelpMenuItemListener(ActionListener al
) {
437 this.helpMenuItem
.addActionListener(al
);
440 public void addAboutMenuItemListener(ActionListener al
) {
441 this.aboutMenuItem
.addActionListener(al
);
445 public void addReleaseUnitListener(ActionListener al
) {
446 this.releaseUnitsButton
.addActionListener(al
);
449 public void addMapListener(MouseListener ml
) {
450 gameComponent
.addMouseListener(ml
);