代码之家  ›  专栏  ›  技术社区  ›  Johann Chu

如何使一个圆在旋转一次后停止或在一个循环后停止

  •  0
  • Johann Chu  · 技术社区  · 2 年前

    这就是我现在拥有的。在我点击按钮后,它应该会从中心向右然后向左反弹,然后回到原来的位置。然后我应该能够再次点击按钮,这样它就会开始另一个循环。

    public class Bounce extends JFrame {
    
    private static JButton btnMovement = new JButton("Click");
    private Container container;
    private Timer timer;
    private int x = 290;
    private int y = 350;
    private int radius = 100;
    private int moves = 2;
    
    public Bounce() {
        container = getContentPane();
        container.setLayout(new FlowLayout());
        final MoveListener ml = new MoveListener();
        btnMovement.addActionListener(ml);
        timer = new Timer(5, ml);
    }
    
    private void Move() {
        x += moves;
        
        if (x + (radius * 2) > getWidth()) {
            x = getWidth() - (radius * 2);
            moves *= -1;
        } else if (x < 0) {
            x = 0;
            moves *= -1;
        }
        repaint();
    }
        
    class MoveListener implements ActionListener {
        public void actionPerformed(final ActionEvent event) {
            if (!timer.isRunning()){
                timer.start();
            } else if (timer.isRunning() && x == 290 && y == 350){ // I don't know what condition to put
                timer.stop(); 
            }
            Move();
        }
    }
    
    public void paint (Graphics g){
        super.paint(g);
        g.setColor(Color.black);
        g.fillOval(x - 5, y - radius - 5, radius + 110, radius + 110);
        g.setColor(Color.red);
        g.fillOval(x, y - radius, radius * 2, radius * 2);
    }
    
    public static void main(String args[]){
        final JFrame window = new Bounce();
        window.add(btnMovement);
        window.setSize(800, 800);
        window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        window.setVisible(true);
    }
    

    }

    1 回复  |  直到 2 年前
        1
  •  0
  •   MadProgrammer    2 年前

    这个 ActionListener 对于 Timer 应该是分开的——它充当伪循环。基本上,一旦球从左侧反弹,你可以改变一个标志,表明它到达或通过中点时应该停止,例如。。。

    enter image description here

    import java.awt.BorderLayout;
    import java.awt.Dimension;
    import java.awt.EventQueue;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.Timer;
    
    public class Main {
        public static void main(String[] args) {
            new Main();
        }
    
        public Main() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    JFrame frame = new JFrame();
                    frame.add(new TestPane());
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }
    
        public class TestPane extends JPanel {
    
            private Timer timer;
    
            private int xPos;
            private int yPos;
    
            public TestPane() {
                JButton btn = new JButton("Start");
    
                xPos = 95;
                yPos = 95;
    
                timer = new Timer(5, new ActionListener() {
                    private int xDelta = 1;
                    private boolean hasBounced = false;
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        xPos += xDelta;
                        int middleX = (getWidth() / 2) - 5;
                        if (xPos + 10 > getWidth()) {
                            xPos = getWidth() - 10;
                            xDelta *= -1;
                        } else if (xPos < 0) {
                            xPos = 0;
                            xDelta *= -1;
                            hasBounced = true;
                        } else if (hasBounced && xPos >= middleX) {
                            timer.stop();
                            btn.setEnabled(true);
                            hasBounced = false;
                        }
                        repaint();
                    }
                });
    
                setLayout(new BorderLayout());
                btn.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        btn.setEnabled(false);
                        timer.start();
                    }
                });
    
                add(btn, BorderLayout.SOUTH);
            }
    
            @Override
            public Dimension getPreferredSize() {
                return new Dimension(200, 200);
            }
    
            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                Graphics2D g2d = (Graphics2D) g.create();
                g2d.drawOval(xPos, yPos, 10, 10);
                g2d.dispose();
            }        
        }
    }
    

    一个更复杂的解决方案是在计时器启动时记录当前位置,并将其用作“终点”,但我将留给您决定