不能在缅因州使用鼠标事件

Cannot use MouseEvents in main

我想做什么

制作一个 Pong 游戏,其中 Y 轴根据应用程序从我的光标获取值

我尝试了什么

private void pallet() {
    ycur=(int)MouseInfo.getPointerInfo().getLocation().getY();
}

这样我就可以根据我的显示器而不是应用程序获取 Y 值。

我也尝试过使用 MouseEvent.getY(),但是当我尝试从 main 调用此方法时出现错误。

private void pallet() {
    ycur=(int)MouseInfo.getPointerInfo().getLocation().getY();
}

这是我的代码的样子,我认为问题在于我如何使用我的 main 和方法,但我不确定。

public class MyFirst extends JPanel {

    public int x = 500, y = 300, border = 30;
    public boolean goingDown = true;
    public int ycur, cursor;


    public void moveBall() {
        x++;
        if (goingDown == true) {
            y++;
        } else if (goingDown == false) {
            y--;
        }

        if (y == getHeight() - border) {
            goingDown = false;
        } else if (y == 0) {
            goingDown = true;
        }
    }

    @Override
    public void paint(Graphics g) {
        super.paint(g);
        g.fillOval(x, y, 30, 30);
        g.fillRect(30, ycur, 15, 100);
    }

    public static void main(String[] args) throws InterruptedException     {
        JFrame frame = new JFrame("Pong");
        frame.pack();
        frame.setSize(1000, 600);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
        frame.setLocationRelativeTo(null);

        MyFirst game = new MyFirst();
        frame.add(game);
        while (true) {
            game.pallet(e);
            game.moveBall();
            game.repaint();
            Thread.sleep(10);
        }
    }

    public void pallet(MouseEvent e) {
        ycur=e.getY();
    }

}

您的代码有问题:

  • 如前所述,您正在与 Swing 的事件驱动架构作斗争。使用监听器代替 while true 循环,包括跟踪鼠标位置变化的 MouseMotionListener,以及绑定到 Swing Timer 以移动球的 ActionListener。
  • 避免在 Swing GUI 中使用 Thread.sleep(...),除非格外小心,因为这会使整个应用程序进入休眠状态。
  • 避免在 main 方法中放置太多逻辑。这个方法应该很短,应该创建关键对象,连接它们,启动程序,仅此而已。
  • 使用 paintComponent 方法绘制,而不是 paint 方法。它通过双缓冲产生更流畅的动画。

例如:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.*;

@SuppressWarnings("serial")
public class MoveBallTest extends JPanel{
    private static final int PREF_W = 1000;
    private static final int PREF_H = 600;
    private static final int TIMER_DELAY = 12;
    private static final int SPRITE_WIDTH = 30;
    private static final Color OVAL_SPRITE_COLOR = Color.RED;
    private static final Color RECT_SPRITE_COLOR = Color.BLUE;
    private static final int DELTAY_Y = 1;
    private boolean goingDown = true;
    private Timer timer = new Timer(TIMER_DELAY, this::timerActionPerformed);
    private int ovalSpriteY;
    private int rectSpriteY;

    public MoveBallTest() {
        timer.start();
        MyMouse myMouse = new MyMouse();
        addMouseMotionListener(myMouse);
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.setColor(OVAL_SPRITE_COLOR);
        g.fillOval(SPRITE_WIDTH, ovalSpriteY, SPRITE_WIDTH, SPRITE_WIDTH);
        g.setColor(RECT_SPRITE_COLOR);
        g.fillRect(SPRITE_WIDTH, rectSpriteY, SPRITE_WIDTH / 2, SPRITE_WIDTH * 3);
    }

    @Override
    public Dimension getPreferredSize() {
        if (isPreferredSizeSet()) {
            return super.getPreferredSize();
        }
        return new Dimension(PREF_W, PREF_H);
    }

    public void timerActionPerformed(ActionEvent e) {
        if (ovalSpriteY <= 0) {
            goingDown = true;
        } else if (ovalSpriteY >= getHeight() - SPRITE_WIDTH) {
            goingDown = false;
        }

        ovalSpriteY += goingDown ? DELTAY_Y : -DELTAY_Y;
        repaint();
    }

    private class MyMouse extends MouseAdapter {
        @Override
        public void mouseMoved(MouseEvent e) {
            rectSpriteY = e.getY();
        }
    }

    private static void createAndShowGui() {
        JFrame frame = new JFrame("MoveBallTest");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(new MoveBallTest());
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }
}