How to pause and resume a simple game in Java

Jason4Ever picture Jason4Ever · Nov 28, 2011 · Viewed 16k times · Source

i made simple game by java , it's about "tennis background" and "tennis ball" , and the ball is randomally move automatically ,

my game consist of two file , 1st file fore Jpanel , and 2nd file for JFrame ,

my question is : i need to control of "stopping and resuming" the ball by clicking the mouse , i tried to put wait() during thread running loop , but it's faild , i don't know what is the reason ! , so please review my code and then tell me what is the wrong , and what is the true method of "pause&resume" thread in my simple game !

tennis.java file (which contain the thread):

/*
 * tennis.java
 *
 * Created on Nov 15, 2011, 3:35:28 PM
 */
package io;

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;


public class tennis extends javax.swing.JPanel implements Runnable{

    BufferedImage ball;
    BufferedImage bg;
    int ball_h = 0;
    int ball_w = 0;
    int height = 0;
    int width  = 0;
    int yPos   = -1;
    int xPos   = 10;
    int pause  = 20;

    // Move Speed
    int xMov   = 5;
    int yMov   = 10;
    boolean clicked = false;
    int play    =   0;

    Thread runner;

    /** Creates new form tennis */
    public tennis() throws IOException {

        ball = ImageIO.read(new File("tennis/ball.png"));
        bg = ImageIO.read(new File("tennis/bg.jpg"));
        ball_h = 50;
        ball_w = 50;
        height = 600 - ball_h;
        width  = 800  - ball_w;

        runner = new Thread(this);
        runner.start();

    }

    public void start(){
       if(play == 0){

           play     =   1;
           clicked = true;

       }else{
           play    =  0;
           clicked = true;
       }

       System.out.println(play);
    }

    public void stop(){
        runner = null;
    }




    @Override
    public void paint(Graphics g){
        Graphics2D g2D  =   (Graphics2D) g;

        g2D.drawImage(bg, 0, 0, 800,600, this);
        g2D.drawImage(ball, xPos, yPos,50,50, this);
    }


    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
    private void initComponents() {

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 400, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 300, Short.MAX_VALUE)
        );
    }// </editor-fold>                        
    // Variables declaration - do not modify                     
    // End of variables declaration                   

    @Override
    public void run() {

        while(runner == runner){



                    if(xPos >= (width))
                        {
                           xMov   *= -1;   
                        }



                           xPos   += xMov;

                    if(xPos < 1)
                        {
                           xMov   *= -1;   
                        }                

                    if(yPos >= (height-ball_h))
                        {
                            yMov    *= -1 ;
                        }



                            yPos    += yMov;

                     if(yPos < 1)
                        {
                            yMov    *= -1 ;
                        }

                    repaint();



                    try {
                        if(play == 1){
                            Thread.sleep(pause);
                        }else{
                            synchronized(this){
                                while(play == 0){
                                wait();
                              }
                            }
                        }

                    } catch (InterruptedException ex) {
                        Logger.getLogger(tennis.class.getName()).log(Level.SEVERE, null, ex);
                    }

        }  
    }

}

Tennis3D.java file(frame for starting the game and define the thread) :

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * Tennis3D.java
 *
 * Created on Nov 15, 2011, 3:42:42 PM
 */
package io;

import io.tennis;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;


public class Tennis3D extends javax.swing.JFrame implements MouseListener{

    tennis tennis;

    /** Creates new form Tennis3D */
    public Tennis3D() {
        super("Tennis3D");
        setSize(800,600);


        try {
            tennis = new tennis();
            add(tennis);
            tennis.addMouseListener(this);
        } catch (IOException ex) {
            Logger.getLogger(Tennis3D.class.getName()).log(Level.SEVERE, null, ex);
        }


        setVisible(true);

    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
    private void initComponents() {

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 400, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 300, Short.MAX_VALUE)
        );

        pack();
    }// </editor-fold>                        

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
       Tennis3D tennis = new Tennis3D();
    }
    // Variables declaration - do not modify                     
    // End of variables declaration                   

    @Override
    public void mouseClicked(MouseEvent e) {
       tennis.start();
    }

    @Override
    public void mousePressed(MouseEvent e) {

    }

    @Override
    public void mouseReleased(MouseEvent e) {

    }

    @Override
    public void mouseEntered(MouseEvent e) {

    }

    @Override
    public void mouseExited(MouseEvent e) {

    }
}

Thank you for your help :)

Answer

jeff picture jeff · Nov 28, 2011

This is piggy-backing on what Nerdtron wrote in the comment above. Typically a game loop looks like this

 while (!game.isOver())
 {
      if (!game.isPaused())
           game.update()  // this moves your ball, players, etc
 }