Java Circle to Circle碰撞检测 [英] Java Circle to Circle collision detection

查看:236
本文介绍了Java Circle to Circle碰撞检测的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在制作一个圆圈来进行碰撞检测程序。我可以让球移动,但是当检测到碰撞时,球很重叠。有什么建议?提前致谢!

I am making a circle to circle collision detection program. I can get the balls to move around but when the collision is detected, the balls are quite far overlapped. Any suggestions? Thanks in advance!

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.lang.Math;

public class ShapePanel extends JPanel{

  private JButton button, startButton, stopButton;
  private JTextField textField;
  private JLabel label;
  private Timer timer;
  private final int DELAY = 10;


  ArrayList<Shape> obj = new ArrayList<Shape>();


  public static void main(String[] args){

    JFrame frame = new JFrame();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.getContentPane().add(new ShapePanel());
    frame.pack();
    frame.setVisible(true);
  }

  public ShapePanel(){

    JPanel controlPanel = new JPanel();
    DrawingPanel dpanel = new DrawingPanel();
    controlPanel.setPreferredSize(new Dimension(100,400));
    button = new JButton("Add Shape");
    startButton = new JButton("Start");
    stopButton = new JButton("Stop");
    textField = new JTextField(2);
    label = new JLabel("Count:");



    controlPanel.add(button);
    controlPanel.add(label);
    controlPanel.add(textField);
    controlPanel.add(startButton);
    controlPanel.add(stopButton);
    add(controlPanel);
    add(dpanel);

    ButtonListener bListen = new ButtonListener();
    button.addActionListener(bListen);
    startButton.addActionListener(bListen);
    stopButton.addActionListener(bListen);

    timer = new Timer(DELAY, bListen);

  }
  private class ButtonListener implements ActionListener{


    public void actionPerformed(ActionEvent e){

      if (e.getSource() == button){

        obj.add(new Shape());
        if (obj.get(obj.size()-1).y > 200){

          obj.get(obj.size()-1).moveY = -obj.get(obj.size()-1).moveY;
        }

      }else if (e.getSource() == timer){

        for (int i = 0; i < obj.size(); i++){
          obj.get(i).move();
        }

        for (int i = 0; i < obj.size(); i++){

          for (int j = i + 1; j < obj.size(); j++){

            if (Math.sqrt(Math.pow((double)obj.get(i).centerCoordX - (double)obj.get(j).centerCoordX,2)) + 
                Math.pow((double)obj.get(i).centerCoordY - (double)obj.get(j).centerCoordY,2) <= obj.get(i).radius + obj.get(j).radius){

              timer.stop();


            }

          }
        }

      }else if (e.getSource() == startButton){

        timer.start();
      }else if (e.getSource() == stopButton){

        timer.stop();
      }


      repaint();
    }
  }
  private class DrawingPanel extends JPanel{

    DrawingPanel(){

      setPreferredSize(new Dimension(400,400));
      setBackground(Color.pink);

    }
    public void paintComponent(Graphics g){
      super.paintComponent(g);
      for(int i = 0; i < obj.size(); i++){

        obj.get(i).display(g);
      }

    }
  }
}




import java.awt.*;
import java.util.*;

public class Shape{

  public int x, y, width, height, moveX = 1, moveY = 1, centerCoordX, centerCoordY, radius;
  private Color colour;
  public boolean reverse = false, sameDirection = true;

  Random generator = new Random();

  public int randomRange(int lo, int hi){
    return generator.nextInt(hi-lo)+lo;
  }

  Shape(){
    width = randomRange(30, 50);
    if (width % 2 != 0){
      width = randomRange(30, 50);
    }
    height = width;

    radius = width/2;
    x = randomRange(0, 400-width);
    y = randomRange(0, 400-height);
    colour = new Color(generator.nextInt(256),generator.nextInt(256),generator.nextInt(256));
  }

  public void display(Graphics g){

    g.setColor(colour);
    g.fillOval(x, y, width, height);
  }
  void move(){

    x += moveX;
    y += moveY;

    centerCoordX = x + width/2;
    centerCoordY = y + height/2;

    if(x >= 400-width){

      moveX = -moveX;

    }if(x <= 0){

      moveX = -moveX;

    }if(y >= 400-height){

      moveY = -moveY;

    }if (y <= 0){

      moveY = -moveY;

    }


  }
}


推荐答案

这么多未注释的代码!

So much uncommented code!

如果球的中心在半径的总和范围内,球就会发生碰撞。设r1和r2为球半径,x1,y1为球1中心的位置;类似于ball2的x2,y2。

The balls are just colliding if their centres are within the sum of the radii. Let r1 and r2 be the ball radii, and x1, y1 the position of the centre of ball1; similarly x2, y2 for ball2.

测量中心之间距离的平方为(x2 - x1)*(x2 - x1)+ (y2 - y1)*(y2 - y1)。 (毕达哥拉斯)。

Measure the square of the distance between the centres as (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1). (Pythagoras).

如果它小于或等于(r1 + r2)*(r1 + r2)

这里的关键是无需计算平方根这是一项昂贵的计算任务。

The key thing here is that there is no need to compute the square roots which is an expensive computational task.

这篇关于Java Circle to Circle碰撞检测的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆