Dev commited on 2018-07-21 10:16:11
Showing 12 changed files, with 1414 additions and 0 deletions.
... | ... |
@@ -0,0 +1,170 @@ |
1 |
+/* |
|
2 |
+ * ScreenManager.java |
|
3 |
+ * |
|
4 |
+ * Created on 30 March, 2007, 12:35 AM |
|
5 |
+ * |
|
6 |
+ * To change this template, choose Tools | Template Manager |
|
7 |
+ * and open the template in the editor. |
|
8 |
+ */ |
|
9 |
+ |
|
10 |
+/** |
|
11 |
+ * |
|
12 |
+ * @author |
|
13 |
+ */ |
|
14 |
+import java.awt.*; |
|
15 |
+import java.awt.image.BufferStrategy; |
|
16 |
+import java.awt.image.BufferedImage; |
|
17 |
+import javax.swing.JFrame; |
|
18 |
+ |
|
19 |
+/** |
|
20 |
+ The ScreenManager class manages initializing and displaying |
|
21 |
+ full screen graphics modes. |
|
22 |
+*/ |
|
23 |
+public class ScreenManager { |
|
24 |
+ |
|
25 |
+ private GraphicsDevice device; |
|
26 |
+ |
|
27 |
+ /** |
|
28 |
+ Creates a new ScreenManager object. |
|
29 |
+ */ |
|
30 |
+ public ScreenManager() { |
|
31 |
+ GraphicsEnvironment environment = |
|
32 |
+ GraphicsEnvironment.getLocalGraphicsEnvironment(); |
|
33 |
+ device = environment.getDefaultScreenDevice(); |
|
34 |
+ } |
|
35 |
+ |
|
36 |
+ |
|
37 |
+ /** |
|
38 |
+ Returns a list of compatible display modes for the |
|
39 |
+ default device on the system. |
|
40 |
+ */ |
|
41 |
+ public DisplayMode[] getCompatibleDisplayModes() { |
|
42 |
+ return device.getDisplayModes(); |
|
43 |
+ } |
|
44 |
+ |
|
45 |
+ |
|
46 |
+ /** |
|
47 |
+ Returns the current display mode. |
|
48 |
+ */ |
|
49 |
+ public DisplayMode getCurrentDisplayMode() { |
|
50 |
+ return device.getDisplayMode(); |
|
51 |
+ } |
|
52 |
+ |
|
53 |
+ /** |
|
54 |
+ Enters full screen mode and changes the display mode. |
|
55 |
+ If the specified display mode is null or not compatible |
|
56 |
+ with this device, or if the display mode cannot be |
|
57 |
+ changed on this system, the current display mode is used. |
|
58 |
+ <p> |
|
59 |
+ The display uses a BufferStrategy with 2 buffers. |
|
60 |
+ */ |
|
61 |
+ public void setFullScreen(DisplayMode displayMode) { |
|
62 |
+ JFrame frame = new JFrame("PuyoPuyo"); |
|
63 |
+ frame.setUndecorated(true); |
|
64 |
+ frame.setIgnoreRepaint(true); |
|
65 |
+ frame.setResizable(false); |
|
66 |
+ |
|
67 |
+ device.setFullScreenWindow(frame); |
|
68 |
+ if (displayMode != null && device.isDisplayChangeSupported()) |
|
69 |
+ { |
|
70 |
+ try { |
|
71 |
+ device.setDisplayMode(displayMode); |
|
72 |
+ } |
|
73 |
+ catch (IllegalArgumentException ex) { } |
|
74 |
+ } |
|
75 |
+ else{ |
|
76 |
+ System.out.println("Unable to switch to fullscreen... Exiting."); |
|
77 |
+ System.exit(1); |
|
78 |
+ } |
|
79 |
+ frame.createBufferStrategy(2); |
|
80 |
+ } |
|
81 |
+ |
|
82 |
+ |
|
83 |
+ /** |
|
84 |
+ Gets the graphics context for the display. The |
|
85 |
+ ScreenManager uses double buffering, so applications must |
|
86 |
+ call update() to show any graphics drawn. |
|
87 |
+ <p> |
|
88 |
+ The application must dispose of the graphics object. |
|
89 |
+ */ |
|
90 |
+ public Graphics2D getGraphics() { |
|
91 |
+ Window window = device.getFullScreenWindow(); |
|
92 |
+ if (window != null) { |
|
93 |
+ BufferStrategy strategy = window.getBufferStrategy(); |
|
94 |
+ return (Graphics2D)strategy.getDrawGraphics(); |
|
95 |
+ } |
|
96 |
+ else { |
|
97 |
+ return null; |
|
98 |
+ } |
|
99 |
+ } |
|
100 |
+ |
|
101 |
+ |
|
102 |
+ /** |
|
103 |
+ Updates the display. |
|
104 |
+ */ |
|
105 |
+ public void update() { |
|
106 |
+ Window window = device.getFullScreenWindow(); |
|
107 |
+ if (window != null) { |
|
108 |
+ BufferStrategy strategy = window.getBufferStrategy(); |
|
109 |
+ if (!strategy.contentsLost()) { |
|
110 |
+ strategy.show(); |
|
111 |
+ } |
|
112 |
+ } |
|
113 |
+ // Sync the display on some systems. |
|
114 |
+ // (on Linux, this fixes event queue problems) |
|
115 |
+ Toolkit.getDefaultToolkit().sync(); |
|
116 |
+ } |
|
117 |
+ |
|
118 |
+ |
|
119 |
+ /** |
|
120 |
+ Returns the window currently used in full screen mode. |
|
121 |
+ Returns null if the device is not in full screen mode. |
|
122 |
+ */ |
|
123 |
+ public Window getFullScreenWindow() { |
|
124 |
+ return device.getFullScreenWindow(); |
|
125 |
+ } |
|
126 |
+ |
|
127 |
+ |
|
128 |
+ /** |
|
129 |
+ Returns the width of the window currently used in full |
|
130 |
+ screen mode. Returns 0 if the device is not in full |
|
131 |
+ screen mode. |
|
132 |
+ */ |
|
133 |
+ public int getWidth() { |
|
134 |
+ Window window = device.getFullScreenWindow(); |
|
135 |
+ if (window != null) { |
|
136 |
+ return window.getWidth(); |
|
137 |
+ } |
|
138 |
+ else { |
|
139 |
+ return 0; |
|
140 |
+ } |
|
141 |
+ } |
|
142 |
+ |
|
143 |
+ |
|
144 |
+ /** |
|
145 |
+ Returns the height of the window currently used in full |
|
146 |
+ screen mode. Returns 0 if the device is not in full |
|
147 |
+ screen mode. |
|
148 |
+ */ |
|
149 |
+ public int getHeight() { |
|
150 |
+ Window window = device.getFullScreenWindow(); |
|
151 |
+ if (window != null) { |
|
152 |
+ return window.getHeight(); |
|
153 |
+ } |
|
154 |
+ else { |
|
155 |
+ return 0; |
|
156 |
+ } |
|
157 |
+ } |
|
158 |
+ |
|
159 |
+ |
|
160 |
+ /** |
|
161 |
+ Restores the screen's display mode. |
|
162 |
+ */ |
|
163 |
+ public void restoreScreen() { |
|
164 |
+ Window window = device.getFullScreenWindow(); |
|
165 |
+ if (window != null) { |
|
166 |
+ window.dispose(); |
|
167 |
+ } |
|
168 |
+ device.setFullScreenWindow(null); |
|
169 |
+ } |
|
170 |
+} |
|
0 | 171 |
\ No newline at end of file |
... | ... |
@@ -0,0 +1,516 @@ |
1 |
+/* |
|
2 |
+ * backEnd.java |
|
3 |
+ * |
|
4 |
+ * Created on 31 March, 2007, 11:42 PM |
|
5 |
+ * |
|
6 |
+ * To change this template, choose Tools | Template Manager |
|
7 |
+ * and open the template in the editor. |
|
8 |
+ */ |
|
9 |
+ |
|
10 |
+import java.util.Arrays; |
|
11 |
+import java.util.Comparator; |
|
12 |
+import java.util.HashSet; |
|
13 |
+import java.util.Iterator; |
|
14 |
+import java.util.Stack; |
|
15 |
+import java.util.Vector; |
|
16 |
+ |
|
17 |
+/** |
|
18 |
+ * Holds all the logic that drives the game. |
|
19 |
+ * <p>The main engine of the game is comprised of the following |
|
20 |
+ * four methods: |
|
21 |
+ * <ul> |
|
22 |
+ * <li>{@link puyopuyo.backEnd#popPuyos(puyo[]) popPuyos} - This acts as an entry point to {@link puyopuyo.frontEnd# frontEnd} to the logic of the game.</li> |
|
23 |
+ * <li>{@link puyopuyo.backEnd#probe(puyo) probe(puyo)} - It identifies the chain due to puyo passed to it as a parameter.</li> |
|
24 |
+ * <li>{@link puyopuyo.backEnd#popAndMarkDroppings(HashSet) popAndMarkDroppings} - It removes the puyo from {@link puyopuyo.backEnd#boardMap boardMap}</li> |
|
25 |
+ * and also marks the puyo which is to move down because of popping.</li> |
|
26 |
+ * <li>{@link puyopuyo.backEnd#settleDown(puyo) settleDown} - Moves down the puyo (and all those above it) to fill</li> |
|
27 |
+ * in the void created due to popping of puyo.</li> |
|
28 |
+ * </ul> |
|
29 |
+ * </p> |
|
30 |
+ * @author Dev Ghai |
|
31 |
+ */ |
|
32 |
+public class backEnd extends puyo{ |
|
33 |
+ |
|
34 |
+ /** |
|
35 |
+ * Creates a new instance of backEnd, initialises the board |
|
36 |
+ * and pushes a pair of puyos in {@link puyopuyo.backEnd#boardMap boardMap} using {@link puyopuyo.backEnd#pushPuyos() pushPuyos}. |
|
37 |
+ * {@link puyopuyo.backEnd#boardMap boardMap} is a two dimensional array that the heart of the game. It logically |
|
38 |
+ * represents the game's board in memory in form of an array whose width |
|
39 |
+ * is equal to {@link puyopuyo.backEnd#puyosOnXAxis puyosOnXAxis} and height is equal to {@link puyopuyo.backEnd#puyosOnYAxis puyosOnYAxis}. |
|
40 |
+ */ |
|
41 |
+ public backEnd() { |
|
42 |
+ for (int i = 0; i<puyosOnXAxis; i++) |
|
43 |
+ for(int j = 0; j<puyosOnYAxis; j++) |
|
44 |
+ boardMap[i][j] = null; //=> board is initially empty |
|
45 |
+ pushPuyos(); //and let the game begin! |
|
46 |
+ } |
|
47 |
+ //Clean and Build the Project to see the following 2 values take effect. |
|
48 |
+ /** |
|
49 |
+ * Holds the number of puyos on X Axis. Modify this value to effectively |
|
50 |
+ * change the size of the board. Logic has been made to depend on it. |
|
51 |
+ */ |
|
52 |
+ int puyosOnXAxis = 6; |
|
53 |
+ /** |
|
54 |
+ * Holds the number of puyos on Y Axis. Modify this value to effectively |
|
55 |
+ * change the size of the board. Logic has been made to depend on it. |
|
56 |
+ */ |
|
57 |
+ int puyosOnYAxis = 12; |
|
58 |
+ /** |
|
59 |
+ * Holds the minimum length of the chain in terms of puyos that will cause puyos |
|
60 |
+ * to be popped from the board. |
|
61 |
+ */ |
|
62 |
+ int popmin = 4; |
|
63 |
+ /** |
|
64 |
+ * Stores the pair of puyos pushed onto the board. |
|
65 |
+ */ |
|
66 |
+ private puyo puyoPair [] = new puyo[2]; |
|
67 |
+ /** |
|
68 |
+ * Returns a pair of puyos in form of an one dimensional array. |
|
69 |
+ */ |
|
70 |
+ public puyo[] getPuyoPair(){ |
|
71 |
+ return puyoPair; |
|
72 |
+ } |
|
73 |
+ /** |
|
74 |
+ * Integer value that holds the score of the game. Popping of one puyo |
|
75 |
+ * adds 10 to the current score. |
|
76 |
+ */ |
|
77 |
+ private int score = 0; |
|
78 |
+ /** |
|
79 |
+ * Returns the current score. {@link puyopuyo.backEnd#score score} is incremented by 10 points when |
|
80 |
+ * one puyo is popped. |
|
81 |
+ */ |
|
82 |
+ public int getScore(){ |
|
83 |
+ return score; |
|
84 |
+ } |
|
85 |
+ /** |
|
86 |
+ * A boolean value that tells whether the game is over or not. |
|
87 |
+ * |
|
88 |
+ * <p>This value is set in two cases - |
|
89 |
+ * <li> |
|
90 |
+ * <ol>When {@link puyopuyo.backEnd#pushPuyos() pushPuyos} is unable to push a pair on the board.</ol> |
|
91 |
+ * <ol>When the user hits the Esc key, i.e. s/he wants to exit from the game.</ol> |
|
92 |
+ * </li></p> |
|
93 |
+ */ |
|
94 |
+ private boolean gameOver = false; |
|
95 |
+ /** |
|
96 |
+ * Logically tells if the game is over or not by returning the (boolean) value |
|
97 |
+ * of {@link puyopuyo.backEnd#gameOver gameOver}. |
|
98 |
+ */ |
|
99 |
+ public boolean isGameOver(){ |
|
100 |
+ return gameOver; |
|
101 |
+ } |
|
102 |
+ |
|
103 |
+ /** |
|
104 |
+ * This method allows {@link puyopuyo.frontEnd# frontEnd} to set the gameOver to true. |
|
105 |
+ * <p>Game ends in two cases - |
|
106 |
+ * <ol><li>When {@link puyopuyo.backEnd#pushPuyos() pushPuyos} is unable to push a pair on the board.</li> |
|
107 |
+ * <li>When the user hits the Esc key, i.e. s/he wants to exit from the game.</li> |
|
108 |
+ * </ol></p> |
|
109 |
+ * @param status 'status' of the game to be copied to {@link gameOver}. |
|
110 |
+ */ |
|
111 |
+ public void setGameOver(boolean status){ |
|
112 |
+ gameOver = status; |
|
113 |
+ } |
|
114 |
+ /** |
|
115 |
+ * This two dimensional array is the heart of the game. It logically |
|
116 |
+ * represents the game's board in memory in form of an array whose width |
|
117 |
+ * is equal to {@link puyopuyo.backEnd#puyosOnXAxis puyosOnXAxis} and height is equal to {@link puyopuyo.backEnd#puyosOnYAxis puyosOnYAxis}. |
|
118 |
+ */ |
|
119 |
+ private puyo boardMap[][] = new puyo[puyosOnXAxis][puyosOnYAxis]; |
|
120 |
+ |
|
121 |
+ /** |
|
122 |
+ * Returns true if insertion successfully takes place in {@link puyopuyo.backEnd#boardMap boardMap}. |
|
123 |
+ * @param p Puyo to insert in boardMap |
|
124 |
+ * @param X X Co-ordinate of the insertion point. |
|
125 |
+ * @param Y Y co-ordinate of the insertion point. |
|
126 |
+ * @return Returns if the insertion was successful or not. |
|
127 |
+ */ |
|
128 |
+ private synchronized boolean insertInBoardMap(puyo p, int X, int Y){ |
|
129 |
+ /*If boardMap[X,Y] holds null => it is empty & the new point obeys |
|
130 |
+ * boundary conditions. Set the same and return true, |
|
131 |
+ * else that cell is filled or lies outside board, return false.*/ |
|
132 |
+ |
|
133 |
+ boolean newPointLiesOnBoard = (X>=0 & X<puyosOnXAxis) & (Y>=0 & Y<puyosOnYAxis); |
|
134 |
+ if(newPointLiesOnBoard && boardMap[X][Y]==null){ |
|
135 |
+ boardMap[X][Y] = p; |
|
136 |
+ return true; |
|
137 |
+ } |
|
138 |
+ //control will reach here only when the cell is previously filled or the point lies outside the board |
|
139 |
+ return false; |
|
140 |
+ } |
|
141 |
+ |
|
142 |
+ /** |
|
143 |
+ * Removes puyo from the {@link puyopuyo.backEnd#boardMap boardMap}. |
|
144 |
+ * @param X X co-ordinate in boardMap from which to remove puyo. |
|
145 |
+ * @param Y Y co-ordinate of boardMap from which to remove the puyo. |
|
146 |
+ */ |
|
147 |
+ private synchronized void removeFromBoardMap(int X, int Y){ |
|
148 |
+ boolean pointLiesOnBoard = (X>=0 & X<puyosOnXAxis) & (Y>=0 & Y<puyosOnYAxis); |
|
149 |
+ if (pointLiesOnBoard && boardMap[X][Y]!=null) |
|
150 |
+ boardMap[X][Y] = null; |
|
151 |
+ } |
|
152 |
+ |
|
153 |
+ /** |
|
154 |
+ * Returns {@link puyopuyo.backEnd#boardMap boardMap}. One of the main purposes of |
|
155 |
+ * this method is to provide a two dimensional array to {@link puyopuyo.frontEnd# frontEnd} |
|
156 |
+ * for printing the board onto screen. {@link puyopuyo.frontEnd#drawBoardMap() drawBoardMap} |
|
157 |
+ * uses this method to extract the logical {@link puyopuyo.backEnd#boardMap boardMap} and print |
|
158 |
+ * it onto the screen. |
|
159 |
+ * @return boardMap |
|
160 |
+ */ |
|
161 |
+ public puyo[][] getBoardMap(){ |
|
162 |
+ return boardMap; |
|
163 |
+ } |
|
164 |
+ /** |
|
165 |
+ * Generates a new {@link puyo# puyo} and randomly assigns color to the generated {@link puyo# puyo}. |
|
166 |
+ * @return A puyo with randomly generated colors. |
|
167 |
+ */ |
|
168 |
+ private puyo getNewPuyo(){ |
|
169 |
+ Math.random(); //initiate the random number generator by first call |
|
170 |
+ puyo p = new puyo(); //initialize p |
|
171 |
+ switch((int)(Math.random()*10)%4) { |
|
172 |
+ |
|
173 |
+ case 0: p = new puyo("./images/redPuyo.png", 'r'); //red puyo |
|
174 |
+ break; |
|
175 |
+ case 1: p = new puyo("./images/greenPuyo.png", 'g'); //green puyo |
|
176 |
+ break; |
|
177 |
+ case 2: p = new puyo("./images/bluePuyo.png", 'b'); //blue puyo |
|
178 |
+ break; |
|
179 |
+ case 3: p = new puyo("./images/yellowPuyo.png", 'y'); //yellow puyo |
|
180 |
+ } |
|
181 |
+ return p; |
|
182 |
+ } |
|
183 |
+ |
|
184 |
+ /** |
|
185 |
+ * Pushes a new pair of puyos in {@link puyopuyo.backEnd#boardMap boardMap} at the top of |
|
186 |
+ * the board. If no new pair can be pushed, {@link puyopuyo.backEnd#gameOver gameOver} is set true via {@link puyopuyo.backEnd#setGameOver(boolean) setGameOver}. |
|
187 |
+ */ |
|
188 |
+ |
|
189 |
+ |
|
190 |
+ |
|
191 |
+ public void pushPuyos(){ |
|
192 |
+ int centerX = (puyosOnXAxis-1)/2; |
|
193 |
+ if(boardMap[centerX][0]==null & boardMap[centerX+1][0]==null) { |
|
194 |
+ puyo p1 = getNewPuyo(); |
|
195 |
+ puyo p2 = getNewPuyo(); |
|
196 |
+ p1.setX(centerX); p1.setY(0); |
|
197 |
+ boardMap[centerX][0] = p1; |
|
198 |
+ p2.setX(++centerX); p2.setY(0); //centerX+1 causes second puyo to be printed over first puyo |
|
199 |
+ //Hence v c only 1 puyo when a pair is pushed on board. |
|
200 |
+ boardMap[centerX][0] = p2; |
|
201 |
+ puyoPair[0] = p1; |
|
202 |
+ puyoPair[1] = p2; |
|
203 |
+ } else |
|
204 |
+ setGameOver(true); //!! |
|
205 |
+ } |
|
206 |
+ /** |
|
207 |
+ * Moves the puyo passed as parameter one positon to left in {@link puyopuyo.backEnd#boardMap boardMap}. |
|
208 |
+ * It also updates the property of the puyo after successfully moving it. |
|
209 |
+ * @param p puyo to be moved left. |
|
210 |
+ * @return True if puyo was successfully moved and its property updated, else false |
|
211 |
+ */ |
|
212 |
+ public boolean moveLeft(puyo p){ |
|
213 |
+ boolean retVal; |
|
214 |
+ if( retVal = insertInBoardMap(p, p.getX() - 1, p.getY()) ){ |
|
215 |
+ removeFromBoardMap(p.getX(), p.getY()); |
|
216 |
+ p.setX(p.getX()-1); //update the puyo's property |
|
217 |
+ } |
|
218 |
+ return retVal; |
|
219 |
+ } |
|
220 |
+ |
|
221 |
+ /** |
|
222 |
+ * Moves the puyo passed as parameter one positon to right in {@link puyopuyo.backEnd#boardMap boardMap}. |
|
223 |
+ * It also updates the property of the puyo after successfully moving it. |
|
224 |
+ * @return True if puyo was successfully moved and its property updated, else false |
|
225 |
+ * @param p Puyo to be moved right. |
|
226 |
+ */ |
|
227 |
+ public boolean moveRight(puyo p){ |
|
228 |
+ boolean retVal; |
|
229 |
+ if( retVal = insertInBoardMap(p, p.getX() + 1, p.getY())){ |
|
230 |
+ removeFromBoardMap(p.getX(), p.getY()); |
|
231 |
+ p.setX(p.getX()+1); //update puyo's property |
|
232 |
+ } |
|
233 |
+ return retVal; |
|
234 |
+ } |
|
235 |
+ |
|
236 |
+ /** |
|
237 |
+ * Moves the puyo passed as parameter one positon down in {@link puyopuyo.backEnd#boardMap boardMap}. |
|
238 |
+ * It also updates the property of the puyo after successfully moving it. |
|
239 |
+ * @return True if puyo was successfully moved and its property updated, else false |
|
240 |
+ * @param p Puyo to be moved down. |
|
241 |
+ */ |
|
242 |
+ public boolean moveDown(puyo p){ |
|
243 |
+ /* while(boundary conditions are ok & next cell is empty) |
|
244 |
+ * The loop will exit when an attempt will be made to insert an imaginary |
|
245 |
+ * puyo above the topmost puyo. |
|
246 |
+ */ |
|
247 |
+ if( insertInBoardMap(p, p.getX(), p.getY()+1) ){ |
|
248 |
+ removeFromBoardMap(p.getX(), p.getY()); |
|
249 |
+ p.setY(p.getY()+1); |
|
250 |
+ return true; |
|
251 |
+ } |
|
252 |
+ return false; |
|
253 |
+ } |
|
254 |
+ |
|
255 |
+ /** |
|
256 |
+ * Rotates clockwise the puyo p[1] around p[0]. |
|
257 |
+ * <p><b>DETAILED DESCRIPTION:</b><br> |
|
258 |
+ * p[0] will always be the pivot around which p[1] will rotate<br> |
|
259 |
+ * Determine the orientation of the pair: HORIZONTAL or VERTICAL<br> |
|
260 |
+ * Determine position of p[1] : NORTH EAST SOUTH or WEST<br> |
|
261 |
+ * Move according to the determined position.<br> |
|
262 |
+ * Simple?? |
|
263 |
+ * </p> |
|
264 |
+ * @param p Pair of puyos to rotate. |
|
265 |
+ */ |
|
266 |
+ public void rotate(puyo[] p){ |
|
267 |
+ //only a pair can be rotated |
|
268 |
+ if (p[0].getY()==p[1].getY()){ |
|
269 |
+ //=>lie in same row |
|
270 |
+ if(p[1].getX() == p[0].getX() + 1){ |
|
271 |
+ //p[1] is on right => move p[1] SOUTH |
|
272 |
+ if(insertInBoardMap(p[1], p[0].getX(), p[0].getY()+1)){ |
|
273 |
+ //the cell below p[0] is empty & successful move has taken place |
|
274 |
+ //nullify previous position and update the status of puyo p[1] |
|
275 |
+ boardMap[p[1].getX()][p[1].getY()] = null; |
|
276 |
+ p[1].setX(p[0].getX()); p[1].setY(p[0].getY()+1); |
|
277 |
+ } |
|
278 |
+ } else if(p[0].getX() == p[1].getX() + 1) { |
|
279 |
+ //p[1] is on the left => move p[1] NORTH |
|
280 |
+ if(insertInBoardMap(p[1], p[0].getX(), p[0].getY()-1)){ |
|
281 |
+ boardMap[p[1].getX()][p[1].getY()] = null; |
|
282 |
+ p[1].setX(p[0].getX()); p[1].setY(p[0].getY()-1); |
|
283 |
+ } |
|
284 |
+ } |
|
285 |
+ }// horizontal case ends here |
|
286 |
+ else if(p[0].getX() == p[1].getX()){ |
|
287 |
+ //=> lie in the same column |
|
288 |
+ if(p[0].getY() == p[1].getY() + 1){ |
|
289 |
+ //p[1] is above p[0] => move p[1] EAST |
|
290 |
+ if(insertInBoardMap(p[1], p[0].getX()+1, p[0].getY())){ |
|
291 |
+ boardMap[p[1].getX()][p[1].getY()] = null; |
|
292 |
+ p[1].setX(p[0].getX() + 1); p[1].setY(p[0].getY()); |
|
293 |
+ } |
|
294 |
+ } else if(p[1].getY() == p[0].getY()+1){ |
|
295 |
+ //p[1] is below p[0] => move p[1] WEST |
|
296 |
+ if(insertInBoardMap(p[1], p[0].getX()-1, p[0].getY())){ |
|
297 |
+ boardMap[p[1].getX()][p[1].getY()] = null; |
|
298 |
+ p[1].setX(p[0].getX() - 1); p[1].setY(p[0].getY()); |
|
299 |
+ } |
|
300 |
+ } |
|
301 |
+ } |
|
302 |
+ }// end of the function |
|
303 |
+ |
|
304 |
+ /** |
|
305 |
+ * Holds all the puyos to be removed from the {@link puyopuyo.backEnd#boardMap boardMap} due to them forming a chain |
|
306 |
+ * of {@link puyopuyo.backEnd#popmin popmin} length. |
|
307 |
+ */ |
|
308 |
+ private Stack puyosToBePopped = new Stack(); |
|
309 |
+ /** |
|
310 |
+ * Holds the next set of puyos which have to be settled down and then checks |
|
311 |
+ * have to be made once they cannot move downwards anymore. |
|
312 |
+ */ |
|
313 |
+ private Stack nextSetOfPuyos = new Stack(); |
|
314 |
+ /** |
|
315 |
+ * It is the entry point for {@link puyopuyo.frontEnd# frontEnd}. |
|
316 |
+ * |
|
317 |
+ * <p>It also acts as 'manager', controlling the three methods that comprise the core logic: |
|
318 |
+ * <ul> |
|
319 |
+ * <li>{@link puyopuyo.backEnd#probe(puyo) probe(puyo)}</li> |
|
320 |
+ * <li>{@link puyopuyo.backEnd#popAndMarkDroppings(HashSet) popAndMarkDroppings(HashSet)}</li> |
|
321 |
+ * <li>{@link puyopuyo.backEnd#settleDown(puyo) settleDown(puyo)}</li> |
|
322 |
+ * </ul></p> |
|
323 |
+ * @param p Puyo for which chain has to be identified and popped from the board. |
|
324 |
+ */ |
|
325 |
+ public synchronized void popPuyos(puyo p[]){ |
|
326 |
+ //both of the puyos in the pair have settled down, check can begin with any puyo |
|
327 |
+ |
|
328 |
+ if(p.length == 0) return; //termination condition for recursion. no more puyos available to work on |
|
329 |
+ HashSet marked = new HashSet(); |
|
330 |
+ puyo[] temp; |
|
331 |
+ for(int i = 0; i<p.length; i++){ |
|
332 |
+ marked = probe(p[i]); |
|
333 |
+ if(marked.size()>=popmin) |
|
334 |
+ puyosToBePopped.push(new HashSet(marked)); |
|
335 |
+ marked.clear(); |
|
336 |
+ } |
|
337 |
+ |
|
338 |
+ while(!puyosToBePopped.isEmpty()){ |
|
339 |
+ temp = popAndMarkDroppings((HashSet)puyosToBePopped.pop()); |
|
340 |
+ if(temp.length > 0) |
|
341 |
+ nextSetOfPuyos.push(temp); |
|
342 |
+ } |
|
343 |
+ |
|
344 |
+ Iterator scan = nextSetOfPuyos.iterator();//iterator doesn't remove from stack. Popping is done in next loop |
|
345 |
+ while(scan.hasNext()){ |
|
346 |
+ temp = (puyo[])scan.next(); |
|
347 |
+ /*puyos are sorted in ascending order of getY() [popAndMarkDroppings returns a sorted array]. |
|
348 |
+ * The ones with greater value of Y need to be moved down before others otherwise they'll |
|
349 |
+ * block the path of puyos above them... eventually leaving some puyos hanging in mid air. |
|
350 |
+ */ |
|
351 |
+ for(int i=temp.length -1; i>=0; i--) |
|
352 |
+ settleDown(temp[i]); |
|
353 |
+ } |
|
354 |
+ while(!nextSetOfPuyos.isEmpty()) |
|
355 |
+ popPuyos((puyo[])nextSetOfPuyos.pop()); |
|
356 |
+ } |
|
357 |
+ |
|
358 |
+ /** |
|
359 |
+ * Settles the puyo passed as parameter down to the floor and also all the puyos above it. |
|
360 |
+ * @param p Puyo to be moved down. |
|
361 |
+ */ |
|
362 |
+ private synchronized void settleDown(puyo p){ |
|
363 |
+ int xPos = p.getX(); |
|
364 |
+ int yPos = p.getY(); |
|
365 |
+ //xPos and yPos are modified, xCopy and yCopy are used to check termination condition for recursion. |
|
366 |
+ while(p!=null && insertInBoardMap(p, xPos, yPos+1)){ |
|
367 |
+ p.setY(yPos+1); |
|
368 |
+ removeFromBoardMap(xPos, yPos); |
|
369 |
+ yPos++; |
|
370 |
+ } |
|
371 |
+ } |
|
372 |
+ |
|
373 |
+ |
|
374 |
+ /** |
|
375 |
+ * Holds the puyos to be popped from {@link puyopuyo.backEnd#boardMap boardMap} as they form chains of length >= {@link puyopuyo.backEnd#popmin popmin}. |
|
376 |
+ */ |
|
377 |
+ private HashSet removePuyos = new HashSet(); |
|
378 |
+ |
|
379 |
+ /** |
|
380 |
+ * Returns the set of puyos to be moved down because of chains formed by |
|
381 |
+ * puyo, being passed as the argument. |
|
382 |
+ * @param p Puyo for which chains on the board have to be identified. |
|
383 |
+ * @return Set of puyos to be removed from the boardMap. |
|
384 |
+ */ |
|
385 |
+ private synchronized HashSet probe(puyo p){ |
|
386 |
+ |
|
387 |
+ removePuyos.add(p); //****mark the puyo for which checks have to be done |
|
388 |
+ |
|
389 |
+ |
|
390 |
+ int nextX = p.getX(), nextY = p.getY(); |
|
391 |
+ int directions[]={-1, +1}; |
|
392 |
+ |
|
393 |
+ /* Description of the following loop: |
|
394 |
+ * This method is called recursively and proceeds forward in the correct |
|
395 |
+ * direction. Correct direction here is defined as that direction where |
|
396 |
+ * a puyo with same color exists. procession is done by calling the same |
|
397 |
+ * function with the new puyo (stored in temp). |
|
398 |
+ * First it probes the one to left and proceeds in that direction, if |
|
399 |
+ * there's a proper match. Then the one to right is checked. The above |
|
400 |
+ * 2 activities are done in the first for loop. |
|
401 |
+ * Likewise, the second for loop checks first below current puyo and |
|
402 |
+ * then the puyo above it. |
|
403 |
+ * In both the loops, if a matching puyo exists above, below or to left |
|
404 |
+ * or right, the MATCHED puyo is added to the Set which holds the *unique* |
|
405 |
+ * puyos to be removed. Then the control passes onto MATCHED puyo. |
|
406 |
+ * Because the set holds unique values only, the control doesnot allow |
|
407 |
+ * probing to proceed in direction of puyo already matched. Hence the |
|
408 |
+ * control finally goes towards any uncharted direction. |
|
409 |
+ * MATCHED puyo is added because when we reach end of a chain, the last |
|
410 |
+ * puyo in a chain will not be added because the puyo from which the |
|
411 |
+ * control came will already be in the set, hence not allowing the last |
|
412 |
+ * matched puyo to be added to the set. |
|
413 |
+ */ |
|
414 |
+ for (int i = 0 ; i < directions.length; i++){ |
|
415 |
+ nextX = p.getX()+directions[i]; |
|
416 |
+ if( (nextX >= 0 & nextX < puyosOnXAxis) && boardMap[nextX][nextY]!=null){ //boundary conditions |
|
417 |
+ if(p.getColor()==boardMap[nextX][nextY].getColor()){ |
|
418 |
+ if(removePuyos.add(boardMap[nextX][nextY])) |
|
419 |
+ //successful addition => temp has not been parsed previously, add it to set |
|
420 |
+ probe(boardMap[nextX][nextY]); //proceed forward with the check in its direction |
|
421 |
+ } |
|
422 |
+ } |
|
423 |
+ } |
|
424 |
+ nextX = p.getX(); //nextX was changed by above loop |
|
425 |
+ for (int i = 0 ; i < directions.length; i++){ |
|
426 |
+ nextY = p.getY()+directions[i]; |
|
427 |
+ if( (nextY >= 0 & nextY < puyosOnYAxis) && boardMap[nextX][nextY]!=null){ //boundary conditions |
|
428 |
+ if(p.getColor()==boardMap[nextX][nextY].getColor()){ |
|
429 |
+ if(removePuyos.add(boardMap[nextX][nextY])) |
|
430 |
+ //successful addition => temp has not been parsed previously, add it to set |
|
431 |
+ probe(boardMap[nextX][nextY]); //proceed forward with the check in temp puyo's direction |
|
432 |
+ } |
|
433 |
+ }//end of if checking boundary condition |
|
434 |
+ } |
|
435 |
+ |
|
436 |
+ return removePuyos; |
|
437 |
+ |
|
438 |
+ }//end of probe() |
|
439 |
+ /** |
|
440 |
+ * Pop the puyos marked by {@link puyopuyo.backEnd#probe(puyo) probe(puyo)} and also identifies all the puyos which have |
|
441 |
+ * to be moved down because of popping. |
|
442 |
+ * @param deletePuyos Puyos which have to be deleted from the boardMap. |
|
443 |
+ * @return Puyos which have to be moved down. |
|
444 |
+ */ |
|
445 |
+ private synchronized puyo[] popAndMarkDroppings(HashSet deletePuyos){ //:) pun intended |
|
446 |
+ |
|
447 |
+ /* it works on vectors and returns an array of puyos. |
|
448 |
+ *Vectors are being used because they are already synchronized, can be |
|
449 |
+ *converted to arrays after everything is done and can be resized dynamically |
|
450 |
+ */ |
|
451 |
+ Vector v = new Vector(); |
|
452 |
+ puyo temp; |
|
453 |
+ puyo puyoAboveTemp; |
|
454 |
+ Iterator i = deletePuyos.iterator(); |
|
455 |
+ while(i.hasNext()){//goin thru each element exactly once |
|
456 |
+ temp = (puyo)i.next(); //get an element from the set |
|
457 |
+ //popping routine// |
|
458 |
+ boardMap[temp.getX()][temp.getY()] = null; //remove temp from boardMap if not already removed |
|
459 |
+ score+=10; //increment score by 10 |
|
460 |
+ //---------------// |
|
461 |
+ //Marking routine// |
|
462 |
+ try{ |
|
463 |
+ do{ |
|
464 |
+ puyoAboveTemp = boardMap[temp.getX()][temp.getY()-1]; |
|
465 |
+ if( (puyoAboveTemp!=null && !v.contains(puyoAboveTemp)) & !deletePuyos.contains(puyoAboveTemp) ) //puyoAboveTemp has not been already marked |
|
466 |
+ v.add(puyoAboveTemp);//add it to set of puyos to be moved down |
|
467 |
+ temp = puyoAboveTemp; |
|
468 |
+ }while( temp!=null ); //puyo above the one being removed exists and is not the one to be popped |
|
469 |
+ } catch (ArrayIndexOutOfBoundsException e){ |
|
470 |
+ /* This happens in a very special case in which a pair falls down |
|
471 |
+ *and one among then is blocked at y=0 and the other falls down |
|
472 |
+ *making a chain in the coloumn which is filled till y=0. When |
|
473 |
+ *the chain pops, the above loop moves upward and on finding 'puyoAboveTemp' |
|
474 |
+ *above puyo at y=0, it reports this exception. because it is a |
|
475 |
+ *very special case, it need not be checked in the normal flow. |
|
476 |
+ * |
|
477 |
+ *When the exception occurs, the method should just continue with |
|
478 |
+ *popping the chain as all the puyos making up the column have been marked. |
|
479 |
+ *When exception has occured, control is already outside the loop and |
|
480 |
+ *should proceed normally with the outer while loop... |
|
481 |
+ */ |
|
482 |
+ puyoAboveTemp = null; |
|
483 |
+ } |
|
484 |
+ //---------------// |
|
485 |
+ temp = null; //puyoAboveTemp is null when control reaches here. |
|
486 |
+ }//end of while |
|
487 |
+ |
|
488 |
+ puyo[] movePuyosDown = new puyo[v.size()]; |
|
489 |
+ movePuyosDown = (puyo[])v.toArray(movePuyosDown); |
|
490 |
+ v.clear(); |
|
491 |
+ if(movePuyosDown.length > 1) |
|
492 |
+ Arrays.sort(movePuyosDown, new Comparator(){ |
|
493 |
+ public int compare(Object p1, Object p2){ |
|
494 |
+ if ( (p1!=null && !(p1 instanceof puyo)) & (p2!=null && !(p2 instanceof puyo)) ) |
|
495 |
+ throw new ClassCastException(); |
|
496 |
+ /*In case of one puyo being null, the one's that aint null is returned |
|
497 |
+ to be greater. If both are null, value corresponding to equality is returned*/ |
|
498 |
+ if( (p1 == null) & (p2 instanceof puyo) ) |
|
499 |
+ return -1; //once this evaluates to true, the control should not go further, thats y return statement is used here. |
|
500 |
+ else if ( (p1 instanceof puyo) & (p2 == null)) |
|
501 |
+ return 1; |
|
502 |
+ else if ( (p1 == null) & (p2 == null)) |
|
503 |
+ return 0; |
|
504 |
+ int retVal = 0; |
|
505 |
+ if ( ((puyo)p1).getY() < ((puyo)p2).getY() ) |
|
506 |
+ retVal = -1; |
|
507 |
+ else if ( ((puyo)p1).getY() > ((puyo)p2).getY()) |
|
508 |
+ retVal = 1; |
|
509 |
+ //if the two are equal, retVal = 0, which is the default value. |
|
510 |
+ return retVal; |
|
511 |
+ } |
|
512 |
+ } /* end of anonymous inner class*/ |
|
513 |
+ ); |
|
514 |
+ return movePuyosDown; |
|
515 |
+ } |
|
516 |
+} |
... | ... |
@@ -0,0 +1,611 @@ |
1 |
+/* |
|
2 |
+ * frontEnd.java |
|
3 |
+ * |
|
4 |
+ * Created on 30 March, 2007, 12:04 AM |
|
5 |
+ * |
|
6 |
+ * To change this template, choose Tools | Template Manager |
|
7 |
+ * and open the template in the editor. |
|
8 |
+ */ |
|
9 |
+ |
|
10 |
+import java.awt.AWTException; |
|
11 |
+import java.awt.Color; |
|
12 |
+import java.awt.Cursor; |
|
13 |
+import java.awt.DisplayMode; |
|
14 |
+import java.awt.Font; |
|
15 |
+import java.awt.Graphics2D; |
|
16 |
+import java.awt.Point; |
|
17 |
+import java.awt.RenderingHints; |
|
18 |
+import java.awt.Robot; |
|
19 |
+import java.awt.Toolkit; |
|
20 |
+import java.awt.Window; |
|
21 |
+import java.awt.event.KeyEvent; |
|
22 |
+import java.awt.event.KeyListener; |
|
23 |
+import java.awt.event.MouseEvent; |
|
24 |
+import java.awt.event.MouseListener; |
|
25 |
+import java.awt.event.MouseMotionListener; |
|
26 |
+import java.awt.image.ImageObserver; |
|
27 |
+import java.io.File; |
|
28 |
+import javax.swing.SwingUtilities; |
|
29 |
+ |
|
30 |
+/** |
|
31 |
+ * frontEnd manages the screen using {@link puyopuyo.ScreenManager# ScreenManager} and calls on {@link puyopuyo.backEnd# backEnd} |
|
32 |
+ * to execute the logic. |
|
33 |
+ * @author Dev Ghai |
|
34 |
+ */ |
|
35 |
+public class frontEnd extends backEnd implements KeyListener, MouseMotionListener, MouseListener { |
|
36 |
+ |
|
37 |
+ /** |
|
38 |
+ * <CODE>ImageObserver</CODE> object used to wait on puyo's image to |
|
39 |
+ * load so that its heigth and width can be determined. |
|
40 |
+ */ |
|
41 |
+ private ImageObserver observer; |
|
42 |
+ /** |
|
43 |
+ * Holds the width of the image representing the {@link puyopuyo.puyo# puyo}. It is assumed that all |
|
44 |
+ * the images representing puyos have same height and width. |
|
45 |
+ */ |
|
46 |
+ private final int puyoWidth = getPuyoPair()[0].getImage().getWidth(observer); |
|
47 |
+ |
|
48 |
+ /** |
|
49 |
+ * Holds the height of the image representing the {@link puyopuyo.puyo# puyo}. It is assumed that all |
|
50 |
+ * the images representing puyos have same height and width. |
|
51 |
+ */ |
|
52 |
+ private final int puyoHeight = getPuyoPair()[1].getImage().getHeight(observer); |
|
53 |
+ |
|
54 |
+ /** |
|
55 |
+ * Used for printing on screen. |
|
56 |
+ */ |
|
57 |
+ private Graphics2D g; |
|
58 |
+ /** |
|
59 |
+ * Returns the current graphics context. |
|
60 |
+ */ |
|
61 |
+ private Graphics2D getG(){ |
|
62 |
+ return g; |
|
63 |
+ } |
|
64 |
+ |
|
65 |
+ /** |
|
66 |
+ * Sets the current graphics context. |
|
67 |
+ */ |
|
68 |
+ private void setG(Graphics2D gr){ //used for initializing g |
|
69 |
+ g = gr; |
|
70 |
+ } |
|
71 |
+ /** |
|
72 |
+ * Creates a new instance of <CODE>frontEnd</CODE> |
|
73 |
+ */ |
|
74 |
+ public frontEnd(){ |
|
75 |
+ } |
|
76 |
+ |
|
77 |
+ /** |
|
78 |
+ * <ul><li>Creates an instance of the class.</li> |
|
79 |
+ * <li>Initialises {@link puyopuyo.backEnd#backEnd() backEnd} by calling on its constructor.</li> |
|
80 |
+ * <li>Adds the mouse and keyboard listeners.</li> |
|
81 |
+ * <li>Draws the complete screen for the first time.</li></ul> |
|
82 |
+ * @param autodetect Whether to autodetect the resolution at which to run the game. |
|
83 |
+ */ |
|
84 |
+ public frontEnd(boolean autodetect) { |
|
85 |
+ super(); |
|
86 |
+ initializeGraphics(autodetect); |
|
87 |
+ |
|
88 |
+ //add the listeners |
|
89 |
+ Window window = screen.getFullScreenWindow(); |
|
90 |
+ window.addMouseListener(this); |
|
91 |
+ window.addMouseMotionListener(this); |
|
92 |
+ window.addKeyListener(this); |
|
93 |
+ |
|
94 |
+ drawBoardMap(); |
|
95 |
+ } |
|
96 |
+ |
|
97 |
+ /** |
|
98 |
+ * Object of {@link puyopuyo.ScreenManager# ScreenManager}. |
|
99 |
+ */ |
|
100 |
+ private ScreenManager screen; |
|
101 |
+ /** |
|
102 |
+ * Array of supported display modes. |
|
103 |
+ */ |
|
104 |
+ private DisplayMode dm[]; |
|
105 |
+ /** |
|
106 |
+ * Font used for printing text on the screen. |
|
107 |
+ */ |
|
108 |
+ private Font f = new Font("Dialog", Font.PLAIN, 10); //initializing with a dummy value. |
|
109 |
+ /** |
|
110 |
+ * Color of the border surrounding the playing area. |
|
111 |
+ */ |
|
112 |
+ private Color borderColor = Color.ORANGE; |
|
113 |
+ /** |
|
114 |
+ * Color of the board. This color is also used as a background color to fill the screen. |
|
115 |
+ */ |
|
116 |
+ private Color boardColor = Color.WHITE; |
|
117 |
+ /** |
|
118 |
+ * Width of the border surrounding the playing area, in pixels. |
|
119 |
+ */ |
|
120 |
+ private int borderWidth = 8; |
|
121 |
+ |
|
122 |
+ /** |
|
123 |
+ * <ul> |
|
124 |
+ * <li>Switch to most appropriate display resolution.</li> |
|
125 |
+ * <li>Switch to full screen if system allows to, else exit.</li> |
|
126 |
+ * <li>Determine the co-ordinates at which to print the score.</li> |
|
127 |
+ * <li>Initialize mouse.</li> |
|
128 |
+ * <li>Set the current Graphics context.</li> |
|
129 |
+ * <li>Initialize the font.</li> |
|
130 |
+ * </ul> |
|
131 |
+ * @param autodetect Enable autodetection of graphics mode or not. |
|
132 |
+ */ |
|
133 |
+ private void initializeGraphics(boolean autodetect){ |
|
134 |
+ boolean switchedToFullscreen = false; |
|
135 |
+ System.out.println("Initializing Graphics..."); |
|
136 |
+ screen = new ScreenManager(); |
|
137 |
+ if(autodetect){ |
|
138 |
+ dm = screen.getCompatibleDisplayModes(); |
|
139 |
+ System.out.println("Available Display Modes: "); |
|
140 |
+ for(int i=dm.length-1 ; i>=0; i--){ |
|
141 |
+ System.out.println(dm[i].getWidth() + "x" + dm[i].getHeight() + " @ " + dm[i].getBitDepth() + " bits"); |
|
142 |
+ //Loop's runing in reverse dir coz in Windows systems, the modes are sorted |
|
143 |
+ //in asc order, and 1024x768 is given preference. |
|
144 |
+ if( (dm[i].getWidth() == 1024 && dm[i].getHeight() == 768) |
|
145 |
+ || (dm[i].getWidth() == 800 && dm[i].getHeight() == 600) ){ |
|
146 |
+ screen.setFullScreen(dm[i]); //switch to fullscreen only if its supported |
|
147 |
+ switchedToFullscreen = true; |
|
148 |
+ break; |
|
149 |
+ } |
|
150 |
+ } |
|
151 |
+ if(!switchedToFullscreen){ |
|
152 |
+ System.out.println("Your system doesn't support 1024x768 or 800x600 resolutions... \nAutoDetect failed!\nUsing the current DisplayMode"); |
|
153 |
+ screen.setFullScreen(screen.getCurrentDisplayMode()); |
|
154 |
+ } |
|
155 |
+ } |
|
156 |
+ else |
|
157 |
+ screen.setFullScreen(screen.getCurrentDisplayMode()); |
|
158 |
+ System.out.println("PuyosOnXAxis: " + puyosOnXAxis + ", puyosOnYxis: " + puyosOnYAxis); |
|
159 |
+ System.out.println("Dimensions of puyo's image = " + puyoHeight + "x" + puyoHeight); |
|
160 |
+ System.out.println("Playing area dimensions: " + playingAreaWidth + "x" + playingAreaHeight); |
|
161 |
+ System.out.println("Full screened at configuration: " + screen.getWidth() + "x" + screen.getHeight() + " @ " + screen.getCurrentDisplayMode().getBitDepth() + " bits"); |
|
162 |
+ scoreX = (screen.getWidth()/2)-(fontsize*2); |
|
163 |
+ scoreY = screen.getHeight()-fontsize; |
|
164 |
+ initializeMouse(screen.getFullScreenWindow()); |
|
165 |
+ Graphics2D g = screen.getGraphics(); |
|
166 |
+ setG(g); |
|
167 |
+ getG().setRenderingHint( |
|
168 |
+ RenderingHints.KEY_TEXT_ANTIALIASING, |
|
169 |
+ RenderingHints.VALUE_TEXT_ANTIALIAS_ON); |
|
170 |
+ initializeFont(); |
|
171 |
+ } |
|
172 |
+ /** |
|
173 |
+ * Set the font file to use, over-riding the default font created during initialization. |
|
174 |
+ */ |
|
175 |
+ private void initializeFont(){ |
|
176 |
+ File fontfile = new File("Pokemon.ttf"); |
|
177 |
+ try{ |
|
178 |
+ f = Font.createFont(Font.TRUETYPE_FONT, fontfile); |
|
179 |
+ } catch(Exception ffe){ |
|
180 |
+ System.out.println("Font format Exception: " + ffe.toString()); |
|
181 |
+ } |
|
182 |
+ getG().setFont(f.deriveFont((float)fontsize)); |
|
183 |
+ System.out.println("Using font: " + fontfile.toString()); |
|
184 |
+ getG().setColor(Color.RED); |
|
185 |
+ } |
|
186 |
+ |
|
187 |
+ /** |
|
188 |
+ * Stores X co-ordinate of the board (board contains playing area) |
|
189 |
+ */ |
|
190 |
+ private int boardX; |
|
191 |
+ /** |
|
192 |
+ * Stores Y Co-ordinate of the board (board contains playing area) |
|
193 |
+ */ |
|
194 |
+ private int boardY = 10; |
|
195 |
+ /** |
|
196 |
+ * playingAreaWidth = {@link puyopuyo.frontEnd#puyoWidth puyoWidth} * {@link puyopuyo.backEnd#puyosOnXAxis puyosOnXAxis}. |
|
197 |
+ */ |
|
198 |
+ private final int playingAreaWidth = puyoWidth * puyosOnXAxis; |
|
199 |
+ /** |
|
200 |
+ * playingAreaHeight = {@link puyopuyo.frontEnd#puyoHeight puyoHeight} * {@link puyopuyo.backEnd#puyosOnYAxis puyosOnYAxis}. |
|
201 |
+ */ |
|
202 |
+ private final int playingAreaHeight = puyoHeight * puyosOnYAxis; |
|
203 |
+ /** |
|
204 |
+ * Size of the font used for printing text on the screen. |
|
205 |
+ */ |
|
206 |
+ private int fontsize = 50; |
|
207 |
+ /** |
|
208 |
+ * X co-ordinate of the point where score has to be printed. |
|
209 |
+ */ |
|
210 |
+ private int scoreX; |
|
211 |
+ /** |
|
212 |
+ * Y co-ordinate of the point where score has to be printed. |
|
213 |
+ */ |
|
214 |
+ private int scoreY; |
|
215 |
+ |
|
216 |
+ /** |
|
217 |
+ * Fills the screen with background color and draws the outline of the playing area. |
|
218 |
+ */ |
|
219 |
+ public void drawScreen(){ |
|
220 |
+ //fill the screen with background color |
|
221 |
+ getG().setColor(boardColor); |
|
222 |
+ getG().fillRect(0, 0, screen.getWidth(), screen.getHeight()); |
|
223 |
+ //Board has to be center aligned horizontally |
|
224 |
+ boardX = (screen.getWidth()/2) - ((playingAreaWidth+(2*borderWidth))/2); |
|
225 |
+ //Draw the board |
|
226 |
+ getG().setColor(borderColor); |
|
227 |
+ getG().fillRoundRect(boardX, |
|
228 |
+ boardY, |
|
229 |
+ playingAreaWidth+(borderWidth*2), |
|
230 |
+ playingAreaHeight+(borderWidth*2), |
|
231 |
+ borderWidth, |
|
232 |
+ borderWidth); |
|
233 |
+ getG().setColor(boardColor); |
|
234 |
+ getG().fillRoundRect(boardX + borderWidth, |
|
235 |
+ boardY + borderWidth, |
|
236 |
+ playingAreaWidth, |
|
237 |
+ playingAreaHeight, |
|
238 |
+ borderWidth, |
|
239 |
+ borderWidth); |
|
240 |
+ //Score Area |
|
241 |
+ getG().fillRect(boardX, screen.getHeight()-(fontsize*2), screen.getWidth()/2, fontsize*2); |
|
242 |
+ } |
|
243 |
+ |
|
244 |
+ /** |
|
245 |
+ * Draws puyos according to the {@link puyopuyo.backEnd#boardMap boardMap} within the playing |
|
246 |
+ * area drawn by {@link puyopuyo.frontEnd#drawScreen() drawScreen}. |
|
247 |
+ */ |
|
248 |
+ public synchronized void drawBoardMap(){ |
|
249 |
+ drawScreen(); //MS Windows specific. |
|
250 |
+ getG().setColor(boardColor); |
|
251 |
+ getG().fillRoundRect(boardX + borderWidth, |
|
252 |
+ boardY + borderWidth, |
|
253 |
+ playingAreaWidth, |
|
254 |
+ playingAreaHeight, |
|
255 |
+ borderWidth, |
|
256 |
+ borderWidth); |
|
257 |
+ //Score Area |
|
258 |
+ getG().fillRect(boardX, screen.getHeight()-(fontsize*2), screen.getWidth()/2, fontsize*2); |
|
259 |
+ puyo board[][] = super.getBoardMap(); |
|
260 |
+ for (int j=0; j<puyosOnYAxis; j++) |
|
261 |
+ for(int i=0; i<puyosOnXAxis; i++){ |
|
262 |
+ if(board[i][j]!=null) |
|
263 |
+ getG().drawImage(board[i][j].getImage(), |
|
264 |
+ boardX + borderWidth + (puyoWidth*i), |
|
265 |
+ boardY + borderWidth + (puyoHeight*j), |
|
266 |
+ null); |
|
267 |
+ } |
|
268 |
+ //Print the score |
|
269 |
+ getG().setColor(Color.RED); |
|
270 |
+ getG().drawString("Score: "+getScore(), scoreX, scoreY); |
|
271 |
+ screen.update(); |
|
272 |
+ } |
|
273 |
+ |
|
274 |
+ /** |
|
275 |
+ * Direction in which to rotate the puyo. This value tells {@link puyopuyo.frontEnd#movementWrapper(int) movementWrapper} |
|
276 |
+ * to move the pair one step left. |
|
277 |
+ */ |
|
278 |
+ private final int LEFT = 1; |
|
279 |
+ /** |
|
280 |
+ * Direction in which to rotate the puyo. This value tells {@link puyopuyo.frontEnd#movementWrapper(int) movementWrapper} |
|
281 |
+ * to move the pair one step right. |
|
282 |
+ */ |
|
283 |
+ private final int RIGHT = 2; |
|
284 |
+ /** |
|
285 |
+ * Direction in which to rotate the puyo. This value tells {@link puyopuyo.frontEnd#movementWrapper(int) movementWrapper} |
|
286 |
+ * to move the pair one step down, or in other words, accelerate their fall. |
|
287 |
+ */ |
|
288 |
+ private final int DOWN = 3; |
|
289 |
+ /** |
|
290 |
+ * It directs {@link puyopuyo.frontEnd#movementWrapper(int) movementWrapper} to rotate the pair. |
|
291 |
+ */ |
|
292 |
+ private final int ROTATE = 4; |
|
293 |
+ |
|
294 |
+ /** |
|
295 |
+ * Tells whether the game is paused or not. If it is, all the Mouse and |
|
296 |
+ * Keyboard events are ignored. However, user is allowed to exit from the |
|
297 |
+ * game. |
|
298 |
+ */ |
|
299 |
+ private boolean paused = false; |
|
300 |
+ |
|
301 |
+ /** |
|
302 |
+ * Takes care of the movements on screen. |
|
303 |
+ * <p>Converts the pair of puyos on screen to single puyos and operates on them.<br> |
|
304 |
+ * Note that all calls to {@link puyopuyo.backEnd# backEnd }have been synchronized. This also ensures |
|
305 |
+ * that though operations are performed on a pair, logically operations are |
|
306 |
+ * performed individually on each {@link puyopuyo.puyo# puyo}. |
|
307 |
+ * </p> |
|
308 |
+ * @param direction Direction in which to move the pair, or rotate it clockwise. |
|
309 |
+ */ |
|
310 |
+ public synchronized void movementWrapper(int direction) { |
|
311 |
+ if(paused == true || isGameOver()) return; |
|
312 |
+ boolean lowerCouldMove = false; |
|
313 |
+ boolean upperCouldMove = false; //used to detect 'collisions' |
|
314 |
+ int lower = -1; //index of the puyo which is lower when the 2 r vertically arranged |
|
315 |
+ int upper = -1; //if any of the values is modified, this implies the puyos are arranged vertically |
|
316 |
+ //Check the one which is below |
|
317 |
+ if( (getPuyoPair()[0].getY()-1) == getPuyoPair()[1].getY() ){ |
|
318 |
+ //puyo at [0] is below |
|
319 |
+ lower = 0; |
|
320 |
+ upper = 1; |
|
321 |
+ } else if ( (getPuyoPair()[1].getY()-1) == getPuyoPair()[0].getY() ){ |
|
322 |
+ //[1]'s below |
|
323 |
+ lower = 1; |
|
324 |
+ upper = 0; |
|
325 |
+ } |
|
326 |
+ switch(direction){ |
|
327 |
+ case LEFT: |
|
328 |
+ if( (getPuyoPair()[0].getY() != getPuyoPair()[1].getY()) & |
|
329 |
+ (getPuyoPair()[0].getX() != getPuyoPair()[1].getX())) |
|
330 |
+ return; //return back without doing anything if the puyos dont lie in single row or single column |
|
331 |
+ if (lower != -1){ //VERTICAL ORIENTATION [PATCH] |
|
332 |
+ if(moveLeft(getPuyoPair()[lower])) |
|
333 |
+ moveLeft(getPuyoPair()[upper]); //move upper to left only if lower could move left first |
|
334 |
+ } |
|
335 |
+ //HORIZONTAL ORIENTATION: Check the one which is to left |
|
336 |
+ else if(getPuyoPair()[0].getX() == (getPuyoPair()[1].getX()-1) ){ |
|
337 |
+ //puyo at [0] is to left and both the puyos are joined |
|
338 |
+ moveLeft(getPuyoPair()[0]); |
|
339 |
+ moveLeft(getPuyoPair()[1]); |
|
340 |
+ } else{ |
|
341 |
+ //either the Xpositions are equal or [1]'s on left |
|
342 |
+ moveLeft(getPuyoPair()[1]); |
|
343 |
+ moveLeft(getPuyoPair()[0]); |
|
344 |
+ } |
|
345 |
+ break; |
|
346 |
+ case RIGHT: |
|
347 |
+ if( (getPuyoPair()[0].getY() != getPuyoPair()[1].getY()) & |
|
348 |
+ (getPuyoPair()[0].getX() != getPuyoPair()[1].getX())) |
|
349 |
+ return; //return back without doing anything if the puyos dont lie in single row or single column |
|
350 |
+ if (lower != -1){ //VERTICAL ORIENTATION [PATCH] |
|
351 |
+ if(moveRight(getPuyoPair()[lower])) |
|
352 |
+ moveRight(getPuyoPair()[upper]); //move upper to left only if lower could move left first |
|
353 |
+ } |
|
354 |
+ //HORIZONTAL ORIENTATION: Check the one which is to right |
|
355 |
+ else if(getPuyoPair()[0].getX() == (getPuyoPair()[1].getX()-1) ){ |
|
356 |
+ //puyo at [1] is to right |
|
357 |
+ moveRight(getPuyoPair()[1]); |
|
358 |
+ moveRight(getPuyoPair()[0]); |
|
359 |
+ } else{ |
|
360 |
+ //either the X positions are equal or [0]'s on right |
|
361 |
+ moveRight(getPuyoPair()[0]); |
|
362 |
+ moveRight(getPuyoPair()[1]); |
|
363 |
+ } |
|
364 |
+ break; |
|
365 |
+ case DOWN: |
|
366 |
+ if(lower == -1){ //HORIZONTAL ORIENTATION => move any of the puyos first. |
|
367 |
+ lower = 1; |
|
368 |
+ upper = 0; |
|
369 |
+ } |
|
370 |
+ lowerCouldMove = moveDown(getPuyoPair()[lower]); |
|
371 |
+ upperCouldMove = moveDown(getPuyoPair()[upper]); |
|
372 |
+ //launch chain rxn of popping if both couldn't move |
|
373 |
+ if( !lowerCouldMove & !upperCouldMove ){ |
|
374 |
+ popPuyos(getPuyoPair()); |
|
375 |
+ drawBoardMap(); |
|
376 |
+ //now that the 2 have settled, push a new pair on board |
|
377 |
+ pushPuyos(); |
|
378 |
+ } |
|
379 |
+ break; |
|
380 |
+ case ROTATE: rotate(getPuyoPair()); |
|
381 |
+ break; |
|
382 |
+ } |
|
383 |
+ drawBoardMap(); |
|
384 |
+ } |
|
385 |
+ |
|
386 |
+ /** |
|
387 |
+ * <CODE>KeyEvent</CODE> listener that is responsible for firing appropriate actions corresponding |
|
388 |
+ * to the key pressed. |
|
389 |
+ * <p><ul><b>UP ARROW KEY</b> - Rotate the pair.</ul> |
|
390 |
+ * <ul><b>LEFT ARROW KEY</b> - Move the pair to left.</ul> |
|
391 |
+ * <ul><b>RIGHT ARROW KEY</b> - Move the pair to right. |
|
392 |
+ * <ul><b>DOWN ARROW KEY</b> - Move the pair downwards/accelerate the fall.</ul> |
|
393 |
+ * <ul><b>SPACEBAR</b> - Pause the game.</ul> |
|
394 |
+ * <ul><b>ESC</b> - Quit from the game.</ul></p> |
|
395 |
+ * @param e Virtual code of the key pressed. |
|
396 |
+ */ |
|
397 |
+ public void keyPressed(KeyEvent e){ |
|
398 |
+ switch(e.getKeyCode()){ |
|
399 |
+ case KeyEvent.VK_ESCAPE: setGameOver(true); break; |
|
400 |
+ case KeyEvent.VK_LEFT: movementWrapper(LEFT); break; |
|
401 |
+ case KeyEvent.VK_RIGHT: movementWrapper(RIGHT); break; |
|
402 |
+ case KeyEvent.VK_DOWN: movementWrapper(DOWN); break; |
|
403 |
+ case KeyEvent.VK_UP: movementWrapper(ROTATE); break; |
|
404 |
+ case KeyEvent.VK_SPACE: paused = !paused; break; |
|
405 |
+ } |
|
406 |
+ } |
|
407 |
+ |
|
408 |
+ /** |
|
409 |
+ * <CODE>KeyListener</CODE> Interface: keyReleased. Ignored. |
|
410 |
+ */ |
|
411 |
+ public void keyReleased(KeyEvent e){ |
|
412 |
+ //do nothing! |
|
413 |
+ } |
|
414 |
+ |
|
415 |
+ /** |
|
416 |
+ * <CODE>KeyListener</CODE> Interface: keyTyped. Ignored. |
|
417 |
+ */ |
|
418 |
+ public void keyTyped(KeyEvent e){ |
|
419 |
+ //do nothing! |
|
420 |
+ } |
|
421 |
+ |
|
422 |
+ |
|
423 |
+ |
|
424 |
+ /** |
|
425 |
+ * From the <CODE>MouseListener</CODE> interface. <CODE>MouseListener</CODE> responsible for firing |
|
426 |
+ * appropriate events corresponding to the key pressed. |
|
427 |
+ */ |
|
428 |
+ public void mousePressed(MouseEvent e) { |
|
429 |
+ movementWrapper(ROTATE) ; |
|
430 |
+ } |
|
431 |
+ |
|
432 |
+ /** |
|
433 |
+ * From the <CODE>MouseListener</CODE> interface. Ignored. |
|
434 |
+ */ |
|
435 |
+ public void mouseReleased(MouseEvent e) { |
|
436 |
+ // do nothing |
|
437 |
+ } |
|
438 |
+ |
|
439 |
+ /** |
|
440 |
+ * From the <CODE>MouseListener</CODE> interface. Ignored. |
|
441 |
+ */ |
|
442 |
+ public void mouseClicked(MouseEvent e) { |
|
443 |
+ // called after mouse is released - ignored |
|
444 |
+ } |
|
445 |
+ |
|
446 |
+ /** |
|
447 |
+ * From the <CODE>MouseListener</CODE> interface. Ignored. |
|
448 |
+ */ |
|
449 |
+ public void mouseEntered(MouseEvent e) { |
|
450 |
+ //do nothing |
|
451 |
+ } |
|
452 |
+ |
|
453 |
+ /** |
|
454 |
+ * From the <CODE>MouseListener</CODE> interface. Ignored. |
|
455 |
+ */ |
|
456 |
+ public void mouseExited(MouseEvent e) { |
|
457 |
+ //do nothing |
|
458 |
+ } |
|
459 |
+ |
|
460 |
+ /** |
|
461 |
+ * From the <CODE>MouseMotionListener</CODE> interface. Ignored. |
|
462 |
+ */ |
|
463 |
+ public void mouseDragged(MouseEvent e) { |
|
464 |
+ //do nothing |
|
465 |
+ } |
|
466 |
+ |
|
467 |
+ /** |
|
468 |
+ * From the <CODE>MouseMotionListener</CODE> interface. Determines in which direction has |
|
469 |
+ * the mouse moved and then recenters it. |
|
470 |
+ */ |
|
471 |
+ public synchronized void mouseMoved(MouseEvent e) { |
|
472 |
+ if(paused == true) return; |
|
473 |
+ // this event is from re-centering the mouse - ignore it |
|
474 |
+ if (isRecentering && |
|
475 |
+ centerLocation.x == e.getX() && |
|
476 |
+ centerLocation.y == e.getY()) { |
|
477 |
+ isRecentering = false; |
|
478 |
+ } |
|
479 |
+ |
|
480 |
+ else { |
|
481 |
+ int dx = e.getX() - mouseLocation.x; |
|
482 |
+ int dy = e.getY() - mouseLocation.y; |
|
483 |
+ if(dx<0) //Mouse moved left |
|
484 |
+ movementWrapper(LEFT); |
|
485 |
+ else if(dx>0) //Mouse moved right |
|
486 |
+ movementWrapper(RIGHT); |
|
487 |
+ else if(dy>0) //Mouse moved down |
|
488 |
+ movementWrapper(DOWN); |
|
489 |
+ //Movements towards north are to be ignored |
|
490 |
+ recenterMouse(); |
|
491 |
+ |
|
492 |
+ |
|
493 |
+ } |
|
494 |
+ mouseLocation.x = e.getX(); |
|
495 |
+ mouseLocation.y = e.getY(); |
|
496 |
+ } |
|
497 |
+ |
|
498 |
+ /** |
|
499 |
+ * Object of <CODE>Robot</CODE> class used for recentering the mouse. |
|
500 |
+ */ |
|
501 |
+ private Robot robot; |
|
502 |
+ /** |
|
503 |
+ * <CODE>Point</CODE> object storing the mouse's location. |
|
504 |
+ */ |
|
505 |
+ private Point mouseLocation; |
|
506 |
+ /** |
|
507 |
+ * Holds the center point of the screen. |
|
508 |
+ */ |
|
509 |
+ private Point centerLocation; |
|
510 |
+ /** |
|
511 |
+ * <CODE>Boolean</CODE> telling if the mouse is re-centering or not. |
|
512 |
+ */ |
|
513 |
+ private boolean isRecentering; |
|
514 |
+ |
|
515 |
+ /** |
|
516 |
+ * Initializes the mouse, recenters it and hides the mouse pointer. |
|
517 |
+ * @param window Window for which to initialize the mouse. |
|
518 |
+ */ |
|
519 |
+ private void initializeMouse(Window window){ |
|
520 |
+ //hide the mouse pointer |
|
521 |
+ Cursor invisibleCursor = |
|
522 |
+ Toolkit.getDefaultToolkit().createCustomCursor( |
|
523 |
+ Toolkit.getDefaultToolkit().getImage(""), |
|
524 |
+ new Point(0,0),"invisible"); |
|
525 |
+ window.setCursor(invisibleCursor); |
|
526 |
+ System.out.println("Mouse Pointer is now hidden!"); |
|
527 |
+ |
|
528 |
+ mouseLocation = new Point(); |
|
529 |
+ centerLocation = new Point(); |
|
530 |
+ isRecentering = false; |
|
531 |
+ |
|
532 |
+ try { |
|
533 |
+ robot = new Robot(); |
|
534 |
+ recenterMouse(); |
|
535 |
+ mouseLocation.x = centerLocation.x; |
|
536 |
+ mouseLocation.y = centerLocation.y; |
|
537 |
+ } catch (AWTException ex) { |
|
538 |
+ System.out.println("Couldn't create Robot! Mouse initialization failed!!"); |
|
539 |
+ } |
|
540 |
+ } |
|
541 |
+ |
|
542 |
+ /** |
|
543 |
+ * Uses the <CODE>Robot</CODE> class to try to position the mouse in the |
|
544 |
+ * center of the screen. |
|
545 |
+ * <p>Note that use of the <CODE>Robot</CODE> class may not be available |
|
546 |
+ * on all platforms.</p> |
|
547 |
+ */ |
|
548 |
+ private synchronized void recenterMouse() { |
|
549 |
+ Window window = screen.getFullScreenWindow(); |
|
550 |
+ if (robot != null && window.isShowing()) { |
|
551 |
+ centerLocation.x = window.getWidth() / 2; |
|
552 |
+ centerLocation.y = window.getHeight() / 2; |
|
553 |
+ SwingUtilities.convertPointToScreen(centerLocation, |
|
554 |
+ window); |
|
555 |
+ isRecentering = true; |
|
556 |
+ robot.mouseMove(centerLocation.x, centerLocation.y); |
|
557 |
+ } |
|
558 |
+ } |
|
559 |
+ /** |
|
560 |
+ * Kills the thread and exits from the game while restoring the screen |
|
561 |
+ * and unhiding the mouse pointer. |
|
562 |
+ */ |
|
563 |
+ public void goodbye(){ //do cleanup ops before exiting |
|
564 |
+ /* Restore Cursor |
|
565 |
+ * Restore Screen |
|
566 |
+ * Kill the thread |
|
567 |
+ */ |
|
568 |
+ System.out.println("GoodBye!!"); |
|
569 |
+ getG().setColor(Color.MAGENTA); |
|
570 |
+ getG().drawString("GoodBye!", 10, screen.getHeight()-50); |
|
571 |
+ getG().drawString(":(", screen.getWidth()-100, screen.getHeight()-50); |
|
572 |
+ screen.update(); |
|
573 |
+ try { |
|
574 |
+ Thread.sleep(1000); |
|
575 |
+ } catch (InterruptedException ex) { } |
|
576 |
+ Cursor normalCursor = |
|
577 |
+ Cursor.getDefaultCursor(); |
|
578 |
+ Window window = screen.getFullScreenWindow(); |
|
579 |
+ window.setCursor(normalCursor); |
|
580 |
+ screen.restoreScreen(); |
|
581 |
+ System.exit(0); |
|
582 |
+ } |
|
583 |
+ /** |
|
584 |
+ * 'Mainest' Method Of ALL :D |
|
585 |
+ * @param args the command line arguments |
|
586 |
+ */ |
|
587 |
+ public static void main(String[] args) { |
|
588 |
+ frontEnd w; |
|
589 |
+ if(args.length>0 && args[0].equalsIgnoreCase(new String("autodetect"))) |
|
590 |
+ w = new frontEnd(true); |
|
591 |
+ else w = new frontEnd(false); |
|
592 |
+ |
|
593 |
+ while(!w.isGameOver()){ |
|
594 |
+ w.movementWrapper(3); //3 implies down |
|
595 |
+ try{ |
|
596 |
+ Thread.sleep(500); |
|
597 |
+ } catch (InterruptedException ex) { |
|
598 |
+ System.out.println("Main Thread Interrupted! Reason: " + ex.toString()); |
|
599 |
+ } |
|
600 |
+ } |
|
601 |
+ try |
|
602 |
+ { |
|
603 |
+ w.goodbye(); |
|
604 |
+ } |
|
605 |
+ catch (Exception e) |
|
606 |
+ { |
|
607 |
+ System.out.println(e.toString()); |
|
608 |
+ } |
|
609 |
+ |
|
610 |
+ } |
|
611 |
+} |
... | ... |
@@ -0,0 +1,114 @@ |
1 |
+/* |
|
2 |
+ * puyo.java |
|
3 |
+ * |
|
4 |
+ * Created on 16 April, 2007, 3:00 AM |
|
5 |
+ * |
|
6 |
+ * To change this template, choose Tools | Template Manager |
|
7 |
+ * and open the template in the editor. |
|
8 |
+ */ |
|
9 |
+ |
|
10 |
+import java.awt.Image; |
|
11 |
+import javax.swing.ImageIcon; |
|
12 |
+ |
|
13 |
+/** |
|
14 |
+ * Creates a puyo object that holds all the its properties- |
|
15 |
+ * the image representing the puyo, logical x and y positions (in array {@link puyopuyo.backEnd#boardMap boardMap}) |
|
16 |
+ * and a character representing the color of the puyo. |
|
17 |
+ * @author Dev Ghai |
|
18 |
+ */ |
|
19 |
+public class puyo{ |
|
20 |
+ |
|
21 |
+ /** |
|
22 |
+ * Creates a new puyo and associates image file <b>filename</b> to the puyo |
|
23 |
+ * and sets its color to <b>c</b>. |
|
24 |
+ * @param filename File name of the image that has to be associated with the puyo. |
|
25 |
+ * @param c Color of the puyo |
|
26 |
+ * <p>Following are its possible values: |
|
27 |
+ * <ul> |
|
28 |
+ * <li>'r' - Red</li> |
|
29 |
+ * <li>'g' - Green</li> |
|
30 |
+ * <li>'b' - Blue</li> |
|
31 |
+ * <li>'y' - Yellow</li> |
|
32 |
+ * </ul> |
|
33 |
+ */ |
|
34 |
+ public puyo(String filename, char c){ |
|
35 |
+ image = new ImageIcon(filename).getImage(); |
|
36 |
+ x=0; |
|
37 |
+ y=0; |
|
38 |
+ color = c; |
|
39 |
+ } |
|
40 |
+ /** |
|
41 |
+ * Creates a default puyo without assigning any image or color to it. |
|
42 |
+ */ |
|
43 |
+ public puyo(){} |
|
44 |
+ /** |
|
45 |
+ * Holds the image that represents the puyo. |
|
46 |
+ */ |
|
47 |
+ private Image image; |
|
48 |
+ |
|
49 |
+ /** |
|
50 |
+ * Returns the image associated with the puyo. |
|
51 |
+ */ |
|
52 |
+ public Image getImage(){ |
|
53 |
+ return image; |
|
54 |
+ } |
|
55 |
+ |
|
56 |
+ /** |
|
57 |
+ * Holds the X-Co-ordinate of the puyo in {@link puyopuyo.backEnd#boardMap} |
|
58 |
+ */ |
|
59 |
+ private int x; |
|
60 |
+ |
|
61 |
+ /** |
|
62 |
+ * Returns the X-Co-ordinate of the puyo in {@link puyopuyo.backEnd#boardMap boardMap}. |
|
63 |
+ */ |
|
64 |
+ public int getX(){ |
|
65 |
+ return x; |
|
66 |
+ } |
|
67 |
+ |
|
68 |
+ /** |
|
69 |
+ * Sets the X-Co-ordinate of the puyo in {@link puyopuyo.backEnd#boardMap boardMap} to xPos. |
|
70 |
+ * @param xPos New x position of puyo in {@link puyopuyo.backEnd#boardMap boardMap}. |
|
71 |
+ */ |
|
72 |
+ public void setX(int xPos){ |
|
73 |
+ x = xPos; |
|
74 |
+ } |
|
75 |
+ |
|
76 |
+ /** |
|
77 |
+ * Holds the Y-Co-ordinate of the puyo |
|
78 |
+ */ |
|
79 |
+ private int y; |
|
80 |
+ |
|
81 |
+ /** |
|
82 |
+ * Returns the Y-Co-ordinate of the puyo in the {@link puyopuyo.backEnd#boardMap boardMap} |
|
83 |
+ */ |
|
84 |
+ public int getY(){ |
|
85 |
+ return y; |
|
86 |
+ } |
|
87 |
+ |
|
88 |
+ /** |
|
89 |
+ * Sets the Y-Co-ordinate of the puyo in {@link puyopuyo.backEnd#boardMap boardMap} to yPos. |
|
90 |
+ * @param yPos New y position of puyo in {@link puyopuyo.backEnd#boardMap boardMap}. |
|
91 |
+ */ |
|
92 |
+ public void setY(int yPos){ |
|
93 |
+ y = yPos; |
|
94 |
+ } |
|
95 |
+ |
|
96 |
+ /** |
|
97 |
+ * Holds the color of the puyo. The color is stored first letter of the color string. |
|
98 |
+ * For example 'r' is stored for red. |
|
99 |
+ */ |
|
100 |
+ private char color; |
|
101 |
+ |
|
102 |
+ /** |
|
103 |
+ * Returns the color of the puyo - |
|
104 |
+ * <ul> |
|
105 |
+ * <li>'r' - Red</li> |
|
106 |
+ * <li>'g' - Green</li> |
|
107 |
+ * <li>'b' - Blue</li> |
|
108 |
+ * <li>'y' - Yellow</li> |
|
109 |
+ * </ul> |
|
110 |
+ */ |
|
111 |
+ public char getColor(){ |
|
112 |
+ return color; |
|
113 |
+ } |
|
114 |
+} |
... | ... |
@@ -0,0 +1 @@ |
1 |
+java frontEnd |