0

Here is the code:

public class BallGame extends JPanel implements Runnable {

    JPanel panel1 = new JPanel();

    private int ballX = 10, ballY = 110, ...;
    Thread aThread;
    int toRight=5; 
    int toLeft= -5; 
    int upWard=5; 
    int downWard= -5; 
    int widthBall, heightBall; 

    public BallGame(){
        game=true;
        aThread=new Thread(this);
        aThread.start();
    }

    public void paintComponent(Graphics g){
        setOpaque(false);
        super.paintComponent(g);

        g.setColor(Color.RED);
        g.fillOval(ballX, ballY, 7,7);
        g.setColor(Color.BLUE);
        g.fillOval(ballX + 15, ballY + 10, 7,7);
        g.setColor(Color.GREEN);
        g.fillOval(ballY - 10, ballY - 15, 7,7);

    }

    public void positionBall(int sx, int sy)
    {
        ballX = sx; 
        ballY = sy; 
        this.widthBall = this.getWidth();
        this.heightBall = this.getHeight();
        repaint();
    }
public void run() {
        boolean leftRight = false;
        boolean upDown = false;

        while(true){

            if(game){

            if (leftRight) 
            {
                ballX += toRight;
                if (ballX >= (widthBall - 5))
                    leftRight= false;
            }
            else
            {
                ballX += toLeft;
                if ( ballX <= 0)
                    leftRight =  true;
            }

            if (upDown) 
            {
                ballY += upWard;
                if (ballY >= (heightBall - 5))
                    upDown = false;

            }
            else
            {
                ballY += downWard;
                if ( ballY <= 0)
                    upDown =  true;
            }
            positionBall(ballX, ballY);

            try 
                {
                    Thread.sleep(70);
                }
                catch(InterruptedException ex)
                {

                }

I don't know if the part where I drew the balls was right. The balls move in the same path. How can I move them in different directions and how can I limit them inside the frame? I need this for our case study immediately. Thank you for your time!

  • 1
    Note that for Swing animations, you better use a `javax.swing.Timer` instead of your own `Thread`. [This](http://stackoverflow.com/q/9849950/1076463) is an example of a ball-moving application in Swing using the `Timer` class – Robin Mar 24 '13 at 12:46

1 Answers1

0

In order for the balls to move independently you need to treat them as 3 balls. The reason why they always go the same direction, is that you use the same delta, just inverting the sign of delta x and delta y, thus you will always keep the same speed, and bounce at 90 degrees.

In the code below which is basically the same as you had, I keep the state of each ball in separate instances, change speed of delta x and delta y once a side is touched, and use the Swing Timer which is a better approach with respect to timing in Swing, as pointed out by Robin above.

enter image description here

I have updated the example, so that 4 balls start in the middle, and they move away from each other. This should give you enough information to adapt it to your requirements. The picture below is produced by only allowing 10 iterations, and setting

ballGame.setOpaque(true);

enter image description here

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;

import javax.swing.*;

public class BallGame extends JPanel {

    private class Ball {
        private int x;
        private int y;
        private int width;
        private int height;
        private Color color;
        private boolean leftRight;
        private boolean upDown;
        private int deltaX;
        private int deltaY;

        Ball(Color color, int x, int y, int width, int height) {
            this(color, x, y, width, height, false, false);
        }

        Ball(Color color, int x, int y, int width, int height, boolean leftRight, boolean upDown) {
            this.color = color;
            this.x = x;
            this.y = y;
            this.width = width;
            this.height = height;
            this.leftRight = leftRight;
            this.upDown = upDown;
            updateDelta();
        }

        private void updateDelta() {
            final int minimumMovement = 5;
            final int maxExtra = 10;
            deltaY = minimumMovement + (int) (Math.random() * maxExtra);
            deltaX = minimumMovement + (int) (Math.random() * maxExtra);
        }

        public void positionBall() {
            if (leftRight) {
                x += deltaX;
                if (x >= (BallGame.this.getWidth() - width / 2)) {
                    leftRight = false;
                    updateDelta();
                }
            } else {
                x += -deltaX;
                if (x <= 0) {
                    leftRight = true;
                    updateDelta();
                }
            }

            if (upDown) {
                y += deltaY;

                upDown = !(y >= (BallGame.this.getHeight() - height / 2));
                if (y >= (BallGame.this.getHeight() - height / 2)) {
                    upDown = false;
                    updateDelta();
                }
            } else {
                y += -deltaY;
                if (y <= 0) {
                    upDown = true;
                    updateDelta();
                }
            }
        }

        public Color getColor() {
            return color;
        }

        public int getX() {
            return x;
        }

        public int getY() {
            return y;
        }

        public int getWidth() {
            return width;
        }

        public int getHeight() {
            return height;
        }
    }

    private ArrayList<Ball> balls = new ArrayList<>(3);

    public BallGame() {
        createBalls();
        startGame();
    }

    private void startGame() {
        int framesPerSecond = 30;
        int timeToWait = 1000 / framesPerSecond;
        Timer timer = new Timer(timeToWait, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                for (Ball ball : balls) {
                    ball.positionBall();
                }
                repaint();
            }
        });
        timer.start();
    }

    private void createBalls() {
        int startX = 400;
        int startY = 200;
        balls.add(new Ball(Color.green, startX, startY, 10, 10));
        balls.add(new Ball(Color.blue, startX, startY, 15, 15, true, true));
        balls.add(new Ball(Color.red, startX, startY, 20, 20, false, true));
        balls.add(new Ball(Color.orange, startX, startY, 20, 20, true, false));
    }

    public void paintComponent(Graphics g) {
        Graphics2D g2 = (Graphics2D) g.create();
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);

        for (Ball ball : balls) {
            g2.setColor(ball.getColor());
            g2.fillOval(ball.getX(), ball.getY(), ball.getWidth(), ball.getHeight());
            g2.setColor(ball.getColor().darker());
            g2.drawOval(ball.getX(), ball.getY(), ball.getWidth(), ball.getHeight());
        }
        g2.dispose();
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame("Ball Game");
                BallGame ballGame = new BallGame();
                ballGame.setOpaque(false);
                frame.getContentPane().add(ballGame);
                frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
                frame.setMinimumSize(new Dimension(800, 450));
                frame.setLocationRelativeTo(null); // Center
                frame.pack();
                frame.setVisible(true);
            }
        });
    }
}
Skjalg
  • 763
  • 5
  • 13
  • Thank you very much for your help! But the red and blue balls were still moving in the same direction. What can possibly be the problem? – Erica Marie Lorenzo Mar 24 '13 at 14:25
  • It is the leftRight and upDown that you created that give the direction. Updated the example to give different start directions. – Skjalg Mar 24 '13 at 14:47