导致球在一个简单的球弹跳程序中碰撞

时间:2016-06-12 01:14:07

标签: java animation

我有一个简单的球弹跳程序,其中球的框架两侧的弹跳很好。我试图通过在每个球周围创建一个矩形并检查是否有任何其他球与该矩形相交以及是否确实切换了它们的速度来检查两个球是否接触,从而为球互相反弹添加了一种方法。当我添加围绕它的代码并且只有一个球时,它工作正常,但是当我添加多个球时,它们开始一起移动直到它们被卡在框架外。我不知道出了什么问题。

import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.event.*;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;

public class BallBounceFrame
{

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

JFrame frame;
JPanel controlPanel;
JButton stop, start;
JSpinner ballNum;
Timer t;
BallCanvas c;
static int WIDTH = 500;
static int HEIGHT = 500;

public BallBounceFrame()
{   
    frame = new JFrame("Bouncing Balls");
    frame.setSize(WIDTH, HEIGHT);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setLocationRelativeTo(null);
    frame.setResizable(false);
    c = new BallCanvas(0, 20);
    frame.add(c, BorderLayout.CENTER);
    addPanels();
    frame.setVisible(true); 
    t = new Timer(10, new animator());
    t.start();
}

public void addPanels()
{
    controlPanel = new JPanel();
        start = new JButton("Start");
        start.addActionListener(new buttonControlListener());
        controlPanel.add(start);

        stop = new JButton("Stop");
        stop.addActionListener(new buttonControlListener());
        controlPanel.add(stop);

        ballNum = new JSpinner(new SpinnerNumberModel(0, 0, 1000, 1));
        ballNum.addChangeListener(new spinnerControlListener());
        controlPanel.add(ballNum);

    frame.add(controlPanel, BorderLayout.NORTH);
}

class BallCanvas extends JPanel
{

    private static final long serialVersionUID = 1L;
    ArrayList<Ball> balls = new ArrayList<Ball>();

    public BallCanvas(int ballNum, int ballSize)
    {
        setBalls(ballNum, ballSize);
    }

    public void paint(Graphics g)
    {
        Graphics2D g2 = (Graphics2D) g;
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2.setColor(Color.RED);
        for(Ball b : balls)
        {
            b.move(this.getSize());
            g2.fill(b);
        }
    }

    public void animate()
    {
        while(true)
        {
            try
            {
                frame.repaint();
                Thread.sleep(10);
            }
            catch(Exception e)
            {
                System.out.println(e);
            }
        }
    }
    public void setBalls(int ballNum, int ballSize)
    {
        balls.clear();
        for(int i = 0; i < ballNum; i++)
        {
            balls.add(new Ball(ballSize, balls));
        }
    }
}

class Ball extends Ellipse2D.Float
{
    private int xVel, yVel;
    private int size;
    private ArrayList<Ball> balls;

    public Ball(int size, ArrayList<Ball> balls)
    {
        super((int) (Math.random() * (BallBounceFrame.WIDTH /(1.1)) + 1), (int) (Math.random() * (BallBounceFrame.WIDTH /(1.3)) + 7), size, size);
        this.size = size;
        this.xVel = (int) (Math.random() * 7 + 2);
        this.yVel = (int) (Math.random() * 7 + 2);
        this.balls = balls;
    }

    public void move(Dimension panelSize)
    {
        **Rectangle2D r = new Rectangle2D.Float(super.x, super.y, size, size);
        for(Ball b : balls)
        {
            if(b != this && b.intersects(r));
            {
                int tempx = xVel;
                int tempy = yVel;
                xVel = b.xVel;
                yVel = b.yVel;
                b.xVel = tempx;
                b.yVel = tempy;
                break;
            }
        }**

        if(super.x < 0 || super.x > panelSize.getWidth() - size) xVel *= -1;
        if(super.y < 5 || super.y > panelSize.getHeight() - size) yVel *= -1;
        super.x += xVel;
        super.y += yVel;
    }
}
class animator implements ActionListener
{
    public void actionPerformed(ActionEvent e)
    {
        frame.repaint();
    }
}

class buttonControlListener implements ActionListener
{
    public void actionPerformed(ActionEvent e)
    {
        if (e.getSource() == stop) t.stop();

        if(e.getSource() == start) t.start();
    }
}

class spinnerControlListener implements ChangeListener
{
    public void stateChanged(ChangeEvent e) {
        if(e.getSource() == ballNum)
        {
            int balls = (int) ballNum.getValue();
            c.setBalls(balls, 20);
            frame.revalidate();
            frame.repaint();
        }
    }

}
}

1 个答案:

答案 0 :(得分:-1)

您的代码在<body data-spy="scroll" data-target=".navbar" data-offset="86"> 内有一个ArrayList<Ball> - &#39;主&#39; list - 然后每个BallCanvas都有自己的Ball,表示在此之前创建的球列表。 ArrayList<Ball>然后只在Ball方法中使用自己的ArrayList<Ball>

我建议您move()内只有一个ArrayList<Ball>主人吗?而不是将其传递给BallCanvas构造函数,而是将其传递给Ball调用。