[Last Call] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 908
  • Last Modified:

Ping Pong

i have been working on a ping pong game for some time now but it is still not working as smoothly as I would like it.

The ball will not bounce off the left side bat. I simply changed the formula i had used to get it to bounce off the right hand side bat but it won't work.
The ball doesn't appear to actually bounce on a jPanel but rather on top of it.
When i add another panel, with say a drop down menu and i then try to use the arrow keys to move the bat up or down instead of moving the bat it moves through the drop down list.

i have several different version of code which show different ways in which I have tried to get this game to work properly. If any other versions are needed to be seen. :-)

code
=======================================================================================
import java.awt.*;
import java.awt.image.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;

public class PingPong extends JFrame implements Runnable
{
     int ballX = 150, ballY = 100, r = 5; // Position and radius of the circle

     int dx = 8, dy = 5; // Trajectory of circle
     
     int batY1 = 20, batY2=30, batMin, batMax;
     
     int player1Score = 0, player2Score = 0;
     
     String playerOneScore, playerTwoScore;

     Dimension size; // The size of the frame

     Image buffer; // The off-screen image for double-buffering

     Graphics bufferGraphics; // A Graphics object for the buffer

     Thread animator; // Thread that performs the animation

     boolean please_stop; // A flag asking animation thread to stop
     
     int DELAY = 50; // Delay in milliseconds
      
       JPanel bouncePanel;
       JPanel optionsPanel;
//       JRadioButton slow, medium, fast;
      
     
     public PingPong()
       {
             super("Ping Pong");
               Container container = getContentPane();
               repaint();
              bouncePanel = new JPanel();
               bouncePanel.setBackground(Color.white);
              container.add(bouncePanel, "Center");
             
              optionsPanel = new JPanel();
              optionsPanel.setBackground(Color.blue);
      /*        slow = new JRadioButton();
              medium = new JRadioButton();
              medium = new JRadioButton();
              medium = new JRadioButton();
              fast = new JRadioButton();*/              
              container.add(optionsPanel, BorderLayout.EAST);
              /*optionsPanel.add(slow);
              optionsPanel.add(medium);
              optionsPanel.add(fast);*/
            //  setSize(400,200);
            
              setVisible(true);
             
              batMin = 30;                        //minimum bat's x-position
              batMax = 180;                        //maximum bat's y-position
             
              size = new Dimension(400, 200);
                       
              //handlers to deal with events
              MouseHandler handler = new MouseHandler();
              bouncePanel.addMouseListener(handler);
              bouncePanel.addMouseMotionListener(handler);              
              KeyHandler handler2 = new KeyHandler();
              bouncePanel.addKeyListener(handler2);
             
             
              //bouncePanel.setMinimumSize(size);
             

          buffer = new BufferedImage(size.width, size.height, BufferedImage.TYPE_INT_RGB);
          bufferGraphics = buffer.getGraphics();
          setSize(size);
         
          setSize(600,200);
          show();
     }
     
     public void paint(Graphics g)
       {
          bufferGraphics.setColor(Color.green);
          bufferGraphics.fillRect(0, 0, size.width, size.height); // clear the buffer
          bufferGraphics.setColor(Color.blue);
          bufferGraphics.fillOval(ballX - r, ballY - r, r * 2, r * 2); // draw the circle
                  
              bufferGraphics.setColor(Color.red);
              bufferGraphics.fillRect(375,batY1,5,30); // paint player1's bat
              bufferGraphics.setColor(Color.blue);
            bufferGraphics.fillRect(15,batY2,5,30);// paint player2's bat
                
                // Then copy the off-screen buffer onto the screen
          g.drawImage(buffer, 0, 0, this);

              String playerOneScore = Integer.toString(player1Score);
              String playerTwoScore = Integer.toString(player2Score);
             
              if (player2Score == 0)  
              {
                    g.drawString("Player Two Score: "+playerTwoScore,10,40);
              }
              else
                    g.drawString("Player Two Score: "+playerTwoScore,10,40);
                    
              if (player1Score == 0)
              {
                    g.drawString("Player One Score: "+playerOneScore,290,40);
              }
              else
              g.drawString("Player One Score: "+playerOneScore,290,40);      
     }

     public void run()
       {
             repaint();//if this isnt here the green background doesn't appear till the
                           //next repaint
                           
          while (!please_stop)
              {
               // Bounce the circle if we've hit an edge.
               if ((ballX - r + dx < 0) || (ballX + r + dx > size.width))
                    dx = -dx;
               if ((ballY - r + dy < 37) || (ballY + r + dy > size.height))
                    dy = -dy;

               // Move the circle.
               ballX += dx;
               ballY += dy;

               repaint(ballX - r - dx, ballY - r - dy, 2 * r, 2 * r); // paint over old position of circle
                                                                                                                                       // circle
               repaint(ballX - r, ballY - r, 2 * r, 2 * r); // repaint new position of circle
               
               // if the ball hits player1's bat change the ball direction.
               if (ballX > 370 && ballY >= batY1 )
               {
                              
                              if(((ballY + 6) > batY1) && ((batY1 + 31) > ballY))
                              {
                               dx = -dx;
                              }
                        }
                        
                        //if the ball hits player2's bat change the ball direction
                        if (ballX < 30 && ballY >= batY2)
                        {
                              if(((ballY+6) > batY2) && ((batY2 + 31) > ballY))
                              {
                                    dx = -dx;;
                              }
                        }
                        
                        //if ball hits left side wall add point to player2
                        if (ballX<= 12)
                        {
                              player1Score ++;
                              repaint();
                     }
                     if(ballX>=385)
                     {
                           player2Score ++;
                           repaint();
                     }
                     
                     
               try
                     {
                    Thread.sleep(DELAY);
               }
               catch(InterruptedException e)
                     {//blank
               }
          }
          animator = null;
     }

     public void start()
       {
          if (animator == null)
              {
               please_stop = false;
               animator = new Thread(this);
               animator.start();
          }
     }

     // Stop the animation thread
     public void stop()
       {
          please_stop = true;
     }
 
             //move player's bat up
      protected void MoveUp(int y)
      {            
            if ( y > batMin)
            {
                  batY1 = y;
                  repaint();
            }
            else
            {
                  batY1 = batMin;
                  repaint();
            }
      }
      
      //move player's bat down      
      protected void MoveDown(int y)
      {                  
            if ( y < batMax)
            {
                  batY1 = y;
                  repaint();
            }
            else
            {
                  batY1 = batMax;
                  repaint();
            }
      }
      
       private class MouseHandler implements MouseListener, MouseMotionListener
       {
             public MouseHandler()
             {
                  addMouseListener(this);
                  addMouseMotionListener(this);
             }
      
           public void mouseClicked(MouseEvent e)
           {
           }
           public void mouseEntered(MouseEvent e)
           {
           }
           public void mousePressed(MouseEvent e)           
             {
                  if (animator != null)
                        please_stop = true; // if running request a stop
                  else
                        start(); // otherwise start it.
           }
           public void mouseReleased(MouseEvent e)             
             {
           }
           public void mouseExited(MouseEvent e)
           {
           }
             public void mouseDragged(MouseEvent e)
             {
             }
             public void mouseMoved(MouseEvent e)
             {
                  int y = e.getY();
                  if ( (y - batY1) > 0 )
                        MoveDown(y);
                  else
                        MoveUp(y);
             }
      
       }
      
       private class KeyHandler implements KeyListener
       {
             public KeyHandler()
             {
                   addKeyListener(this);
             }
             public void keyPressed(KeyEvent event)
             {                   
                  switch (event.getKeyCode())
                  {
                        case KeyEvent.VK_DOWN:
                        if (batY2 < batMax)
                        {
                              batY2 = batY2 + 10;
                              repaint();
                        }
                        else
                        {
                              batY2 = batMax;
                              repaint();
                        }
                        break;
                        case KeyEvent.VK_UP:
                        if (batY2 > batMin)
                        {
                              batY2 = batY2 - 10;
                              repaint();
                        }
                        else
                        {
                              batY2 = batMin;
                              repaint();
                        }
                        break;
                  }
             }
             public void keyReleased(KeyEvent event)
             {
             }
             public void keyTyped(KeyEvent event)
             {
             }
       }
      
       private class CheckBoxHandler
       {
             
       }
      
             
     public static void main(String args[])
       {
          PingPong application = new PingPong();
          application.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          application.setVisible(true);
          application.start();
     }
}
0
pete420
Asked:
pete420
  • 4
  • 3
  • 2
  • +1
2 Solutions
 
CEHJCommented:
Seems to work on on my machine ...
0
 
pete420Author Commented:
sorry, i had that question typed up and saved for when i had enough points to post (was waiting on a refund) and I pasted it in forgettin i had fixed the bat problem.

The problems im left with is :

when the radio buttons are un-commented and added to the program, the bat can no longer be moved by Keys.

i have a few other queries but i need to find the code to submit.

pete :-)
0
 
CEHJCommented:
I'll try to have a look a bit later:

>>i have a few other queries but i need to find the code to submit.

Please try to post a link to the code if possible as the above was quite long ;-)
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
pete420Author Commented:
thanks, i should be online for an hour or so yet :-)

will post code to:

http://www.newwavesound.co.uk/PingPong

thanks
0
 
pete420Author Commented:
ah yes, the other problem was how to add another ball in.


public void mouseClicked(MouseEvent e)
{
     PingPong.animator = new Thread();
     PingPong.animator.start();
}


this produces the error:
Non-Static variable animator cannot be referenced from a static context

the full code is available at the above address
0
 
gnoonCommented:
>when the radio buttons are un-commented and added to the program, the bat can no longer be moved by Keys.

Sure, because of the focus is changed from the bouncePanel to a radio button, so the bouncePanel is no longer available to receive key press event. Instead of adding key listener to the bouncePanel, you can use the centralized focus manager (java.awt.KeyboardFocusManager) to listen for key press. Every key event will be grabbed by this class.

Try to add the code below to the last line of the PingPong constructor.

          KeyboardFocusManager fm = KeyboardFocusManager.getCurrentKeyboardFocusManager();
          fm.addKeyEventDispatcher(new KeyEventDispatcher()
          {
              public boolean dispatchKeyEvent(KeyEvent e)
              {
                  if(e.paramString().startsWith("KEY_PRESSED"))
                  {
                    System.out.println("Key "+e.getKeyCode()+" is pressed.");
                  }
                  return true;                    //no further action with regard to the KeyEvent
              }
          });

You can process keyPressed in this method !
0
 
gnoonCommented:
>ah yes, the other problem was how to add another ball in.
>public void mouseClicked(MouseEvent e)
>{
>     PingPong.animator = new Thread();
>     PingPong.animator.start();
>}

I dont think this code can add another ball.

>this produces the error:
>Non-Static variable animator cannot be referenced from a static context

That's because of you're not define 'animator' as a static variable, so you cant refer to it as a static variable.
0
 
pete420Author Commented:
thanks for reply:)

so how would a new ball be added by pressing the mouse?

pete
0
 
gnoonCommented:
>so how would a new ball be added by pressing the mouse?

In the paint() method, you'll see this code

bufferGraphics.fillOval(ballX - r, ballY - r, r * 2, r * 2); // draw the circle

The code is drawing the ball at the point (ballX,ballY) for every repaint() called.
Add the line of code will add a ball. Just provide another point (ballX2,ballY2) for it.
0
 
hkang042997Commented:
I thought I'd play around with your project as an excercise. I posted my java files at the following site if you're interested in seeing some changes I've made in your code:

http://home.earthlink.net/~hkang02/

Most of the changes are cosmetic, but some of the major changes are separating the bounce panel and the ball in separate classes. Some of the changes address some of your problems such as getting the keypress event.  This can be taken care of by the setFocusable(true) method of the JPanel.  Putting the scores in a different panel eliminates the flickering text.  The addition of methods of detecting collision handles different cases where the change in x (dx) is very large or small.  Added ability to add new ball when mouse clicked.

Some problems still need to be addressed.  One is that the key delay that exists in the OS is noticeable in the application.  I'd have to search to find a way to remove the delay when you hold down the up/down cursor to move the left bat.  Also, the game sometime does not respond to the mouse click. I might try giving each ball its own thread may make the game more responsive when many balls are added.

Thanks. It's been educational.
0

Featured Post

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

  • 4
  • 3
  • 2
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now