Reputation: 17
I'm doing this bouncing ball problem and I have was given this formula: (velocity) vx = v0*cos(angle). and (x-position) x = v0*cos(angle)*t. However, I cannot get the ball to bounce properly. The problem is that after the ball hits the right vertical wall, it starts to bounce inside certain range on the right-hand-side of the window. (y and vy shouldn't matter in this case.) How can I fix this weird bouncing problem to make it bounce property in the x direction?
public class GamePanel2 extends JPanel implements KeyListener, ActionListener{
Timer tm = new Timer(60, this); //this refers to the ActionListener
public int score = 0;
public GamePanel2(){
addKeyListener(this);
setFocusable(true);
setBackground(Color.BLACK);
}
public int getScore() {
return score;
}
public double v0 = 100;
public double t = 0;
public double angle = Math.PI/2.5;
public double x = 0;
public double y = 0;
public double vx =0;
public double vy = 0;
public int move = 0;
public int paddlex =0;
public void paintComponent(Graphics g){
int h = getHeight();
int w = getWidth();
vx = v0*Math.cos(angle);
vy = v0*Math.sin(angle);
Graphics2D g2d = (Graphics2D)g;
g2d.translate(0.0,h);
g2d.scale(1.0, -1.0);
//ball
g2d.setColor(Color.GREEN);
g2d.fillOval((int)Math.round(x), (int)Math.round(y+6), 20, 20);
//paddle
g2d.setColor(Color.RED);
g2d.fillRect(paddlex + move, 0, 60, 6);
repaint();
}
//KeyListener methods
@Override
public void keyPressed(KeyEvent arg0) {
if(arg0.getKeyCode() == KeyEvent.VK_SPACE){
tm.start();
}
else if(arg0.getKeyCode()==KeyEvent.VK_ESCAPE){
tm.stop();
}
if(arg0.getKeyCode() == KeyEvent.VK_RIGHT){
move += 30;
}
//if pressed right key
if(arg0.getKeyCode() == KeyEvent.VK_LEFT){
move -= 30;
}
repaint();
}
@Override
public void keyReleased(KeyEvent arg0) {
}
@Override
public void keyTyped(KeyEvent arg0) {
}
@Override
public void actionPerformed(ActionEvent arg0) {
t = 0.2;
vy -= 9.8;
x += vx;
y += (vy)*t-(t*t*9.8)*0.5;
if( x<= 0){
vx = v0*Math.cos(angle);
}
if (x>=getWidth()-20){
vx =-(v0*Math.cos(angle));
}
repaint();
}
}
Upvotes: 0
Views: 609
Reputation: 47020
You're not even close. The differential equations of motion for a ball with gravity supplying the only force are
d^2x/dt^2 = -9.8 and d^2x/dt^2 = 0
You need to integrate these equations. For this purpose, you need to get rid of the second degree differentials by introducing a new variable:
dv_y/dt = -9.8 and dv_x/dt = 0
dy/dt = v_y dx/dt = v_x
With Euler forward differences (the simplest possible integration method), this becomes:
v_y[i+i] = v_y[i] + h * -9.8
y[i+1] = y[i] + h * v_y[i]
v_x[i+1] = v_x[i] + h * 0 // x-velocity is constant!
x[i+1] = x[i] + h * v_x[i]
When the ball encounters a vertical wall with a perfectly elastic collision, the x velocity instantly changes sign. When it hits the floor or ceiling, the y velocity changes sign.
Your formula provides only the initial values of v_x
and v_y
. All x and y values after are results of the above Euler equations. In pseudocode it will look something like this:
// Initialize the velocity components.
vx = v0 * cos(theta)
vy = v0 * sin(theta)
// Initialize the position of the ball.
x = R // in the corner of the first quadrant
y = R
// Choose a time increment.
h = < a very small number of seconds >
// Start the clock.
t = 0
while (t < END_OF_SIMULATION) {
draw_ball(x,y)
x = x + h * vx;
y = y + h * vy;
vy = vy - h * 9.8;
// Check for bounces
// Assumes box has corners (0,0), (W,H)
if ((vx < 0 and x < r) or (vx > 0 && x > W-r)) x = -x;
if ((vy < 0 and y < r) or (vy > 0 && y > H-r)) y = -y;
t = t + h
}
Note that that 9.8 means that the units are meters and seconds. You need to scale pixels in the Java window and use a timer to get a realistic result.
To roughly simulate lossy collision, you can steal some velocity on every bounce:
x = -<a number a bit less than 1.0> * x and
y = -<a number a bit less than 1.0> * y
With these, the ball will slow down a bit every time it hits a wall.
Upvotes: 1
Reputation: 7576
I can't find where you're changing the angle after detecting a bounce. I also don't see bounds checking for all four sides of the windows the ball is in.
There's a related bug you might run into where there's a double bounce in a corner that leaves the ball outside the window after all the calculations are done. Think about ways to handle that case.
Upvotes: 0