001 import java.awt.*;
002 import java.awt.event.*;
003 import java.awt.geom.*;
004 import java.util.*;
005 import javax.swing.*;
006 import javax.swing.BorderFactory; 
007 import javax.swing.border.Border;
008 import javax.swing.border.TitledBorder;
009 import javax.swing.border.EtchedBorder;
010 
011 /**
012  * This class works as a game engine which loops to do updates.
013  *
014  */
015 class GameEngine extends JPanel implements Runnable {
016     
017     // Field variables
018     public static final int NUM_BLOCKS = 32// 4 X 8
019     public static final int BLOCK_SPACE = 5;
020     public static final int WIDTH = (Block.WIDTH+BLOCK_SPACE)*8+BLOCK_SPACE;
021     public static final int HEIGHT = 364;
022     public static final int THRESHOLD = BouncerFrame.HEIGHT - 2*Ball.RADIUS;
023     public static final int BALL_START_XPOS = 20;
024     public static final int BALL_START_YPOS = 280;
025     public static final int BAR_START_XPOS = 0;
026     public static final int BAR_START_YPOS = 300;
027     public static final int LEVEL1_INTERVAL = 100;    // speed of level 1
028     public static final int LEVEL2_INTERVAL = 90;    // speed of level 2
029     public static final int LEVEL3_INTERVAL = 80;    // speed of level 3
030     public static final int LEVEL4_INTERVAL = 70;    // speed of level 4
031     public static final int LEVEL5_INTERVAL = 60;    // speed of level 5
032     
033     public static boolean isHitBottom = false;    // indicates if the ball hits the bottom
034                                                 //  set as global for simplicity
035     public static boolean isCheat = false;    // tooggle cheat mode
036                                                 // set as global for simplicity
037     int blocksDestroyed = 0;
038     boolean gameStarted = false;
039     boolean stopRequested = false;
040     boolean suspendRequested = false;
041     Ball ball;
042     Block[] blockArray;
043     Bar bar;
044     int currentInterval;
045     int score;
046     
047     private SuspendRequestor suspender =  new SuspendRequestor();
048     
049     public GameEngine() {
050         
051         currentInterval = LEVEL1_INTERVAL;
052         score = 0;
053         setSize(WIDTH, HEIGHT);
054         setBorder(BorderFactory.createEtchedBorder(EtchedBorder.RAISED));
055         blockArray = new Block[GameEngine.NUM_BLOCKS];
056         int x = 10 , y = 10;
057         for(int i=0; i<4; i++) {
058 
059             for(int j=0; j<; j++) {
060                 blockArray[i*+ jnew Block(x, y, Color.YELLOW);
061                 x = x + Block.WIDTH + BLOCK_SPACE;
062             }
063 
064             x = 10;    // reset the x position            
065             y = y + Block.HEIGHT + 5;
066         
067         bar = new Bar(BAR_START_XPOS, BAR_START_YPOS, Color.BLACK);
068         // position the ball above the center of the bar
069         ball = new Ball(bar.getXPos()+Bar.WIDTH/2-ball.RADIUS, bar.getYPos()-2*Ball.RADIUS, Color.RED, 1010);
070 
071         repaint();
072         
073         requestFocus();
074         addKeyListener(new KeyHandler());
075         
076     // end of GameEngine(RecordPanel)
077     
078     public void startGame() {
079         
080         if(!gameStarted) {
081             gameStarted = true;
082             stopRequested = false;
083             suspendRequested = false;
084             ball.setXPos(bar.getXPos()+Bar.WIDTH/2);
085             ball.setYPos(bar.getYPos()-Ball.RADIUS);
086             
087             //*******Add something here to make the game start*****
088             
089             //*****************************************************
090         }
091         
092     // end of startGame()
093     
094     public void suspendResumeGame() {
095         
096         suspendRequested = !suspendRequested;
097 
098         if(gameStarted) {
099             //********Handle the request according to the state of the game*******
100             //**********Only need to write codes inside this if-block*************
101         }
102         
103     // end of suspendResumeGame()
104     
105     public void requestSuspend() { 
106 
107         //*********Write your code here*************
108 
109     // end of requestSuspend()
110     
111     public synchronized void requestResume() { 
112 
113         //*********Write your code here*************
114 
115     // end of requestResume()
116     
117     public void stopGame() {
118         
119         stopRequested = true;
120         gameStarted = false;
121         
122     // end of stopGame()
123     
124     
125     public void paintComponent(Graphics g) {
126         
127         super.paintComponent(g);
128         Graphics2D g2 = (Graphics2D)g;
129         
130         // draw the ball
131         ball.draw(g2);
132 
133         // draw the blocks
134         for(int i=0; i<blockArray.length; i++) {
135             if(!blockArray[i].isDestroyed()){
136                 blockArray[i].draw(g2);
137                 //System.out.println(i + "th block drawn");
138             }
139         }
140         
141         // draw the bar
142         bar.draw(g2);
143         
144         // debug message for showing the dimension of the game panel
145         //System.out.println(getWidth()+" X "+getHeight());
146         
147     // end of paintComponent(Graphics)
148     
149     
150     public void run() {
151         
152             // loop thoughout the whole game, unless stop is requested
153             while(!stopRequested) {
154                 
155                 //******Add something here to make the suspend/resume work*******
156                 
157                 //***************************************************************
158                 
159                 // check if the ball hits any block
160                 int blockResult;
161                 for(int i=0; i<blockArray.length; i++) {
162                     if(!blockArray[i].isDestroyed()) {
163                         blockResult = blockArray[i].isHit(ball);    
164                         if(blockResult == Block.TOP_OR_BOTTOM) {
165                             blockArray[i].setDestroyed(true);
166                             ball.setYVel(-ball.getYVel());
167                             // increase score
168                             score += currentInterval;
169                             blocksDestroyed++;
170                         
171                         else if(blockResult == Block.LEFT_OR_RIGHT) {
172                             blockArray[i].setDestroyed(true);
173                             ball.setXVel(-ball.getXVel());
174                             // increase score
175                             score += currentInterval;
176                             blocksDestroyed++;
177                         }
178                         else {    // do nothing
179                         }
180                     }    
181                 }
182                 
183                 // check if all the blocks are destroyed
184                 if(blocksDestroyed >= NUM_BLOCKS) {            
185                     // repaint all the things
186                     repaint();
187                     stopGame();
188                     JOptionPane.showMessageDialog(this, "You've won!\nScore = "+score);
189                     System.exit(0);    
190                 }
191                 
192                 // check if the ball hits the bar
193                 int barResult = bar.isHit(ball);
194                 if(barResult==Bar.LEFT_SIDE || barResult==Bar.RIGHT_SIDE) {
195                     // make it move faster horizontally
196                     ball.setXVel(ball.getXVel()+2);
197                     ball.setYVel(-ball.getYVel());
198                 
199                 else if(barResult == Bar.MIDDLE) {
200                     ball.setYVel(-ball.getYVel());
201                 }
202                 else {
203                     // do nothing, since no hit    
204                 }
205     
206                 // check if the ball has hit the bottom
207                 if(!isCheat && isHitBottom) {
208                     stopGame();
209                     JOptionPane.showMessageDialog(this, "Game Over!\nScore = "+score);
210                     System.exit(0);                    
211                 }
212                 
213     
214                 // move the ball
215                 ball.move(getWidth(), getHeight());
216                 
217                 // repaint all the things
218                 repaint();
219                 
220                 // sleep for delay
221                 try {
222                     Thread.sleep(currentInterval);
223                 catch(InterruptedException ie) {}
224             }
225             
226     // end of run()
227     
228     // public boolean isFocusTraversable() <- Deprecated since JDK1.4
229     public boolean isFocusable() {
230     
231         return true// allow panel to get input focus
232         
233     }
234 
235     /**
236      * Inner class for handling the left and right button events
237      *
238      */
239     private class KeyHandler extends KeyAdapter {
240         
241         public void keyPressed(KeyEvent event) {
242             
243             int keyCode = event.getKeyCode();
244 
245             if (keyCode == KeyEvent.VK_LEFT && !suspendRequested) {
246                 //System.out.println("left pressed");
247                 bar.move(getWidth(), getHeight(), Bar.LEFT);
248                 if(!gameStarted)
249                     ball.setXPos(bar.getXPos()+Bar.WIDTH/2-Ball.RADIUS);
250             }
251             else if (keyCode == KeyEvent.VK_RIGHT && !suspendRequested) {
252                 //System.out.println("right pressed");
253                 bar.move(getWidth(), getHeight(), Bar.RIGHT);
254                 if(!gameStarted)
255                     ball.setXPos(bar.getXPos()+Bar.WIDTH/2-Ball.RADIUS);
256             }
257             else if (keyCode == KeyEvent.VK_UP) {
258                 //System.out.println("up pressed");
259                 if(!gameStarted)
260                     startGame();
261             }
262             else if (keyCode == KeyEvent.VK_C) {
263                 isCheat = !isCheat;
264                 if(isCheat)    ball.setColor(Color.BLUE);
265                 else ball.setColor(Color.RED);
266             }
267             else if (keyCode == KeyEvent.VK_P) {
268                 suspendResumeGame();
269             }
270             else {
271                 // do nothing
272             }
273             
274             repaint();
275             
276       // end of keyPressed(KeyEvent)
277           
278     // end of KeyHandler inner class definition
279     
280 // end of GameEngine class definition
281 
282 // The class for us to use its objects as locks
283 class SuspendRequestor
284 {   public synchronized void set boolean b)
285   {  suspendRequested = b;
286      notifyAll();}
287    
288   public synchronized void waitForResume()
289      throws InterruptedException
290   {  while suspendRequestedwait ()}
291 
292   private boolean suspendRequested;
293 }
Java2html