当前位置: 首页 > 面试题库 >

在Java上绘制2个朝不同方向移动的球,但一个消失了

程昕
2023-03-14
问题内容

我正在尝试创建一个程序,该程序将绘制2个球,其中一个在北中心,另一个在南中心。我需要将球朝不同的方向移动,北侧的第一个球随机向南移动,南侧的另一个球向北移动。我可以使“北中心”球向下移动,但在绘制后,在南侧的第二个球会消失。

PS:我需要有2个内部类,分别是Ball1Ball2。请帮忙。非常感谢。


问题答案:

问题…

  1. while-loop 在事件调度线程中,该线程可调整图形对象的位置
  2. Thread.sleeppaint方法上。
  3. 不打电话 super.paintComponent
  4. paintComponent方法中更新对象的状态。

Swing使用一个单线程模型,该模型负责将重绘请求分派给所有组件

在EDT中执行任何停止处理这些事件的操作,将防止Swing重新绘制UI。这将使您的动画看起来像突然从一个步骤到整个步骤都消失了。

有关更多详细信息,请参阅Swing中的并发。特别要看一看初始线程和如何使用Swing计时器

我要强调第4点

您无法控制重绘周期。重涂请求可能是出于多种原因而提出的,这些原因并非您所要求的,这将导致您的对象无法控制或在您不希望被更新时被更新。您绝对不能从任何paint方法中更改UI的任何部分的状态。

简单的例子

这是一个非常简单的示例,但它演示了在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);
        }

    }

}


 类似资料:
  • 使用matplotlib时,我可以使用{importmatplotlib.pyplotas plt}因为我使用Tkinter,所以我也会使用PicreCanvasTkAgg来做同样的事情 有人能帮我在如何实现matplotlib的停顿效果在菲格勒CanvasTkAgg。

  • 在div中有一个和可点击的图像,称为(不幸的是,我不知道在哪里添加相关的图像。抱歉)我想像我做的那样将它们分开。我想知道有没有更简单、更好的解决方案来缩短CSS代码。谢谢。 null null

  • 所以我试着在处理过程中对乒乓球进行编码,一切正常,我可以完美地上下移动球拍,但是,当你试图同时移动两个球拍时,他们不动/它不让你动(我将把这变成一个两人游戏,这样两个人可以使用同一个键盘,但不同的按键可以玩不同的桨)。 我认为这是使用“key”或“keyPressed”的问题,因为我认为它不能同时检测这两个或其他东西?但我似乎不知道如何解决这个问题或任何替代方案。(请记住,我知道如何移动桨叶,只是

  • 因此,目前在伪代码中,我有: 我取代了dragbutton类中的鼠标运动/按压/释放功能。因此,我不能在那里引用新的。因此,dragbutton类中的无法获得,因为它是不同的self。我有什么办法让它起作用吗?谢了。

  • 我有两个独立实例(p1、p2)的生产者应用程序和两个独立实例(c1、c2)的消费者应用程序。 生产者p1连接到exchange,主题为t1,队列名称为name1。 使用者c1连接到exchange,主题为t1,队列名称为name1。 生产者p2连接到exchange,主题为t2,队列名称为name1。 使用者c2连接到exchange,主题为t2,队列名称为name1。 我在RabbitMQ GU