1 | package jpacman.controller; |
2 | |
3 | import java.awt.Image; |
4 | import java.io.IOException; |
5 | import java.net.URL; |
6 | |
7 | import javax.swing.ImageIcon; |
8 | |
9 | /** |
10 | * The responsibilities of this class include obtaining images from file, |
11 | * that can be used for animations of the player and the monsters in Pacman. |
12 | * |
13 | * @author Arie van Deursen, Delft University of Technology, May 2007 |
14 | * @version $Id: ImageFactory.java,v 1.10 2008/02/04 09:59:28 arie Exp $ |
15 | * |
16 | */ |
17 | |
18 | public class ImageFactory { |
19 | |
20 | /** |
21 | * Animation sequence of images for monsters. |
22 | */ |
23 | private Image[] monsterImage; |
24 | |
25 | /** |
26 | * Animation sequence of images for the player. |
27 | */ |
28 | private Image[][] playerImage; |
29 | |
30 | /** |
31 | * Read images for player and monsters from file. |
32 | * Different images exist for different phases of the animation. |
33 | * @throws IOException if the images can't be found. |
34 | */ |
35 | public ImageFactory() throws IOException { |
36 | monsterImage = new Image[]{ |
37 | getImage("Ghost1.gif"), |
38 | getImage("Ghost2.gif") }; |
39 | |
40 | String[] sequence = new String[]{"2", "3", "4", "3", "2"}; |
41 | String[] direction = new String[]{ |
42 | "right", "left", "down", "up" }; |
43 | playerImage = new Image[direction.length][sequence.length + 1]; |
44 | for (int dir = 0; dir < direction.length; dir++) { |
45 | playerImage[dir][0] = getImage("PacMan1.gif"); |
46 | for (int seq = 0; seq < sequence.length; seq++) { |
47 | String name = "PacMan" + sequence[seq] |
48 | + direction[dir] + ".gif"; |
49 | playerImage[dir][seq + 1] = getImage(name); |
50 | } |
51 | } |
52 | assert invariant(); |
53 | } |
54 | |
55 | /** |
56 | * @return Number of different monster animation steps |
57 | */ |
58 | public int monsterAnimationCount() { |
59 | assert monsterImage != null; |
60 | int result = monsterImage.length; |
61 | assert result >= 0; |
62 | return result; |
63 | } |
64 | |
65 | /** |
66 | * @return Number of different player animation steps |
67 | */ |
68 | public int playerAnimationCount() { |
69 | assert playerImage != null; |
70 | assert playerImage[0] != null; |
71 | return playerImage[0].length; |
72 | } |
73 | |
74 | /** |
75 | * Invariant that may be a bit expensive to compute all the time, |
76 | * so it is selectively invoked. |
77 | * @return true iff invariant holds and all images are non-null. |
78 | */ |
79 | public boolean invariant() { |
80 | boolean result = monsterImage != null; |
81 | result = result && monsterImage.length > 0; |
82 | for (int i = 0; i < monsterImage.length; i++) { |
83 | result = result && monsterImage[i] != null; |
84 | } |
85 | result = result && playerImage != null; |
86 | result = result && playerImage[0] != null; |
87 | for (int i = 0; i < playerImage.length; i++) { |
88 | for (int j = 0; j < playerImage[i].length; j++) { |
89 | result = result && playerImage[i][j] != null; |
90 | } |
91 | } |
92 | return result; |
93 | } |
94 | |
95 | /** |
96 | * Get a player in (pizza slice) in the appropriate direction at the |
97 | * given animation sequence. |
98 | * @param dx x direction |
99 | * @param dy y direction |
100 | * @param anim Animation step |
101 | * @return Player image in appropriate direction. |
102 | */ |
103 | public Image player(int dx, int dy, int anim) { |
104 | assert anim >= 0; |
105 | anim = anim % playerAnimationCount(); |
106 | Image img = null; |
107 | int dirIndex = 0; |
108 | if (dx > 0) { |
109 | dirIndex = 0; |
110 | } else if (dx < 0) { |
111 | dirIndex = 1; |
112 | } else if (dy > 0) { |
113 | dirIndex = 2; |
114 | } else if (dy < 0) { |
115 | dirIndex = 3; |
116 | } else { |
117 | assert dx == 0; |
118 | assert dy == 0; |
119 | // stick to default name. |
120 | } |
121 | img = playerImage[dirIndex][anim]; |
122 | assert img != null; |
123 | return img; |
124 | } |
125 | |
126 | /** |
127 | * Obtain a picture of a monster. |
128 | * @param animationIndex counter indicating which animation to use. |
129 | * @return The monster image at the given animation index. |
130 | */ |
131 | public Image monster(int animationIndex) { |
132 | assert animationIndex >= 0; |
133 | animationIndex = animationIndex % monsterAnimationCount(); |
134 | return monsterImage[animationIndex]; |
135 | } |
136 | |
137 | /** |
138 | * Obtain an image from a file / resource that can |
139 | * be found on the classpath. |
140 | * @param name The file containg, e.g., a .gif picture. |
141 | * @return The corresponding Image. |
142 | * @throws IOException If file can't be found. |
143 | */ |
144 | private Image getImage(String name) throws IOException { |
145 | assert name != null; |
146 | URL picfile = getClass().getClassLoader().getResource(name); |
147 | if (picfile == null) { |
148 | throw new IOException("Can't load image: " + name); |
149 | } |
150 | Image result = (new ImageIcon(picfile)).getImage(); |
151 | assert result != null; |
152 | return result; |
153 | } |
154 | } |