绘制2个球在Java上以不同的方向移动但是一个消失了 [英] Drawing 2 Balls to move in different direction on Java but one disappeared

查看:80
本文介绍了绘制2个球在Java上以不同的方向移动但是一个消失了的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建一个可以绘制2个球的程序,其中一个在北方中心,另一个在南方中心。我需要向不同方向移动球,北方的第一个球随机向南移动,另一个球向南移动向北移动。我可以让North Center球向下移动,但是南方的第二个球在被拉出后立即消失。

I'm trying to create a program that would have 2 balls drawn, with one at the North center and the other at the south center. I am required to move the balls in different directions with the first ball at the North moving randomly towards south and the other ball at the south center to move towards the North. I can make the North Center ball move downwards but the second ball at the South disappears right after it is drawn.

PS:我需要有2个内部类,它是 Ball1 Ball2 。请帮忙。非常感谢。

PS: I need to have 2 inner class which is Ball1 and Ball2. Please help. Many thanks.

推荐答案

问题......


  1. while-loop 在Event Dispatching Thread中调整图形对象的位置

  2. Thread .sleep in paint methods。

  3. 不调用 super.paintComponent

  4. 更新 paintComponent 方法中对象的状态。

  1. while-loop in the Event Dispatching Thread which adjusts the positions of graphics objects
  2. Thread.sleep in paint methods.
  3. Not calling super.paintComponent
  4. Updating the state of an object in the paintComponent method.

Swing使用单线程模型,负责(其中包括)将重绘请求分派给所有组件。

Swing uses a single thread model that is responsible for, amongst other things, dispatching repaint requests to all the components.

在EDT中执行任何停止处理这些事件的操作,将阻止Swing重新绘制UI。这将使您的动画看起来像一步一步突然从开始到结束。

Performing any operation in the EDT that stops from processing these events, will prevent Swing from repainting the UI. This will make it look like your animation has suddenly gone from the start to the end in a single step.

看看 Swing中的并发。特别是,请查看初始主题如何使用Swing Timers

Take a look at Concurrency in Swing for more details. In particular, take a look at Initial Threads and How to use Swing Timers

我应该突出显示第4点 -

I should highlight point 4-

您无法控制重绘周期。重绘请求可能会因为您没有要求的多种原因而引发,这些原因会导致您的对象更新超出您的控制范围或您不希望它们更新。您永远不应该在任何 paint 方法中更改UI的任何部分的状态。

You do not control the repaint cycle. Repaint requests may be raised for a number of reasons, that you didn't ask for, these will cause your objects to be updated beyond your control or when you don't want them to be. You should never change the state of any part of your UI from within any paint method.

简单示例

这是一个非常简单的示例,但它演示了在Swing中执行任何动画时需要理解的基本概念

This is a very simple example, but it demonstrates the basic concepts you need to understand in order to do any animation in Swing

public class SimpleBouncyBall {

    public static void main(String[] args) {
        new SimpleBouncyBall();
    }

    public SimpleBouncyBall() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (Exception ex) {
                }

                JFrame frame = new JFrame("Test");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new CourtPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class CourtPane extends JPanel {

        private Ball ball;
        private int speed = 5;

        public CourtPane() {
            Timer timer = new Timer(40, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    Rectangle bounds = new Rectangle(new Point(0, 0), getSize());
                    if (ball == null) {
                        ball = new Ball(bounds);
                    }
                    speed = ball.move(speed, bounds);
                    repaint();
                }
            });
            timer.setRepeats(true);
            timer.setCoalesce(true);
            timer.start();
        }

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

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g); 
            if (ball != null) {
                Graphics2D g2d = (Graphics2D) g.create();
                g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
                Point p = ball.getPoint();
                g2d.translate(p.x, p.y);
                ball.paint(g2d);
                g2d.dispose();
            }
        }

    }

    public class Ball {

        private Point p;
        private int radius = 12;

        public Ball(Rectangle bounds) {

            p = new Point();
            p.x = 0;
            p.y = bounds.y + (bounds.height - radius) / 2;

        }

        public Point getPoint() {
            return p;
        }

        public int move(int speed, Rectangle bounds) {

            p.x += speed;
            if (p.x + radius >= (bounds.x + bounds.width)) {

                speed *= -1;
                p.x = ((bounds.x + bounds.width) - radius) + speed;

            } else if (p.x <= bounds.x) {

                speed *= -1;
                p.x = bounds.x + speed;

            }

            p.y = bounds.y + (bounds.height - radius) / 2;

            return speed;

        }

        public void paint(Graphics2D g) {
            g.setColor(Color.RED);
            g.fillOval(0, 0, radius, radius);
        }

    }

}

这篇关于绘制2个球在Java上以不同的方向移动但是一个消失了的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆