Смещение при добавлении компонента на панель - Java
Формулировка задачи:
Доброго времени суток.
Реализуя анимация соударения множества шаров друг о друга наткнулся на одну проблему:
Шары - экземпляры класса Ellipse2D, отрисовываю внутри класса Ball расширяющего JPanel. Получается что для каждого изображения шара - своя панель. Размеры панели соответствуют размерам шара. Проблема в том, что хоть размеры шара и панели его содержащей одинаковы, их центры не совпадают. Это становится заметно при обработке столкновений шаров: в одном случае они отскакивают от стены и друг друга даже не коснувшись, в другом сперва "срастаются" о потом происходит реакция на столкновение. Кто может знать в чем проблема - подскажите пожалуйста или скиньте ссылку где можно подробно об этом узнать. Ниже привожу код:
Класс шаров:
Класс фрейма:
Класс - точка входа в программу:
package simple9PG; import javax.swing.*; import java.awt.*; import java.awt.geom.*; import java.util.ArrayList; public class Ball extends JComponent { private static ArrayList<Ball> balls = new ArrayList<>(); //проверяем столкновение шаров друг с другом и границами фрейма, и перемещаем их. static void moveAndDetection(JFrame frame) { for (int i = 0; i < balls.size(); i++) { //проверим столкновение с границами фрейма Ball ball = balls.get(i); if (ball.getX() + ball.speedX + ball.radius > frame.getWidth()) { ball.speedX *= -1; } else if (ball.getX() + ball.speedX - ball.radius < 0) { ball.speedX *= -1; } if (ball.getY() + ball.speedY + ball.radius > frame.getHeight()) { ball.speedY *= -1; } else if (ball.getY() + ball.speedY - ball.radius < 0) { ball.speedY *= -1; } //проверим столкновение с другими шарами for (int j = i + 1; j < balls.size(); j++) { Ball otherBall = balls.get(j); int x = (ball.getX() - ball.radius) - (otherBall.getX() - otherBall.radius); int y = (ball.getY() - ball.radius) - (otherBall.getY() - otherBall.radius); double xy = Math.sqrt(x * x + y * y); //упрощенная реакция на столкновение шаров if (xy <= ball.radius + otherBall.radius) { float sX = ball.speedX; float sY = ball.speedY; float sumSpeedX = Math.abs(ball.speedX) + Math.abs(otherBall.speedX); float sumSpeedY = Math.abs(ball.speedY) + Math.abs(otherBall.speedY); ball.speedX = otherBall.speedX; ball.speedY = otherBall.speedY; otherBall.speedX = sX; otherBall.speedY = sY; } } ball.setLocation(ball.getX() + (int)ball.speedX, ball.getY() + (int)ball.speedY); } } private float speedX; private float speedY; private Color color; private int radius; public Ball(float speed, int radius) { balls.add(this); this.radius = radius; speedX = speed; speedY = -speed;//speedY можно сделать положительным - разницы нет. setSize(radius * 2, radius * 2); setLocation((int)(Math.random() * (550 - radius * 2)), (int)(Math.random() * (500 - radius * 2))); //установим случайный цвет для шарика color = new Color((int)(Math.random() * 255), (int)(Math.random() * 255), (int)(Math.random() * 255)); } @Override public void paintComponent(Graphics g) { Graphics2D g2 = (Graphics2D) g; Ellipse2D ellipse = new Ellipse2D.Float(0, 0, radius * 2, radius * 2); g2.setColor(color); g2.fill(ellipse); } }
package simple9PG; import java.awt.*; import java.awt.event.*; import javax.swing.*; public class Bouns { private Timer timer; private JFrame frame; public Bouns() { EventQueue.invokeLater(new Runnable() { @Override public void run() { frame = new JFrame(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setSize(550, 550); frame.setLayout(null); frame.add(new Ball(5, 20)); frame.add(new Ball(4, 30)); frame.add(new Ball(3, 25)); frame.add(new Ball(4, 27)); frame.add(new Ball(1, 35)); frame.add(new Ball(2, 40)); frame.add(new Ball(4, 22)); frame.add(new Ball(6, 23)); frame.add(new Ball(12, 15)); timer = new Timer(30, new TimerListener()); timer.start(); frame.setVisible(true); } }); } private class TimerListener implements ActionListener{ @Override public void actionPerformed(ActionEvent event) { Ball.moveAndDetection(simple9PG.Bouns.this.frame); } } }
import simple9PG.Bouns; public class Main { public static void main(String[] args) { Bouns bouns = new Bouns(); } }
Решение задачи: «Смещение при добавлении компонента на панель»
textual
Листинг программы
xy <= ball.radius + otherBall.radius
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д