java - 无法在缅因州使用鼠标事件

标签 java swing mouseevent

我正在尝试做什么

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

我尝试了什么

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

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

我还尝试使用 MouseEvent.getY(),但在尝试从主函数调用此方法时出现错误。

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 绑定(bind)的用于移动球的 ActionListener。
  • 避免在 Swing GUI 中使用 Thread.sleep(...),除非非常小心,因为这可能会使整个应用程序进入休眠状态。
  • 避免在主方法中放置太多逻辑。这个方法应该很短,应该创建关键对象,连接它们,设置程序运行,仅此而已。
  • 使用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());
    }
}

关于java - 无法在缅因州使用鼠标事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41126617/

相关文章:

java - 如果鼠标在 JWindow 之外单击,如何使用 mouseClick 事件?

java - 每次鼠标单击时的单独操作

java - while 循环后的代码不接受输入 [Java]

java - Spring Web 服务单元测试 : java. lang.IllegalStateExcepton:无法加载应用程序上下文

c# - 在 pictureBox 上更改光标

Java Swing 更新 JTextArea 中的字符串

java - 一次使用一个 Swing 计时器?

java - LibGDX 鼠标悬停在场景对象上

java - 我们可以在 Java 中使用 Robot 类插入 Unicode 字符吗?

用于指定框架大小的 Java Swing 应用程序