Java 球相互碰撞

Java 球相互碰撞,java,algorithm,swing,Java,Algorithm,Swing,我正在制作移动球的动画,这些球必须与墙壁和彼此碰撞。 工作完成了一半。球已经可以与墙壁碰撞了。 但我不知道如何使球相互碰撞。我尝试在整个ArrayList集合中使用循环,但球被错误地移除。 也许你能帮我完成这项任务 MainClass.java import java.awt.EventQueue; import javax.swing.Timer; public class MainClass { public static Timer t; public static

我正在制作移动球的动画,这些球必须与墙壁和彼此碰撞。 工作完成了一半。球已经可以与墙壁碰撞了。 但我不知道如何使球相互碰撞。我尝试在整个ArrayList集合中使用循环,但球被错误地移除。 也许你能帮我完成这项任务

MainClass.java

import java.awt.EventQueue;
import javax.swing.Timer;

public class MainClass
{
    public static Timer t; 

    public static void main(String[] args)  
    {

        UI myUI = new UI();
        EventQueue.invokeLater(myUI);

        t = new Timer(10, myUI);
        t.start();
    }

}
java

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JFrame;


public class UI extends JFrame implements Runnable, ActionListener
{
    private static final long serialVersionUID = 1L;
    @Override
    public void run()
    {
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setSize(600, 500);
        setLocationRelativeTo(null);
        setTitle("Bouncing Balls!");

        add(new DrawingSurface());
        setVisible(true);
    }

    @Override
    public void actionPerformed(ActionEvent e)
    {
        repaint();
    }


}
DrawingSurface.java

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.util.ArrayList;
import java.util.Random;

import javax.swing.JPanel;

public class DrawingSurface extends JPanel
{
    private static final long serialVersionUID = 1L;
    static ArrayList<BouncingBall> bList = new ArrayList<BouncingBall>();
    private final int numBalls = 2;
    Random r = new Random();
    int rangeMin = 1, rangeMax = 3;
    double randomXSpeed;
    double randomYSpeed;


    // create a list of balls in the constructor. This way it happens only one time
    // rather than EVERY time you re-draw...
    public DrawingSurface()
    {
        for(int i = 0; i < numBalls ; i++)
        {
            randomXSpeed = rangeMin + (rangeMax - rangeMin) * r.nextDouble();
            randomYSpeed = rangeMin + (rangeMax - rangeMin) * r.nextDouble();
            // Notice I delegate ALL of the ball functionality to the BouncingBall class. 
            // I don't want give it anything to create a new ball. 
            // The only place the balls exist is in the ArrayList.
            bList.add(new BouncingBall(r.nextInt(400), r.nextInt(300), randomXSpeed, randomYSpeed));  
        }
    }


    public void paintComponent(Graphics gContext)
    {

        // loop through the array list and tell each ball the size of the window
        // and give it the graphics context so it can draw itself.
        for(int i = 0; i < bList.size(); i++)
        {
            bList.get(i).updatePosition(getWidth(), getHeight(), (Graphics2D)gContext);
        }
    }
}
导入java.awt.Graphics;
导入java.awt.Graphics2D;
导入java.util.ArrayList;
导入java.util.Random;
导入javax.swing.JPanel;
公共类DrawingSurface扩展JPanel
{
私有静态最终长serialVersionUID=1L;
静态ArrayList bList=新ArrayList();
私有最终整数numBalls=2;
随机r=新随机();
int rangeMin=1,rangeMax=3;
双随机速度;
双随机速度;
//在构造函数中创建一个球列表。这样它只发生一次
//而不是每次你重新画。。。
公共绘图表面()
{
for(int i=0;i
BouncingBall.java

import java.awt.Color;
import java.awt.Graphics2D;

import javax.swing.JPanel;

// a class that manages the position of randomly colored ball, and draws it.
public class BouncingBall extends JPanel
{

    private static final long serialVersionUID = 1L;
    public int x,y;
    Double xMove;
    Double yMove;
    public final static int size = 20; //size of the ball
    private Color c;

    public BouncingBall(int width, int height, Double xSpeed, Double ySpeed)
    {
        x = width; //starting position
        y = height; //starting position

        xMove = xSpeed; //starting velocity
        yMove = ySpeed; //starting velocity     

        //pick a random color
        c = new Color((int)(Math.random()*255),(int)(Math.random()*255),(int)(Math.random()*255));
    }

    //pass in the height and width of the current window so we can tell where we should bounce
    public void updatePosition(int width, int height, Graphics2D g)
    {
        //update the position
        y += yMove;
        x += xMove;
        Double xSpeed = 0.0, ySpeed = 0.0;

        //if the ball moves to the right edge of the window, turn around. 
        if(x > width - size)
        {   
            x = width - size;
            xMove *= -1;
            if (xMove > 0) {
                xSpeed = xMove + (Math.random() * (1));
            }
            if (xMove <= 0) {
                xSpeed = xMove - (Math.random() * (1));
            }
            if (yMove > 0) {
                ySpeed = yMove + (Math.random() * (1));
            }
            if (yMove <= 0) {
                ySpeed = yMove - (Math.random() * (1));
            }
            DrawingSurface.bList.add(new BouncingBall(x, y, xSpeed, ySpeed));
            c = new Color((int)(Math.random()*255),(int)(Math.random()*255),(int)(Math.random()*255));
        }

        //if the ball moves to the left edge of the window, turn around.
        if(x < 1)
        {
            x = 1;
            xMove *= -1;
            if (xMove > 0) {
                xSpeed = xMove + (Math.random() * (1));
            }
            if (xMove <= 0) {
                xSpeed = xMove - (Math.random() * (1));
            }
            if (yMove > 0) {
                ySpeed = yMove + (Math.random() * (1));
            }
            if (yMove <= 0) {
                ySpeed = yMove - (Math.random() * (1));
            }
            DrawingSurface.bList.add(new BouncingBall(x, y, xSpeed, ySpeed));
            c = new Color((int)(Math.random()*255),(int)(Math.random()*255),(int)(Math.random()*255));
        }

        //if the ball moves to the bottom of the screen, turn around.
        if(y > height - size )
        {
            y = height - size;
            yMove *= -1;
            if (xMove > 0) {
                xSpeed = xMove + (Math.random() * (1));
            }
            if (xMove <= 0) {
                xSpeed = xMove - (Math.random() * (1));
            }
            if (yMove > 0) {
                ySpeed = yMove + (Math.random() * (1));
            }
            if (yMove <= 0) {
                ySpeed = yMove - (Math.random() * (1));
            }
            DrawingSurface.bList.add(new BouncingBall(x, y, xSpeed, ySpeed));
            c = new Color((int)(Math.random()*255),(int)(Math.random()*255),(int)(Math.random()*255));
        }

        //if the ball moves to the top of the screen, turn around.
        if(y < 1)
        {
            y = 1;
            yMove *= -1;
            if (xMove > 0) {
                xSpeed = xMove + (Math.random() * (1));
            }
            if (xMove <= 0) {
                xSpeed = xMove - (Math.random() * (1));
            }
            if (yMove > 0) {
                ySpeed = yMove + (Math.random() * (1));
            }
            if (yMove <= 0) {
                ySpeed = yMove - (Math.random() * (1));
            }
            DrawingSurface.bList.add(new BouncingBall(x, y, xSpeed, ySpeed));
            c = new Color((int)(Math.random()*255),(int)(Math.random()*255),(int)(Math.random()*255));
        }

        g.setColor(c);
        g.fillOval(x, y, size, size);
    }


}
导入java.awt.Color;
导入java.awt.Graphics2D;
导入javax.swing.JPanel;
//管理随机着色球的位置并绘制它的类。
公共类弹跳球扩展JPanel
{
私有静态最终长serialVersionUID=1L;
公共整数x,y;
双X移动;
双移动;
public final static int size=20;//球的大小
私有颜色c;
公共弹跳球(整数宽度、整数高度、双X速度、双Y速度)
{
x=宽度;//起始位置
y=高度;//起始位置
xMove=xSpeed;//起动速度
yMove=ySpeed;//起动速度
//随意挑选一种颜色
c=新颜色((int)(Math.random()*255),(int)(Math.random()*255),(int)(Math.random()*255));
}
//输入当前窗口的高度和宽度,这样我们就可以知道应该在哪里反弹
公共void更新位置(整数宽度、整数高度、图形2d g)
{
//更新职位
y+=yMove;
x+=xMove;
双X速度=0.0,Y速度=0.0;
//如果球移动到窗口的右边缘,请转身。
如果(x>宽度-大小)
{   
x=宽度-尺寸;
xMove*=-1;
如果(xMove>0){
xSpeed=xMove+(Math.random()*(1));
}
如果(xMove 0){
ySpeed=yMove+(Math.random()*(1));
}
如果(移动0){
xSpeed=xMove+(Math.random()*(1));
}
如果(xMove 0){
ySpeed=yMove+(Math.random()*(1));
}
如果(移动高度-大小)
{
y=高度-尺寸;
yMove*=-1;
如果(xMove>0){
xSpeed=xMove+(Math.random()*(1));
}
如果(xMove 0){
ySpeed=yMove+(Math.random()*(1));
}
如果(移动0){
xSpeed=xMove+(Math.random()*(1));
}
如果(xMove 0){
ySpeed=yMove+(Math.random()*(1));
}

如果(yMove要检测每个球与另一个球的碰撞,一种简单的方法是通过一对嵌套循环的球集合进行循环。因此,每个球将与所有其他球进行碰撞检查:

//From your list of balls
ArrayList<BouncingBall> bList = new ArrayList<BouncingBall>();

for(BouncingBall b1 : bList)
    for(BouncingBall b2 : bList)
        if(b1.intersects(b2)){
            //do whatever (such as bouncing off) when the balls collide
            b1.flipDirection();
            b2.flipDirection();              
        }
然后您仍然可以使用
intersects()
方法:

//to check for collision using intersects() method
for(BouncingBall b1 : bList)
    for(BouncingBall b2 : bList)
        if(b1.getBounds().intersects(b2.getBounds())){
            //do whatever (such as bouncing off) when the balls collide
            b1.flipDirection();
            b2.flipDirection();              
        }
对于这样一个简单的球动画,使用嵌套循环来检测碰撞就足够了。除非您正在制作一个游戏,其中每一帧都需要检查数千个或更多实体的碰撞,否则您将需要不同的碰撞检测算法,如四叉树

我以前用同样的算法编写过这样的程序,它运行得非常好:


问题是什么?请清楚地描述它。请参阅:我试图使用类似的方法:但如果几个球同时碰撞,则无效。也许您对如何解决此问题有一些想法。欢迎使用StackOverflow。请阅读并遵循帮助文档中的发布指南。适用于此处。我们无法有效地帮助您,直到您发布MCVE代码并准确描述问题。我们应该能够将您发布的代码粘贴到文本文件中,并重现您描述的问题。“它不起作用”不是一个有问题的规范。您发布的代码没有运行任何东西——它定义了四个类和出口。您能再帮我一次吗。请发布flipDirection()的源代码功能。非常感谢。@EDWIN你应该接受我的解决方案。你可以在翻转方向上发布另一个问题,因为这将是另一个问题,我稍后会回答。我实际上对你的问题投了赞成票,每次投赞成票给你5个信誉点。接受答案会给你2分。更高的信誉会给你更多的优先权是网站。
//to check for collision using intersects() method
for(BouncingBall b1 : bList)
    for(BouncingBall b2 : bList)
        if(b1.getBounds().intersects(b2.getBounds())){
            //do whatever (such as bouncing off) when the balls collide
            b1.flipDirection();
            b2.flipDirection();              
        }