如何在随机方向上移动球,如何让它们在框架内弹跳?

时间:2013-03-24 12:06:21

标签: swing jframe jpanel

以下是代码:

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)
                {

                }

我不知道我画球的部分是否正确。球在同一条路上移动。如何将它们向不同方向移动,如何将它们限制在框架内?我立即需要这个用于我们的案例研究。谢谢你的时间!

1 个答案:

答案 0 :(得分:0)

为了使球独立移动,您需要将它们视为3个球。 它们总是走同一个方向的原因是你使用相同的三角形,只是反转delta x和delta y的符号,因此你将始终保持相同的速度,并以90度反弹。

在下面的代码基本上与你的相同,我将每个球的状态保持在不同的实例中,一旦触摸一侧改变delta x和delta y的速度,并使用Swing Timer,这是一个更好的关于Swing中的计时方法,正如上面Robin所指出的那样。

enter image description here

我更新了这个例子,所以4个球从中间开始,然后彼此远离。这应该为您提供足够的信息以使其适应您的要求。下图仅通过允许10次迭代和设置

来生成
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);
            }
        });
    }
}