【问题标题】:why my code "Bouncing ball" doesn't work?为什么我的代码“弹跳球”不起作用?
【发布时间】:2014-01-18 08:31:36
【问题描述】:

我正在尝试编写一个关于弹跳球的代码,但我不知道如何让球弹跳。代码似乎是正确的,没有来自 eclipse 的错误消息,但球没有移动。感谢任何帮助/提示。

这是我的代码:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class BouncingBallTest extends JFrame {

    private JButton jbtStart = new JButton("Start");
    private JButton jbtStop = new JButton("Stop");
    private Ball canvas = new Ball();

    public BouncingBallTest() {
        JPanel panel = new JPanel(); // Use the panel to group buttons
        panel.add(jbtStart);
        panel.add(jbtStop);

        add(canvas, BorderLayout.CENTER); // Add canvas to centre
        add(panel, BorderLayout.SOUTH); // Add panel to south

        // register listener
        jbtStart.addActionListener(new StartBouncingBallTest());
        jbtStop.addActionListener(new StopBouncingBallTest());

    }

    // the main method
    public static void main(String[] args) {
        JFrame frame = new BouncingBallTest();
        frame.setTitle("Bouncing Ball Test");
        frame.setLocationRelativeTo(null);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(470, 300);
        frame.setVisible(true);
    }

    class StartBouncingBallTest implements ActionListener { // inner class
        @Override
        public void actionPerformed(ActionEvent e) {
            canvas.StartBouncingBallTest();
        }
    }

    class StopBouncingBallTest implements ActionListener { // inner class
        @Override
        public void actionPerformed(ActionEvent e) {
            canvas.StopBouncingBallTest();
        }
    }

    class Ball extends JPanel {
        private int radius = 10;
        private int x;
        private int y;
        private int dx = 3;
        private int dy = 3;

        private Timer timer = new Timer(20, new TimerListener());

        public void StartBouncingBallTest() {
            if (x > 0 && y > 0) {
                x += dx;
                y += dy;
            }

            else if (x == 0) {
                x -= dx;
                y += dy;
            }

            else if (y + (2 * radius) > getHeight()) {
                x += dx;
                y -= dy;
            }

            else if (y == 0) {
                x += dx;
                y -= dy;
            }

            else if (x + (2 * radius) > getWidth()) {
                x -= dx;
                y += dy;
            }
            repaint();

            timer.start();

        }

        public void StopBouncingBallTest() {

            timer.stop();
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.setColor(Color.GREEN);
            g.fillOval(x, y, 2 * radius, 2 * radius);

        }
    }

    class TimerListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            repaint();
        }
    }

}

【问题讨论】:

  • 您的计时器操作根本不会修改坐标。将定位代码移到那里,您应该会看到一些移动。
  • 我试过了,但没有任何反应..

标签: java swing events user-interface actionlistener


【解决方案1】:

基本上,没有任何东西在移动球。

每次 Swing Timer 滴答作响,您所做的就是重新绘制。

需要将移动逻辑移动到ActionListener注册到TimeractionPerformed方法中

更像...

public void StartBouncingBallTest() {
    timer.start();
}

//...

class TimerListener implements ActionListener {
    @Override
    public void actionPerformed(ActionEvent e) {
        if (x > 0 && y > 0) {
            x += dx;
            y += dy;
        }

        else if (x == 0) {
            x -= dx;
            y += dy;
        }

        else if (y + (2 * radius) > getHeight()) {
            x += dx;
            y -= dy;
        }

        else if (y == 0) {
            x += dx;
            y -= dy;
        }

        else if (x + (2 * radius) > getWidth()) {
            x -= dx;
            y += dy;
        }
        repaint();
    }
}

这样,每次Timer 滴答作响时,您都会相应地更新球的位置...

更新了工作示例

我做了两个改变。我让你的TimerListener 成为Ball 的内部类,它允许它访问Ball 的变量和方法,并修改了你的运动逻辑,让它工作

class Ball extends JPanel {

    private int radius = 10;
    private int x;
    private int y;
    private int dx = 3;
    private int dy = 3;

    private Timer timer = new Timer(20, new TimerListener());

    public void StartBouncingBallTest() {

        timer.start();

    }

    public void StopBouncingBallTest() {

        timer.stop();
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.setColor(Color.GREEN);
        g.fillOval(x, y, 2 * radius, 2 * radius);

    }

    class TimerListener implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent e) {

            if (x < 0 || x + (2 * radius) > getWidth()) {
                dx *= -1;
            }
            if (y < 0 || y + (2 * radius) > getHeight()) {
                dy *= -1;
            }

            x += dx;
            y += dy;
            repaint();
        }
    }
}

【讨论】:

  • 你是对的..确实如此。当我第一次尝试你的方法时,我的支架放置错误。使“TimerListener 成为 Ball 的内部类”..我(从未)想过!!..非常感谢您的帮助。
【解决方案2】:
private Timer timer = new Timer(20, new TimerListener());

new TimerListener() 不需要做一些有用的事情吗? StartBouncingBallTest 中的大部分代码不应该在每次计时器滴答时发生,而在计时器启动时只发生一次?

【讨论】:

  • 是的,但这只是问题的一半。如果重复运行该代码,球将移动到 (-3, 3) 然后卡住。所以这不会解决 OP 的问题。
  • 好吧,操作的原始问题是什么都没有发生。这不是什么,希望让 OP 从那里进行故障排除。
【解决方案3】:

你从来没有声明 g.fillOval 是这里的球……

g.drawOval((int)applex, (int)appley, (int)appleradius, appleradius);
  public double applex = ArandomX; //replace the random with values..
    public double appley = ArandomY; //same here
    public int appleradius = 10;

这使它移动......

a.px += a.vx;
        // check for boundaries
        if (a.px >= this.getWidth() || a.px <= 0) {
            // reverse vel and apply
            a.vx = -a.vx;
            a.px += -a.vx; // to prevent sticking
        }

        //a.vx += -gravity; // add this constant to accelerate things down
        a.py += a.vy;
        // check for boundaries
        if (a.py >= this.getHeight() || a.py <= 0) {
            // reverse vel and apply
            a.vy = -a.vy;
            a.py += a.vy; // to prevent sticking
        }`

将 a.vx 替换为您的 x 或 dx idk,因为您的变量不清楚,是的,只需将 a.vy 替换为 y 或 dy 并对我的 px 执行相同操作...它将起作用

【讨论】:

  • “用值替换随机数..”是什么意思?什么是?
  • “你的 x 或 dx idk”是什么意思?最后一句话是不可理解的。
猜你喜欢
  • 1970-01-01
  • 2014-01-23
  • 2013-08-06
  • 1970-01-01
  • 2016-01-23
  • 2011-05-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多