Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2012/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java中的弹跳球_Java_Swing - Fatal编程技术网

Java中的弹跳球

Java中的弹跳球,java,swing,Java,Swing,我正在创建一个弹跳球项目,每次点击鼠标时都会以随机的速度、随机的大小和随机的位置生成弹跳球,除了一件事之外,一切都很完美,当球从顶部和左侧撞击墙壁时,它会完全反弹,但当球撞击窗户底部和右侧时,它们也会反弹,但不是完全反弹,我的意思是,球在撞击墙壁之前从窗户右侧反弹,当几乎一半的球超过窗户时从底部反弹。 问题是什么,为什么要这样做 代码如下: import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import j

我正在创建一个弹跳球项目,每次点击鼠标时都会以随机的速度、随机的大小和随机的位置生成弹跳球,除了一件事之外,一切都很完美,当球从顶部和左侧撞击墙壁时,它会完全反弹,但当球撞击窗户底部和右侧时,它们也会反弹,但不是完全反弹,我的意思是,球在撞击墙壁之前从窗户右侧反弹,当几乎一半的球超过窗户时从底部反弹。 问题是什么,为什么要这样做

代码如下:

import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
//To generate random colors
/*new Color((int) Math.floor((Math.random() * 256)),(int) Math.floor((Math.random() * 256)),(int) 
Math.floor((Math.random() * 256)))*/
public class bouncingBalls {
public static void main(String[] args) {
    Program program = new Program();
    program.run();
}
}

class Program {
protected JFrame mainFrame;
protected DrawPanel drawPanel;
protected java.util.List<Ball> balls;
void run() {

    balls = new ArrayList<>();
    mainFrame = new JFrame();
    drawPanel = new DrawPanel();
    mainFrame.getContentPane().add(drawPanel);
    mainFrame.setTitle("Bouncing Balls");
    mainFrame.setSize(640, 480);
    mainFrame.setVisible(true);
    mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    /* Generate balls */
    mainFrame.addMouseListener(new MouseAdapter() {
        public void mouseClicked(MouseEvent me) {
            System.out.println("Mouse clicked");
            Ball ball = new Ball(
                    /* Random positions from 0 to windowWidth or windowHeight */
                    (int) Math.floor(Math.random() * 640),
                    (int) Math.floor(Math.random() * 480),
                    /* Random size from 10 to 30 */
                    (int) Math.floor(Math.random() * 20) + 10,
                    /* Random RGB colors*/
                    new Color(0x851E3E),
                    /* Random velocities from -5 to 5 */
                    (int) Math.floor((Math.random() * 10) - 5),
                    (int) Math.floor((Math.random() * 10) - 5)
            );

            balls.add(ball);
        }
    });
    while (true) {
        for (Ball b: balls) {
            b.update();
        }

        /* Give Swing 10 milliseconds to see the update! */
        try {
            Thread.sleep(30);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        mainFrame.repaint();
    }
}

class DrawPanel extends JPanel {
    @Override
    public void paintComponent(Graphics graphics) {
        super.paintComponent(graphics);

        for (Ball b: balls) {
            b.draw(graphics);
        }

    }
}

class Ball {
    private int posX, posY, size;
    private Color color;

    private int vx;
    private int vy;

    public Ball(int posX, int posY, int size, Color color, int vx, int vy) {
        this.posX = posX;
        this.posY = posY;
        this.size = size;
        this.color = color;
        this.vx = vx;
        this.vy = vy;
    }

    void update() {

        if (posX > mainFrame.getWidth()-size*2 || posX < 0) {
            vx *= -1;
        }

        if (posY > mainFrame.getHeight()-size-32 || posY < 0) {
            vy *= -1;
        }

        if (posX > mainFrame.getWidth()-size*2) {
            posX = mainFrame.getWidth()-size*2;
        }

        if (posX < 0) {
            posX = 0;
        }

        if (posY > mainFrame.getHeight()-size-32) {
            posY = mainFrame.getHeight()-size-32;
        }

        if (posY < 0) {
            posY = 0;
        }

        this.posX += vx;
        this.posY += vy;

    }

    void draw(Graphics g) {
        g.setColor(color);
        g.fillOval(posX, posY, size, size);
        g.getClipBounds();
        g.getClipBounds();
    }
}
}
import java.awt.event.MouseAdapter;
导入java.awt.event.MouseEvent;
导入java.util.ArrayList;
//生成随机颜色
/*新颜色((int)Math.floor((Math.random()*256)),(int)Math.floor((Math.random()*256)),(int)
Math.floor((Math.random()*256)))*/
公开课弹跳球{
公共静态void main(字符串[]args){
程序=新程序();
program.run();
}
}
班级计划{
受保护的JFrame主机;
受保护的抽板抽板;
受保护的java.util.List球;
无效运行(){
balls=新的ArrayList();
大型机=新的JFrame();
drawPanel=新的drawPanel();
mainFrame.getContentPane().add(drawPanel);
大型机.setTitle(“弹跳球”);
大型机。设置大小(640480);
mainFrame.setVisible(true);
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
/*生球*/
mainFrame.addMouseListener(新的MouseAdapter(){
公共无效mouseClicked(MouseEvent me){
System.out.println(“鼠标点击”);
球=新球(
/*从0到windowWidth或windowHeight的随机位置*/
(int)Math.floor(Math.random()*640),
(int)Math.floor(Math.random()*480),
/*随机大小从10到30*/
(int)Math.floor(Math.random()*20)+10,
/*随机RGB颜色*/
新颜色(0x851E3E),
/*从-5到5的随机速度*/
(int)数学层((Math.random()*10)-5),
(int)Math.floor((Math.random()*10)-5)
);
添加(ball);
}
});
while(true){
用于(球b:球){
b、 更新();
}
/*给Swing 10毫秒来查看更新*/
试一试{
睡眠(30);
}捕捉(中断异常e){
e、 printStackTrace();
}
mainFrame.repaint();
}
}
类DrawPanel扩展了JPanel{
@凌驾
公共虚空绘制组件(图形){
super.paintComponent(图形);
用于(球b:球){
b、 绘制(图形);
}
}
}
班级舞会{
私有int posX,posY,size;
私人色彩;
私有intvx;
私营企业;
公共球(int-posX,int-posY,int-size,Color-Color,int-vx,int-vy){
this.posX=posX;
this.posY=posY;
这个。大小=大小;
这个颜色=颜色;
这是vx=vx;
this.vy=vy;
}
无效更新(){
if(posX>mainFrame.getWidth()-size*2 | | posX<0){
vx*=-1;
}
if(posY>mainFrame.getHeight()-size-32 | | posY<0){
vy*=-1;
}
if(posX>mainFrame.getWidth()-size*2){
posX=mainFrame.getWidth()-size*2;
}
if(posX<0){
posX=0;
}
if(posY>mainFrame.getHeight()-size-32){
posY=mainFrame.getHeight()-size-32;
}
if(posY<0){
posY=0;
}
这个.posX+=vx;
this.posY+=vy;
}
虚线绘制(图形g){
g、 设置颜色(颜色);
g、 Fillova(posX、posY、size、size);
g、 getClipBounds();
g、 getClipBounds();
}
}
}

好的,那么您有一些关键问题

JFrame
包含
contentPane
和装饰。装饰出现在框架的边界内,这使得
contentPane
s的大小等于框架大小减去装饰插图。这是您主要遇到问题的地方,因为您使用的是帧大小而不是
DrawPanel
size来确定碰撞检测

相反,您应该使用
DrawPanel
s大小(已添加到
contentPane

有关更多详细信息,请参阅

这是一个重建的代码示例,它使用Swing
计时器而不是
线程
,因此它是线程安全的,并将主要工作负载放置在
绘图面板
,而不是分散在各个位置

有关更多详细信息,请参阅

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;

public class Test {

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

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                Program program = new Program();
                program.run();
            }
        });
    }

    class Program {

        protected JFrame mainFrame;
        protected DrawPanel drawPanel;

        void run() {

            mainFrame = new JFrame();
            drawPanel = new DrawPanel();
            mainFrame.getContentPane().add(drawPanel);
            mainFrame.setTitle("Bouncing Balls");
            mainFrame.pack();
            mainFrame.setVisible(true);
            mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        }

        class DrawPanel extends JPanel {

            private java.util.List<Ball> balls;
            private Timer timer;

            public DrawPanel() {
                balls = new ArrayList<>(25);
                addMouseListener(new MouseAdapter() {
                    public void mouseClicked(MouseEvent me) {
                        System.out.println("Mouse clicked");
                        Ball ball = new Ball(
                                /* Random positions from 0 to windowWidth or windowHeight */
                                (int) Math.floor(Math.random() * 640),
                                (int) Math.floor(Math.random() * 480),
                                /* Random size from 10 to 30 */
                                (int) Math.floor(Math.random() * 20) + 10,
                                /* Random RGB colors*/
                                Color.RED,
                                /* Random velocities from -5 to 5 */
                                (int) Math.floor((Math.random() * 10) - 5),
                                (int) Math.floor((Math.random() * 10) - 5)
                        );

                        balls.add(ball);
                    }
                });
            }

            @Override
            public void addNotify() {
                super.addNotify();
                if (timer != null) {
                    timer.stop();
                }

                timer = new Timer(30, new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent arg0) {
                        for (Ball b : balls) {
                            b.update(getSize());
                        }
                        repaint();
                    }
                });
                timer.start();
            }

            @Override
            public void removeNotify() {
                super.removeNotify();
                if (timer == null) {
                    return;
                }
                timer.stop();
            }

            @Override
            public Dimension getPreferredSize() {
                return new Dimension(640, 480);
            }

            @Override
            public void paintComponent(Graphics graphics) {
                super.paintComponent(graphics);

                for (Ball b : balls) {
                    b.draw(graphics);
                }

            }
        }

        class Ball {

            private int posX, posY, size;
            private Color color;

            private int vx;
            private int vy;

            public Ball(int posX, int posY, int size, Color color, int vx, int vy) {
                this.posX = posX;
                this.posY = posY;
                this.size = size;
                this.color = color;
                this.vx = vx;
                this.vy = vy;
            }

            void update(Dimension bounds) {

                if (posX + size > bounds.width || posX < 0) {
                    vx *= -1;
                }

                if (posY + size > bounds.height || posY < 0) {
                    vy *= -1;
                }

                if (posX + size > bounds.width) {
                    posX = bounds.width - size;
                }

                if (posX < 0) {
                    posX = 0;
                }

                if (posY + size > bounds.height) {
                    posY = bounds.height - size;
                }

                if (posY < 0) {
                    posY = 0;
                }

                this.posX += vx;
                this.posY += vy;

            }

            void draw(Graphics g) {
                g.setColor(color);
                g.fillOval(posX, posY, size, size);
            }
        }
    }
}
导入java.awt.Color;
导入java.awt.Dimension;
导入java.awt.EventQueue;
导入java.awt.Graphics;
导入java.awt.event.ActionEvent;
导入java.awt.event.ActionListener;
导入java.awt.event.MouseAdapter;
导入java.awt.event.MouseEvent;
导入java.util.ArrayList;
导入javax.swing.JFrame;
导入javax.swing.JPanel;
导入javax.swing.Timer;
公开课考试{
公共静态void main(字符串[]args){
新测试();
}
公开考试(){
invokeLater(新的Runnable(){
@凌驾
公开募捐{
程序=新程序();
program.run();
}
});
}
班级计划{
受保护的JFrame主机;
受保护的抽板抽板;
无效运行(){
大型机=新的JFrame();
drawPanel=新的drawPanel();
mainFrame.getContentPane().add(drawPanel);
大型机.setTitle(“弹跳球”);
mainFrame.pack();
mainFrame.setVisible(true);
mainFrame.setD