Swing 如何在随机方向上移动球,如何使球在帧内反弹?

Swing 如何在随机方向上移动球,如何使球在帧内反弹?,swing,jframe,jpanel,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;

代码如下:

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

                }
公共类BallGame扩展JPanel实现可运行{
JPanel panel1=新的JPanel();
私人int ballX=10,ballY=110。。。;
线程读取;
int-toRight=5;
int-toLeft=-5;
int向上=5;
int向下=-5;
int宽度球、高度球;
公共球赛{
游戏=真实;
aThread=新线程(此线程);
aThread.start();
}
公共组件(图形g){
设置不透明(假);
超级组件(g);
g、 setColor(Color.RED);
g、 fillOval(ballX,ballY,7,7);
g、 setColor(Color.BLUE);
g、 圆形(球形+15,球形+10,7,7);
g、 setColor(Color.GREEN);
g、 fillOval(ballY-10,ballY-15,7,7);
}
公共空间定位球(int sx,int sy)
{
ballX=sx;
ballY=sy;
this.widthBall=this.getWidth();
this.heightBall=this.getHeight();
重新油漆();
}
公开募捐{
布尔值leftRight=false;
布尔向上向下=假;
while(true){
如果(游戏){
if(左-右)
{
ballX+=toRight;
如果(球X>=(宽度球-5))
leftRight=false;
}
其他的
{
ballX+=托莱夫特;
如果(球X=(高度球-5))
向上向下=错误;
}
其他的
{
贝利+=向下;

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

在下面的代码中,基本上与您的代码相同,我将每个球的状态保存在不同的实例中,一旦触到一侧,就改变δx和δy的速度,并使用摆动计时器,这是一种更好的摆动计时方法,正如上面罗宾指出的那样

我更新了这个例子,让4个球在中间开始,它们互相移动。这会给你足够的信息来适应你的要求。下面的图片只允许10次迭代,并且设置

ballGame.setOpaque(true);

import java.awt.*;
导入java.awt.event.ActionEvent;
导入java.awt.event.ActionListener;
导入java.util.ArrayList;
导入javax.swing.*;
公共类球赛扩展了JPanel{
私人班级舞会{
私人INTX;
私营企业;
私有整数宽度;
私人内部高度;
私人色彩;
私有布尔左-右;
私有布尔向上向下;
私人所得税;
德尔泰私人酒店;
球(颜色、整数x、整数y、整数宽度、整数高度){
这(颜色、x、y、宽度、高度、假、假);
}
球(颜色、整数x、整数y、整数宽度、整数高度、布尔左右、布尔上下){
这个颜色=颜色;
这个.x=x;
这个。y=y;
这个。宽度=宽度;
高度=高度;
this.leftRight=leftRight;
this.upDown=upDown;
updateDelta();
}
私有void updateDelta(){
最终整数最小移动=5;
最终整数maxExtra=10;
deltaY=最小移动+(int)(Math.random()*maxExtra);
deltaX=minimumMovement+(int)(Math.random()*maxExtra);
}
公众足球(){
if(左-右){
x+=代尔税;
如果(x>=(BallGame.this.getWidth()-width/2)){
leftRight=false;
updateDelta();
}
}否则{
x+=-deltaX;
如果(x=(BallGame.this.getHeight()-height/2));
如果(y>=(BallGame.this.getHeight()-height/2)){
向上向下=错误;
updateDelta();
}
}否则{
y+=-三角洲;

如果(请注意,对于Swing动画,您最好使用
javax.Swing.Timer
而不是您自己的
Thread
。这是使用
Timer
类在Swing中移动球的应用程序的一个示例。非常感谢您的帮助!但是红色和蓝色的球仍在向同一方向移动。可能是什么问题?它是是您创建的左、右、上下方向图,它给出了方向。更新了示例,给出了不同的开始方向。非常感谢您的解释。它真的帮助了我^_^
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);
            }
        });
    }
}