ホームページ > Java > &#&チュートリアル > Java アプリケーションでバウンドするボールの重なりを防ぐには?

Java アプリケーションでバウンドするボールの重なりを防ぐには?

Mary-Kate Olsen
リリース: 2025-01-03 06:51:38
オリジナル
579 人が閲覧しました

How to Prevent Overlapping Bouncing Balls in a Java Application?

Java バウンス ボール

この問題は、境界線から跳ね返る複数のボールをインターフェイス上でレンダリングするように設計された Java アプリケーションに関係します。ユーザーは 1 つのボールの描画を正常に実装しましたが、2 番目のボールを追加しようとすると最初のボールが上書きされるため、問題が発生します。

これに対処するには、ボールのリストを作成して循環させることができます。各ボールを描画する必要がありますが、ユーザーは両方のボールをコンテンツ ペインに追加するときに困難に遭遇します。

分析と解決策

主な問題は 2 つのボールの配置です。不透明なコンポーネントが重なり合うと、一方が他方を隠してしまう可能性があります。これを解決するには:

  1. レイアウト マネージャーがボールのレイアウトを指示しないように、ヌル レイアウト マネージャーを使用する必要があります。
  2. ボール ペインのサイズと位置を制御する必要があります。
  3. 開始点が同一になる可能性を減らすために、ボールの速度と位置をランダム化する必要があります。
  4. EDT (イベント ディスパッチ スレッド) のコンテキスト内ではボールのみを更新する必要があります。
  5. X/Y 値の使用は冗長であり、パネル自体を利用することで削除できます。 .

コード例

これらを組み込んだ改良されたコード例変更:

public class Balls {

    public Balls() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException ex) {
                } catch (InstantiationException ex) {
                } catch (IllegalAccessException ex) {
                } catch (UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TheBalls());
                frame.setSize(400, 400);
                frame.setVisible(true);
            }
        });
    }

    public class TheBalls extends JPanel {

        public TheBalls() {
            setLayout(null);
            // Randomize the speed and direction...
            add(new Ball("red", 10 - (int) Math.round((Math.random() * 20)), 10 - (int) Math.round((Math.random() * 20))));
            add(new Ball("blue", 10 - (int) Math.round((Math.random() * 20)), 10 - (int) Math.round((Math.random() * 20))));
        }
    }

    public class Ball extends JPanel implements Runnable {

        Color color;
        int diameter;
        long delay;
        private int vx;
        private int vy;

        public Ball(String ballcolor, int xvelocity, int yvelocity) {
            if (ballcolor == "red") {
                color = Color.red;
            } else if (ballcolor == "blue") {
                color = Color.blue;
            } else if (ballcolor == "black") {
                color = Color.black;
            } else if (ballcolor == "cyan") {
                color = Color.cyan;
            } else if (ballcolor == "darkGray") {
                color = Color.darkGray;
            } else if (ballcolor == "gray") {
                color = Color.gray;
            } else if (ballcolor == "green") {
                color = Color.green;
            } else if (ballcolor == "yellow") {
                color = Color.yellow;
            } else if (ballcolor == "lightGray") {
                color = Color.lightGray;
            } else if (ballcolor == "magenta") {
                color = Color.magenta;
            } else if (ballcolor == "orange") {
                color = Color.orange;
            } else if (ballcolor == "pink") {
                color = Color.pink;
            } else if (ballcolor == "white") {
                color = Color.white;
            }
            diameter = 30;
            delay = 100;

            vx = xvelocity;
            vy = yvelocity;

            new Thread(this).start();

        }

        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2 = (Graphics2D) g;

            int x = getX();
            int y = getY();

            g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            g.setColor(color);
            g.fillOval(0, 0, 30, 30); //adds color to circle
            g.setColor(Color.black);
            g2.drawOval(0, 0, 30, 30); //draws circle
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(30, 30);
        }

        public void run() {

            try {
                // Randamize the location...
                SwingUtilities.invokeAndWait(new Runnable() {
                    @Override
                    public void run() {
                        int x = (int) (Math.round(Math.random() * getParent().getWidth()));
                        int y = (int) (Math.round(Math.random() * getParent().getHeight()));

                        setLocation(x, y);
                    }
                });
            } catch (InterruptedException exp) {
                exp.printStackTrace();
            } catch (InvocationTargetException exp) {
                exp.printStackTrace();
            }

            while (isVisible()) {
                try {
                    Thread.sleep(delay);
                } catch (InterruptedException e) {
                    System.out.println("interrupted");
                }

                try {
                    SwingUtilities.invokeAndWait(new Runnable() {
                        @Override
                        public void run() {
                            move();
                            repaint();
                        }
                    });
                } catch (InterruptedException exp) {
                    exp.printStackTrace();
                } catch (InvocationTargetException exp) {
                    exp.printStackTrace();
                }
            }
        }

        public void move() {

            int x = getX();
            int y = getY();

            if (x + vx < 0 || x + diameter + vx > getParent().getWidth()) {
                vx *= -1;
            }
            if (y + vy < 0 || y + diameter + vy > getParent().getHeight()) {
                vy *= -1;
            }
            x += vx;
            y += vy;

            // Update the size and location...
            setSize(getPreferredSize());
            setLocation(x, y);

        }
    }
}
ログイン後にコピー

代替アプローチ

あるいは、ボールを収容するコンテナを作成することもできます。ボール自体はコンポーネントではなく、跳ね返りを可能にする十分な情報を備えた仮想概念として存在します。

スケーラビリティに関する懸念

提供されているコード スニペットに注意することが重要です。はボールごとに個別のスレッドを使用するため、ボールの数が増えるとシステム リソースに影響を与える可能性があります。このスケーラビリティの問題に対処するために、単一の BounceEngine スレッドを使用してすべてのボールの動きを処理できます。

以上がJava アプリケーションでバウンドするボールの重なりを防ぐには?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート