Question

I've created a Bouncing Ball application in in Java. The goal is to have a ball appear on mousePressed() and have it bounce off the walls without leaving the frame. Only one Ball One Thread, should be easy.. My problem is that every time I click to make the ball appear it gets faster and I have no idea why. Can somebody help me please. PS: I'm new to threads.

import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class MyFrame extends JPanel {
public int xPos, yPos, xDir = 3, yDir = 4;
public int diameter = 50;

public MyFrame(){
    final JFrame thisFrame = new JFrame();
    thisFrame.add(this);
    thisFrame.setTitle("Bouncing Ball");
    thisFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    thisFrame.setLocationRelativeTo(null);
    thisFrame.setSize(500, 500);

    this.addMouseListener(new MouseListener() {
        @Override
        public void mouseReleased(MouseEvent e) {}
        @Override
        public void mousePressed(MouseEvent e) {
            xPos = e.getX();
            yPos = e.getY();
            Thread t = new Thread() {
                @Override
                public void run() {
                    while(true){
                        try{
                            Thread.sleep(10);
                        }catch(Exception e){};
                        xPos += xDir;
                        yPos += yDir;

                        if(xPos + diameter >= thisFrame.getWidth() - 25 || xPos <= 0) xDir = -xDir;
                        if(yPos + diameter >= thisFrame.getHeight() - diameter || yPos <= 0) yDir = -yDir;
                        repaint();
                    }
                } 
            };
            t.start();
        }
        @Override
        public void mouseExited(MouseEvent e) {}
        @Override
        public void mouseEntered(MouseEvent e) {}
        @Override
        public void mouseClicked(MouseEvent e) {}
        });

    thisFrame.setVisible(true);

    }
    public void paintComponent(Graphics g) { 
        super.paintComponent(g); 
        g.fillOval(xPos, yPos, diameter, diameter); 
    }
}
public class MyMain{

    public static void main(String[] args) {
        new MyFrame();
    }

}
Was it helpful?

Solution

Every time you click, you are starting a new Thread, which means you have another thread updating the x/y positions.

For example, 1 thread means your update the x/p once per sync, 2 means you're updating the x/y position at least twice per cycle and this just gets compounded each time you add a new thread.

A better solution would be to start the Thread at some time earlier and then use a List to maintain the position and direction of the ball.

This will require a little but synchronisation to keep things safe

FYI a delay of 40 milliseconds is roughly 25 fps, 16 milliseconds is roughly 60 fps. IMHO, for what you are doing, 10 milliseconds seems excessive...

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top