Link to home
Start Free TrialLog in
Avatar of pete420
pete420

asked on

ping pong

my ping pong program currently has a problem with the ball hitting the players bat. sometimes it hits, sometimes it hits behind it and sometimes it just misses it totally. The latter being the most common.

im sure its a calculation but i cant seem to work out whats wrong.

heres the 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 x = 150, y = 100, r = 5; // Position and radius of the circle

     int dx = 8, dy = 5; // Trajectory of circle
     
     int batY = 20, batMin, batMax;

     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
     
     final int DELAY = 50; // Delay in milliseconds
      
       JPanel bouncePanel;

     
     public PingPong()
       {
               Container container = getContentPane();
               
              bouncePanel = new JPanel();/*
               bouncePanel.setBackground(Color.red);
              container.add(bouncePanel, BorderLayout.CENTER);
              setSize(400,200);
              setVisible(true);*/
             
              batMin = 10;                        //minimum bat's x-position
              batMax = 180;                        //maximum bat's y-position
             
              size = new Dimension(400, 200);
                       
              MouseHandler handler = new MouseHandler();
              bouncePanel.addMouseListener(handler);
              bouncePanel.addMouseMotionListener(handler);
              bouncePanel.setMinimumSize(size);
             

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

     public void run()
       {
          while (!please_stop)
              {
               // Bounce the circle if we've hit an edge.
               if ((x - r + dx < 0) || (x + r + dx > size.width))
                    dx = -dx;
               if ((y - r + dy < 0) || (y + r + dy > size.height))
                    dy = -dy;

               // Move the circle.
               x += dx;
               y += dy;

               repaint(x - r - dx, y - r - dy, 2 * r, 2 * r); // repaint old position of
                                                                                                                                       // circle
               repaint(x - r, y - r, 2 * r, 2 * r); // repaint new position of circle
               
               if(x > 350 && y < batY )
               {
                              // if the ball hits the player's bat change the direction.
                              if( ((y + 5) > batY) && ((batY + 31) > y) )
                              {
                               dx = -dx;
                              }
                        }
               
               try
                     {
                    Thread.sleep(DELAY);
               }
               catch(InterruptedException e)
                     {
                    // ignore
               }
          }
          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;
     }

     // Allow the user to start and stop the animation by clicking
 
             //move player's bat up
      protected void MoveUp(int y)
      {            
            if ( y > batMin)
            {
                  batY = y;
                  repaint();
            }
            else
            {
                  batY = batMin;
                  repaint();
            }
      }
      //move player's bat down      
      protected void MoveDown(int y)
      {                  
            if ( y < batMax)
            {
                  batY = y;
                  repaint();
            }
            else
            {
                  batY = 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 - batY) > 0 ) MoveDown(y);
                  else MoveUp(y);
             }
      
       }
      
     public static void main(String args[])
       {
          PingPong application = new PingPong();
          application.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          application.setVisible(true);
          application.start();
     }
}

sorry for low points, its all i have. if the topic is still running when i get more i will add them in :-)
ASKER CERTIFIED SOLUTION
Avatar of hkang042997
hkang042997
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of pete420
pete420

ASKER

thanks that works alot better.

could u tell me more about what you mean by geometric details?

thanks
1)  It looks like you're drawing your bat at x=375, yet you're checking the x intersection at 350.  It makes it look as the the ball is bouncing off of the air.  It should be checked at 370 (or x + r).
2)  When the ball hits the bat from the rear, you need to check collision with the rear of the bat.  You need to check if dx is negative and then check if x <= BatX + batWidth.
3) There is another more elegant way of checking for collision.  Check out the class Ellipse2D.Double.  There is a method for checking if an ellipse intersects with a  rectangle of a specified dimension.
Avatar of pete420

ASKER

thank you