我试图让球反弹,或在它们碰撞时反转方向。我让它检查移动方法中的碰撞。它检查两个球之间是否发生碰撞,如果是真的,它会反转速度。问题是,有时球只是相互穿过,大部分是较小的球。球要么弹得早,弹得晚,要么粘在一起振动,要么互相穿过。
public class Balls{
public static void main(String[] args){
new Balls();
}
public Balls(){
JFrame frame = new JFrame("Balls");
frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.setSize(1000,1000);
frame.add(new ballHolder());
}
public class ballHolder extends JPanel{
;
public List<Ball> balls = new ArrayList<>();
public ballHolder(){
//add balls(x,y,speedX,speedY,radius,color,parent)
balls.add(new Ball(670,180,2,9,20,Color.RED,this));
balls.add(new Ball(570,380,-8,-9,20,Color.ORANGE,this));
balls.add(new Ball(170,780,2,2,50,Color.PINK,this));
balls.add(new Ball(470,680,5,3,50,Color.GREEN,this));
balls.add(new Ball(270,280,9,7,50,Color.CYAN,this));
System.out.println("Number of Balls: "+ balls.size());
Timer timer = new Timer(20, new ActionListener(){
public void actionPerformed(ActionEvent e) {
for(Ball ball : balls){
ball.move();
}
repaint();
}});
timer.start();
}
public void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
for(Ball ball : balls){
ball.paint(g2);
}
}
//gets list of balls
public List<Ball> getBalls(){
return balls;
}
}
public class Ball{
int x;
int y;
public int speedX;
public int speedY;
int radius;
int height;
int width;
Color color;
ballHolder parent;
public Ball(int x,int y,int speedX,int speedY,int radius,Color color,ballHolder parent){
this.x = x;
this.y = y;
this.speedX = speedX;
this.speedY = speedY;
this.radius = radius;
this.color = color;
this.parent = parent;
this.height = radius * 2;
this.width = radius * 2;
}
//moves ball
public void move(){
x += speedX;
y += speedY;
if(x + width > parent.getWidth()){
x = parent.getWidth() - width;
speedX = -speedX;
}else if (0 > x){
x = 0;
speedX = -speedX;
}
if(y + height > parent.getHeight()){
y = parent.getHeight() - height;
speedY = -speedY;
}else if (0 > y){
y = 0;
speedY = -speedY;
}
//check for ball collision
for(int i=0;i < parent.getBalls().size();i++){
for(int j=0;j < parent.getBalls().size();j++){
if(i != j){
if(ballCollision(parent.getBalls().get(i), parent.getBalls().get(j))){
System.out.println("Collision");
parent.getBalls().get(i).speedX *= -1;
parent.getBalls().get(i).speedY *= -1;
}
}
}
}
}
//checks for collision
public boolean ballCollision(Ball a, Ball b){
if((b.x-a.x)*(b.x-a.x) + (a.y-b.y)*(a.y-b.y) <= (a.radius+b.radius)*(a.radius+b.radius)){
return true;
}else{
return false;
}
}
private void paint(Graphics g2){
g2.setColor(color);
g2.fillOval(x, y, width, height);
}
}
}
更新版本:来自 JW 和 ZnW 的建议。并添加了更多的球,这样你就可以更清楚地看到问题
public class Balls2{
public static void main(String[] args){
new Balls2();
}
public Balls2(){
JFrame frame = new JFrame("Balls");
frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.setSize(1000,1000);
frame.add(new ballHolder());
}
public class ballHolder extends JPanel{
;
public List<Ball> balls = new ArrayList<>();
public ballHolder(){
//add balls(x,y,speedX,speedY,radius,color,parent)
balls.add(new Ball(350,350,0,0,150,Color.PINK,this));
balls.add(new Ball(500,0,0,10,20,Color.RED,this));
balls.add(new Ball(0,500,10,0,20,Color.CYAN,this));
balls.add(new Ball(500,1000,0,-10,20,Color.ORANGE,this));
balls.add(new Ball(1000,500,-10,0,20,Color.GREEN,this));
System.out.println("Number of Balls: "+ balls.size());
Timer timer = new Timer(20, new ActionListener(){
public void actionPerformed(ActionEvent e) {
for(Ball ball : balls){
ball.move();
repaint();
ball.checkCollision();
}
}});
timer.start();
}
public void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
for(Ball ball : balls){
ball.paint(g2);
}
}
//gets list of balls
public List<Ball> getBalls(){
return balls;
}
}
public class Ball{
private int x;
private int y;
private int speedX;
private int speedY;
private int radius;
private int height;
private int width;
private Color color;
private ballHolder parent;
public Ball(int x,int y,int speedX,int speedY,int radius,Color color,ballHolder parent){
this.x = x;
this.y = y;
this.speedX = speedX;
this.speedY = speedY;
this.radius = radius;
this.color = color;
this.parent = parent;
this.height = radius * 2;
this.width = radius * 2;
}
//moves ball
public void move(){
if(x + width > parent.getWidth()){
x = parent.getWidth() - width;
speedX = -speedX;
}else if (0 > x){
x = 0;
speedX = -speedX;
}
if(y + height > parent.getHeight()){
y = parent.getHeight() - height;
speedY = -speedY;
}else if (0 > y){
y = 0;
speedY = -speedY;
}
x += speedX;
y += speedY;
}
public void checkCollision(){
for(int j=0;j < parent.getBalls().size();j++){
if(parent.getBalls().get(j) != this){
if(ballCollision(parent.getBalls().get(j), this)){
System.out.println("Collision");
speedX *= -1;
speedY *= -1;
}
}
}
}
public boolean ballCollision(Ball a, Ball b){
if((b.x-a.x)*(b.x-a.x) + (a.y-b.y)*(a.y-b.y) <= (a.radius+b.radius)*(a.radius+b.radius)){
return true;
}else{
return false;
}
}
private void paint(Graphics g2){
g2.setColor(color);
g2.fillOval(x, y, width, height);
}
}
}