Смещение при добавлении компонента на панель - Java

Узнай цену своей работы

Формулировка задачи:

Доброго времени суток. Реализуя анимация соударения множества шаров друг о друга наткнулся на одну проблему: Шары - экземпляры класса Ellipse2D, отрисовываю внутри класса Ball расширяющего JPanel. Получается что для каждого изображения шара - своя панель. Размеры панели соответствуют размерам шара. Проблема в том, что хоть размеры шара и панели его содержащей одинаковы, их центры не совпадают. Это становится заметно при обработке столкновений шаров: в одном случае они отскакивают от стены и друг друга даже не коснувшись, в другом сперва "срастаются" о потом происходит реакция на столкновение. Кто может знать в чем проблема - подскажите пожалуйста или скиньте ссылку где можно подробно об этом узнать. Ниже привожу код: Класс шаров:
Листинг программы
  1. package simple9PG;
  2. import javax.swing.*;
  3. import java.awt.*;
  4. import java.awt.geom.*;
  5. import java.util.ArrayList;
  6. public class Ball extends JComponent {
  7. private static ArrayList<Ball> balls = new ArrayList<>();
  8. //проверяем столкновение шаров друг с другом и границами фрейма, и перемещаем их.
  9. static void moveAndDetection(JFrame frame) {
  10. for (int i = 0; i < balls.size(); i++) {
  11. //проверим столкновение с границами фрейма
  12. Ball ball = balls.get(i);
  13. if (ball.getX() + ball.speedX + ball.radius > frame.getWidth()) {
  14. ball.speedX *= -1;
  15. } else if (ball.getX() + ball.speedX - ball.radius < 0) {
  16. ball.speedX *= -1;
  17. }
  18. if (ball.getY() + ball.speedY + ball.radius > frame.getHeight()) {
  19. ball.speedY *= -1;
  20. } else if (ball.getY() + ball.speedY - ball.radius < 0) {
  21. ball.speedY *= -1;
  22. }
  23. //проверим столкновение с другими шарами
  24. for (int j = i + 1; j < balls.size(); j++) {
  25. Ball otherBall = balls.get(j);
  26. int x = (ball.getX() - ball.radius) - (otherBall.getX() - otherBall.radius);
  27. int y = (ball.getY() - ball.radius) - (otherBall.getY() - otherBall.radius);
  28. double xy = Math.sqrt(x * x + y * y);
  29. //упрощенная реакция на столкновение шаров
  30. if (xy <= ball.radius + otherBall.radius) {
  31. float sX = ball.speedX;
  32. float sY = ball.speedY;
  33. float sumSpeedX = Math.abs(ball.speedX) + Math.abs(otherBall.speedX);
  34. float sumSpeedY = Math.abs(ball.speedY) + Math.abs(otherBall.speedY);
  35.  
  36. ball.speedX = otherBall.speedX;
  37. ball.speedY = otherBall.speedY;
  38. otherBall.speedX = sX;
  39. otherBall.speedY = sY;
  40. }
  41. }
  42. ball.setLocation(ball.getX() + (int)ball.speedX, ball.getY() + (int)ball.speedY);
  43. }
  44. }
  45. private float speedX;
  46. private float speedY;
  47. private Color color;
  48. private int radius;
  49. public Ball(float speed, int radius) {
  50. balls.add(this);
  51. this.radius = radius;
  52. speedX = speed;
  53. speedY = -speed;//speedY можно сделать положительным - разницы нет.
  54. setSize(radius * 2, radius * 2);
  55. setLocation((int)(Math.random() * (550 - radius * 2)),
  56. (int)(Math.random() * (500 - radius * 2)));
  57. //установим случайный цвет для шарика
  58. color = new Color((int)(Math.random() * 255), (int)(Math.random() * 255),
  59. (int)(Math.random() * 255));
  60. }
  61. @Override
  62. public void paintComponent(Graphics g) {
  63. Graphics2D g2 = (Graphics2D) g;
  64. Ellipse2D ellipse = new Ellipse2D.Float(0, 0, radius * 2, radius * 2);
  65. g2.setColor(color);
  66. g2.fill(ellipse);
  67. }
  68. }
Класс фрейма:
Листинг программы
  1. package simple9PG;
  2. import java.awt.*;
  3. import java.awt.event.*;
  4. import javax.swing.*;
  5. public class Bouns {
  6. private Timer timer;
  7. private JFrame frame;
  8. public Bouns() {
  9. EventQueue.invokeLater(new Runnable() {
  10. @Override
  11. public void run() {
  12. frame = new JFrame();
  13. frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  14. frame.setSize(550, 550);
  15. frame.setLayout(null);
  16. frame.add(new Ball(5, 20));
  17. frame.add(new Ball(4, 30));
  18. frame.add(new Ball(3, 25));
  19. frame.add(new Ball(4, 27));
  20. frame.add(new Ball(1, 35));
  21. frame.add(new Ball(2, 40));
  22. frame.add(new Ball(4, 22));
  23. frame.add(new Ball(6, 23));
  24. frame.add(new Ball(12, 15));
  25. timer = new Timer(30, new TimerListener());
  26. timer.start();
  27. frame.setVisible(true);
  28. }
  29. });
  30. }
  31. private class TimerListener implements ActionListener{
  32. @Override
  33. public void actionPerformed(ActionEvent event) {
  34. Ball.moveAndDetection(simple9PG.Bouns.this.frame);
  35. }
  36. }
  37. }
Класс - точка входа в программу:
Листинг программы
  1. import simple9PG.Bouns;
  2. public class Main {
  3. public static void main(String[] args) {
  4. Bouns bouns = new Bouns();
  5. }
  6. }

Решение задачи: «Смещение при добавлении компонента на панель»

textual
Листинг программы
  1. xy <= ball.radius + otherBall.radius

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

14   голосов , оценка 3.929 из 5

Нужна аналогичная работа?

Оформи быстрый заказ и узнай стоимость

Бесплатно
Оформите заказ и авторы начнут откликаться уже через 10 минут
Похожие ответы