2013-10-07 5 views
3

Я делаю круг, чтобы окружить программу обнаружения столкновений. Я могу заставить шары двигаться, но когда обнаружено столкновение, шары довольно далеко перекрываются. Какие-либо предложения? Заранее спасибо!Обнаружение столкновений между кругом и кругом Java

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; 

    } 


    } 
} 
+4

См. [Этот ответ] (http://stackoverflow.com/a/14575043/418556) об обнаружении столкновения между фигурами для подсказок. –

ответ

3

Слишком много недописанного кода!

Мячи просто сталкиваются, если их центры находятся в пределах суммы радиусов. Пусть r1 и r2 - радиусы шара, а x1, y1 - положение центра шара 1; аналогично x2, y2 для шара 2.

Измерьте квадрат расстояния между центрами как (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1). (Пифагор).

Они столкнулись, если это меньше или равно (r1 + r2) * (r1 + r2).

Главное, что есть Нет необходимости вычислять квадратные корни, что является дорогостоящей вычислительной задачей.

0

Я бы сказал, что это возможно из-за слишком быстрого перемещения ваших кругов или слишком быстрого шага. Сократите свой временной шаг. Лучшим подходом является использование библиотеки физики, такой как Box2D. Посмотрите на libgdx, что в него включена библиотека java. обсуждалось немного в this link

0

Вы должны проверить столкновение после каждого хода.

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

    for (int j = 0; 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 && i!=j) 
     { 
       timer.stop(); 
     }    
    } 
    } 
+0

Ну, это не оптимизировано. –

0

Вам нужно что-то в этом роде.

public boolean overlaps (Circle c1, Circle c2) { 
    float dx = c1.x - c2.x; 
    float dy = c1.y - c2.y; 
    float distance = dx * dx + dy * dy; 
    float radiusSum = c1.radius + c2.radius; 
    return distance < radiusSum * radiusSum; 
} 
Смежные вопросы