umer selmani
umer selmani

Reputation: 182

Bouncing balls do not move as expected

I have this bouncing balls app.

The first problem I face is, when I initiate all 3 balls, none of them moves, or only 1 moves.

The other issue I face is that, the ball(s) doesn't bounce from the upper wall of the frame. Am I missing something or doing something wrong?

import javax.swing.JFrame;
        import javax.swing.JPanel;
        import java.awt.*;

public class  Bouncing_Balls extends JPanel {

    //variables for the object1
    int x= 0,y=0;
    int angleX = 1 , angleY=1;

    int speed = 5;

    //method to move the ball
    private void move(){
        if (x+angleX<0){
            angleX=speed;
        }else if (x+angleX > getWidth()-50){
            angleX=-speed;
        }else if (y+angleY <0){
            angleY=-speed;
        }else if (y+angleY > getHeight()-50) {
            angleY = -speed;
        }
        x=x+angleX;
        y=y+angleY;
    }

    //@Override
    //public void paint(Graphics g){
     //   super.paint(g);
      //  g.fillOval(x,y,50,50);
    //}

    int x1= 0,y1=0;
    int angleX1 = 1 , angleY1=1;

    int speed1 = 15;
    //variables for the object2

    private void move1(){
        if (x1+angleX1<0){
            angleX1=speed1;
        }else if (x+angleX1 > getWidth()-75){
            angleX1=-speed1;
        }else if (y1+angleY1 <0){
            angleY1=-speed1;
        }else if (y1+angleY1 > getHeight()-75) {
            angleY1 = -speed1;
        }
        x1=x1+angleX1;
        y1=y1+angleY1;
    }

    int x2= 0,y2=0;
    int angleX2 = 1 , angleY2=1;

    int speed2 = 15;
    //variables for the object2

    private void move2(){
        if (x2+angleX2<0){
            angleX2=speed2;
        }else if (x+angleX2 > getWidth()-25){
            angleX2=-speed2;
        }else if (y2+angleY2 <0){
            angleY2=-speed2;
        }else if (y2+angleY2 > getHeight()-25) {
            angleY2 = -speed2;
        }
        x1=x2+angleX2;
        y1=y2+angleY2;
    }


    @Override
    public void paint(Graphics g){
        super.paint(g);
        g.fillOval(x,y,50,50);
        g.fillOval(x1,y1,75,75);
        g.fillOval(x2,y2,25,25);
    }

    public static void main (String[] args) throws InterruptedException{

        JFrame frame = new JFrame("Bouncing Ball!");
        Bouncing_Balls app = new Bouncing_Balls();
        frame.add(app);
        frame.setSize(400,400);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        while (true){
            app.move();
            app.move1();
            app.move2();
            app.repaint();
            Thread.sleep(10);
        }
    }


}

Upvotes: 0

Views: 116

Answers (1)

Nexevis
Nexevis

Reputation: 4667

This might not fix your problem exactly as I have not used JFrame much to be able to quickly pinpoint your issue, but below will show an example of how to simplify the way you have written your code greatly and in turn make it easier to debug if anything goes wrong (posting this because you specifically requested an example of my comment).

Here is the example you asked for below:

public class Bouncing_Balls extends JPanel {

    int x, y;
    int angleX, angleY;
    int speed;
    int moveValue;

    public Bouncing_Balls(int angleX, int angleY, int speed, int moveValue) {
        this.angleX = angleX;
        this.angleY = angleY;
        this.speed = speed;
        this.moveValue = moveValue;
        this.x = 0;
        this.y = 0;
    }

    //method to move the ball
    private void move(){
        if (x+angleX<0){
            angleX=speed;
        }else if (x+angleX > getWidth() - moveValue){
            angleX=-speed;
        }else if (y+angleY <0){
            angleY=-speed;
        }else if (y+angleY > getHeight() - moveValue) {
            angleY = -speed;
        }
        x=x+angleX;
        y=y+angleY;
    }

    @Override
    public void paint(Graphics g){
        super.paint(g);
        g.fillOval(x, y, moveValue, moveValue);
    }

    public static void main (String[] args) throws InterruptedException{

        JFrame frame = new JFrame("Bouncing Ball!");
        Bouncing_Balls ball1 = new Bouncing_Balls(1, 1, 5, 50); //Pass the paremeters you want set (angleX, angleY, speed, moveValue)
        Bouncing_Balls ball2 = new Bouncing_Balls(1, 1, 15, 75);
        Bouncing_Balls ball3 = new Bouncing_Balls(1, 1, 15, 25); 
        frame.add(ball1);
        frame.add(ball2);
        frame.add(ball3);
        frame.setSize(400,400);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        while (true){
            ball1.move();
            ball2.move();
            ball3.move();
            frame.repaint();
            Thread.sleep(10);
        }
    }
}

The main things to notice are the removal of the different variables and different move methods by utilizing a constructor that sets your class variable values rather than hard coding in each different case into the class Bouncing_Balls itself.

Additionally I moved the value you were changing in the move() method (aka the 50, 75 or 25) into the constructor and a class variable so you can declare by how much you want the ball to "move".

Lastly, since the Bouncing_Balls now splits the balls into different objects, you now need to use the constructor three times with Bouncing_Balls ball1 = new Bouncing_Balls(1, 1, 5, 50) and changing the values.

Overall I have attempted to keep this exactly the same as the code you have posted, only refactored for readability, so it should work exactly the same but will now be much easier to add new balls or fix current problems.

Lastly, as a side note, I recommend following proper Java naming conventions, as Bouncing_Balls should be named BouncingBalls in Java, without the underscore.

Upvotes: 1

Related Questions