Смещение при добавлении компонента на панель - 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
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д