Advertisement
Guest User

gamePanel

a guest
Aug 22nd, 2012
124
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 11.07 KB | None | 0 0
  1.  
  2.  
  3. import javax.swing.*;
  4. import java.awt.event.*;
  5. import java.awt.*;
  6.  
  7.  
  8.  
  9. public class gamePanel extends JPanel implements Runnable
  10. {
  11.   private static long MAX_STATS_INTERVAL = 1000000000L;
  12.   // private static long MAX_STATS_INTERVAL = 1000L;
  13.     // record stats every 1 second (roughly)
  14.  
  15.   private static final int NO_DELAYS_PER_YIELD = 16;
  16.   /* Number of frames with a delay of 0 ms before the animation thread yields
  17.      to other running threads. */
  18.  
  19.   private static int MAX_FRAME_SKIPS = 5;   // was 2;
  20.     // no. of frames that can be skipped in any one animation loop
  21.     // i.e the games state is updated but not rendered
  22.  
  23.   private static int NUM_FPS = 10;
  24.      // number of FPS values stored to get an average
  25.  
  26.  
  27.   private int pWidth, pHeight;   // dimensions of the panel
  28.  
  29.   // used for gathering statistics
  30.   private long statsInterval = 0L;    // in ns
  31.   private long prevStatsTime;  
  32.   private long totalElapsedTime = 0L;
  33.   private long gameStartTime;
  34.   private int timeSpentInGame = 0;    // in seconds
  35.  
  36.   private long frameCount = 0;
  37.   private double fpsStore[];
  38.   private long statsCount = 0;
  39.   private double averageFPS = 0.0;
  40.  
  41.   private long framesSkipped = 0L;
  42.   private long totalFramesSkipped = 0L;
  43.   private double upsStore[];
  44.   private double averageUPS = 0.0;
  45.  
  46.  
  47.  
  48.   private Thread animator;           // the thread that performs the animation
  49.   private volatile boolean running = false;   // used to stop the animation thread
  50.   private volatile boolean isPaused = false;
  51.  
  52.   private long period;                // period between drawing in _nanosecs_
  53.  
  54.  
  55.   private Game wcTop;
  56.  
  57.  
  58.   // used at game termination
  59.   private volatile boolean gameOver = false;
  60.   private int score = 0;
  61.   private Font font;
  62.   private FontMetrics metrics;
  63.  
  64.   // off screen rendering
  65.   private Graphics dbg;
  66.   private Image dbImage = null;
  67.  
  68.  
  69. World world;
  70.   public gamePanel(Game wc, long period, int w, int h)
  71.   {
  72.     wcTop = wc;
  73.     this.period = period;
  74.     pWidth = w; pHeight = h;
  75.  
  76.     setBackground(Color.white);
  77.     setPreferredSize( new Dimension(pWidth, pHeight));
  78.  
  79.     setFocusable(true);
  80.     requestFocus();    // the JPanel now has focus, so receives key events
  81.     buttonListener();
  82.  
  83.     // create game components
  84.     world=new World(w,h);
  85.     gameOver = false;
  86.    
  87.    
  88.  
  89.     addMouseListener( new MouseAdapter() {
  90.       public void mousePressed(MouseEvent e)
  91.       { testPress(e.getX(), e.getY()); }
  92.     });
  93.  
  94.     // set up message font
  95.     font = new Font("SansSerif", Font.BOLD, 24);
  96.     metrics = this.getFontMetrics(font);
  97.  
  98.     // initialise timing elements
  99.     fpsStore = new double[NUM_FPS];
  100.     upsStore = new double[NUM_FPS];
  101.     for (int i=0; i < NUM_FPS; i++) {
  102.       fpsStore[i] = 0.0;
  103.       upsStore[i] = 0.0;
  104.     }
  105.   }  // end of WormPanel()
  106.  
  107.  
  108.  
  109.   private void buttonListener()
  110.   {
  111.     addKeyListener( new KeyAdapter() {
  112.     // listen for esc, q, end, ctrl-c on the canvas to
  113.     // allow a convenient exit from the full screen configuration
  114.        public void keyPressed(KeyEvent e)
  115.        { int keyCode = e.getKeyCode();
  116.          if ((keyCode == KeyEvent.VK_ESCAPE) || (keyCode == KeyEvent.VK_Q) ||
  117.              (keyCode == KeyEvent.VK_END) ||
  118.              ((keyCode == KeyEvent.VK_C) && e.isControlDown()) ) {
  119.            running = false;
  120.          }//end if
  121.          else{
  122.              world.moveCamera(keyCode);
  123.          }
  124.          
  125.        }
  126.      });
  127.   }  // end of readyForTermination()
  128.  
  129.  
  130.   public void addNotify()
  131.   // only start the animation once the JPanel has been added to the JFrame
  132.   { super.addNotify();   // creates the peer
  133.     startGame();    // start the thread
  134.   }
  135.  
  136.   private void startGame()
  137.   // initialise and start the thread
  138.   { if (animator == null || !running) {
  139.       animator = new Thread(this);
  140.       animator.start();
  141.     }
  142.   }
  143.  
  144.  
  145.   // ------------- game life cycle methods ------------
  146.   // called by the JFrame's window listener methods
  147.  
  148.   public void resumeGame()
  149.   // called when the JFrame is activated / deiconified
  150.   {  isPaused = false;  }
  151.  
  152.  
  153.   public void pauseGame()
  154.   // called when the JFrame is deactivated / iconified
  155.   { isPaused = true;   }
  156.  
  157.  
  158.   public void stopGame()
  159.   // called when the JFrame is closing
  160.   {  running = false;   }
  161.  
  162.   // ----------------------------------------------
  163.  
  164.  
  165.   private void testPress(int x, int y)
  166.   {
  167.  
  168.   }  // end of testPress()
  169.  
  170.  
  171.   public void run()
  172.   /* The frames of the animation are drawn inside the while loop. */
  173.   {
  174.     long beforeTime, afterTime, timeDiff, sleepTime;
  175.     long overSleepTime = 0L;
  176.     int noDelays = 0;
  177.     long excess = 0L;
  178.     Graphics g;
  179.  
  180.     //gameStartTime = J3DTimer.getValue();
  181.     gameStartTime=System.currentTimeMillis();
  182.     prevStatsTime = gameStartTime;
  183.     beforeTime = gameStartTime;
  184.  
  185.     running = true;
  186.  
  187.     while(running) {
  188.       gameUpdate();
  189.       gameRender();   // render the game to a buffer
  190.       paintScreen();  // draw the buffer on-screen
  191.  
  192.       //afterTime = J3DTimer.getValue();
  193.       afterTime=System.currentTimeMillis();
  194.       timeDiff = afterTime - beforeTime;
  195.       sleepTime = (period - timeDiff) - overSleepTime;  
  196.  
  197.       if (sleepTime > 0) {   // some time left in this cycle
  198.         try {
  199.           Thread.sleep(sleepTime/1000000L);  // nano -> ms
  200.         }
  201.         catch(InterruptedException ex){}
  202.         //overSleepTime = (J3DTimer.getValue() - afterTime) - sleepTime;
  203.         overSleepTime = (System.currentTimeMillis() - afterTime) - sleepTime;
  204.       }
  205.       else {    // sleepTime <= 0; the frame took longer than the period
  206.         excess -= sleepTime;  // store excess time value
  207.         overSleepTime = 0L;
  208.  
  209.         if (++noDelays >= NO_DELAYS_PER_YIELD) {
  210.           Thread.yield();   // give another thread a chance to run
  211.           noDelays = 0;
  212.         }
  213.       }
  214.  
  215.       //beforeTime = J3DTimer.getValue();
  216.       beforeTime = System.currentTimeMillis();
  217.       /* If frame animation is taking too long, update the game state
  218.          without rendering it, to get the updates/sec nearer to
  219.          the required FPS. */
  220.       int skips = 0;
  221.       while((excess > period) && (skips < MAX_FRAME_SKIPS)) {
  222.         excess -= period;
  223.         gameUpdate();    // update state but don't render
  224.         skips++;
  225.       }
  226.       framesSkipped += skips;
  227.  
  228.       storeStats();
  229.     }
  230.  
  231.     printStats();
  232.     System.exit(0);   // so window disappears
  233.   } // end of run()
  234.  
  235.  
  236.  
  237.   private void gameUpdate()
  238.   { if (!isPaused && !gameOver){}
  239.      
  240.   }  // end of gameUpdate()
  241.  
  242.  
  243.   private void gameRender()
  244.   {
  245.     if (dbImage == null){
  246.       dbImage = createImage(pWidth, pHeight);
  247.       if (dbImage == null) {
  248.         System.out.println("dbImage is null");
  249.         return;
  250.       }
  251.       else
  252.         dbg = dbImage.getGraphics();
  253.     }
  254.  
  255.     // clear the background
  256.     dbg.setColor(Color.white);
  257.     dbg.fillRect(0, 0, pWidth, pHeight);
  258.  
  259.     dbg.setColor(Color.blue);
  260.     dbg.setFont(font);
  261.  
  262.     // report frame count & average FPS and UPS at top left
  263.     // dbg.drawString("Frame Count " + frameCount, 10, 25);
  264.     dbg.drawString("Average FPS/UPS: "+(int)(averageFPS) + ", " +
  265.                                 (int)(averageUPS), 20, 25);  // was (10,55)
  266.  
  267.     dbg.setColor(Color.black);
  268.  
  269.     // draw game elements: the obstacles and the worm
  270.     //obs.draw(dbg);
  271.     //fred.draw(dbg);
  272.     world.draw(dbg);
  273.  
  274.     if (gameOver)
  275.       gameOverMessage(dbg);
  276.   }  // end of gameRender()
  277.  
  278.  
  279.   private void gameOverMessage(Graphics g)
  280.   // center the game-over message in the panel
  281.   {
  282.     String msg = "Game Over. Your Score: " + score;
  283.     int x = (pWidth - metrics.stringWidth(msg))/2;
  284.     int y = (pHeight - metrics.getHeight())/2;
  285.     g.setColor(Color.red);
  286.     g.setFont(font);
  287.     g.drawString(msg, x, y);
  288.   }  // end of gameOverMessage()
  289.  
  290.  
  291.   private void paintScreen()
  292.   // use active rendering to put the buffered image on-screen
  293.   {
  294.     Graphics g;
  295.     try {
  296.       g = this.getGraphics();
  297.       if ((g != null) && (dbImage != null))
  298.         g.drawImage(dbImage, 0, 0, null);
  299.       // Sync the display on some systems.
  300.       // (on Linux, this fixes event queue problems)
  301.       Toolkit.getDefaultToolkit().sync();
  302.       g.dispose();
  303.     }
  304.     catch (Exception e)   // quite commonly seen at applet destruction
  305.     { System.out.println("Graphics error: " + e);  }
  306.   } // end of paintScreen()
  307.  
  308.  
  309.  
  310.   private void storeStats()  {
  311.     frameCount++;
  312.     statsInterval += period;
  313.  
  314.     if (statsInterval >= MAX_STATS_INTERVAL) {     // record stats every MAX_STATS_INTERVAL
  315.       //long timeNow = J3DTimer.getValue();
  316.         long timeNow=System.currentTimeMillis();
  317.       timeSpentInGame = (int) ((timeNow - gameStartTime)/1000000000L);  // ns --> secs
  318.       wcTop.setTimeSpent( timeSpentInGame );
  319.  
  320.       long realElapsedTime = timeNow - prevStatsTime;   // time since last stats collection
  321.       totalElapsedTime += realElapsedTime;
  322.  
  323.       double timingError =
  324.          ((double)(realElapsedTime - statsInterval) / statsInterval) * 100.0;
  325.  
  326.       totalFramesSkipped += framesSkipped;
  327.  
  328.       double actualFPS = 0;     // calculate the latest FPS and UPS
  329.       double actualUPS = 0;
  330.       if (totalElapsedTime > 0) {
  331.         actualFPS = (((double)frameCount / totalElapsedTime) * 1000000000L);
  332.         actualUPS = (((double)(frameCount + totalFramesSkipped) / totalElapsedTime)
  333.                                                              * 1000000000L);
  334.       }
  335.  
  336.       // store the latest FPS and UPS
  337.       fpsStore[ (int)statsCount%NUM_FPS ] = actualFPS;
  338.       upsStore[ (int)statsCount%NUM_FPS ] = actualUPS;
  339.       statsCount = statsCount+1;
  340.  
  341.       double totalFPS = 0.0;     // total the stored FPSs and UPSs
  342.       double totalUPS = 0.0;
  343.       for (int i=0; i < NUM_FPS; i++) {
  344.         totalFPS += fpsStore[i];
  345.         totalUPS += upsStore[i];
  346.       }
  347.  
  348.       if (statsCount < NUM_FPS) { // obtain the average FPS and UPS
  349.         averageFPS = totalFPS/statsCount;
  350.         averageUPS = totalUPS/statsCount;
  351.       }
  352.       else {
  353.         averageFPS = totalFPS/NUM_FPS;
  354.         averageUPS = totalUPS/NUM_FPS;
  355.       }
  356. /*
  357.       System.out.println(timedf.format( (double) statsInterval/1000000000L) + " " +
  358.                     timedf.format((double) realElapsedTime/1000000000L) + "s " +
  359.                     df.format(timingError) + "% " +
  360.                     frameCount + "c " +
  361.                     framesSkipped + "/" + totalFramesSkipped + " skip; " +
  362.                     df.format(actualFPS) + " " + df.format(averageFPS) + " afps; " +
  363.                     df.format(actualUPS) + " " + df.format(averageUPS) + " aups" );
  364. */
  365.       framesSkipped = 0;
  366.       prevStatsTime = timeNow;
  367.       statsInterval = 0L;   // reset
  368.     }
  369.   }  // end of storeStats()
  370.  
  371.  
  372.  
  373.   private void printStats()
  374.   {
  375.     System.out.println("Frame Count/Loss: " + frameCount + " / " + totalFramesSkipped);
  376.     System.out.println("Average FPS: " + (int)averageFPS);
  377.     System.out.println("Average UPS: " + (int)(averageUPS));
  378.     System.out.println("Time Spent: " + timeSpentInGame + " secs");
  379.    // System.out.println("Boxes used: " + obs.getNumObstacles());
  380.   }  // end of printStats()
  381.  
  382. }  // end of WormPanel class
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement