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.MouseListen er;
import java.awt.event.MouseMotion Listener;
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.addMouseListen er(handler );
bouncePanel.addMouseMotion Listener(h andler);
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(Co lor.white) ;
bufferGraphics.fillRect(0, 0, size.width, size.height); // clear the buffer
bufferGraphics.setColor(Co lor.blue);
bufferGraphics.fillOval(x - r, y - r, r * 2, r * 2); // draw the circle
bufferGraphics.setColor(Co lor.red);
bufferGraphics.fillRect(37 5,batY,5,3 0); // paint player1's bat
/* bufferGraphics.setColor(Co lor.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(thi s);
}
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.setDefaultClos eOperation (JFrame.EX IT_ON_CLOS E);
application.setVisible(tru e);
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 :-)
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.MouseListen
import java.awt.event.MouseMotion
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(
container.add(bouncePanel,
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.addMouseListen
bouncePanel.addMouseMotion
bouncePanel.setMinimumSize
buffer = new BufferedImage(size.width, size.height, BufferedImage.TYPE_INT_RGB
bufferGraphics = buffer.getGraphics();
setSize(size);
}
public void paint(Graphics g)
{
bufferGraphics.setColor(Co
bufferGraphics.fillRect(0,
bufferGraphics.setColor(Co
bufferGraphics.fillOval(x - r, y - r, r * 2, r * 2); // draw the circle
bufferGraphics.setColor(Co
bufferGraphics.fillRect(37
/* bufferGraphics.setColor(Co
bufferGraphics.fillRect(15
// 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
{
// 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(thi
}
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.setDefaultClos
application.setVisible(tru
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
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
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.
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.
ASKER
thank you
ASKER
could u tell me more about what you mean by geometric details?
thanks