鼠标点检测错误?

时间:2014-05-26 22:49:42

标签: java graphics2d mouselistener

嘿:)所以我正在为我正在制作的游戏制作按钮。图形工作,至少在我还没有修复它们的程度。但是,点击检测有点不确定。例如,按下黑线在下面第一张图片中的位置,会触发响应。现在显然这一点不在按钮上。我已经通过在它周围绘制一个矩形来测试按钮边界框,使用它的getBounds()方法(也用于点击检测)并在它周围绘制一个完美的矩形。然后我测试了鼠标点击点,结果发现即使按钮位于y = 100处,在黑线处,鼠标点也等于100 ......现在我不知道为什么会发生这种情况,特别是因为,如果我将按钮放在左上角,鼠标检测正确检测到顶部像素并且没有偏移......

Weird Mouse Detection

3 个答案:

答案 0 :(得分:0)

这很有意思,在我的时代也遇到过类似的问题。这一切都取决于鼠标监听器附加的原因。许多人将听众附加到框架上,但是在面板上绘图。这可以具有您描述的效果,因此通常最好直接绘制到帧上,或者将侦听器附加到面板上。在99.99%的案例中,我总是选择后者。真的,没有人应该选择后者,除非它非常小。

小组就是这样;他们是拿着东西的盒子,因此是面板'。根据我的经验,使用面板总是更有效。框架只是容纳多个面板的容器。

希望我能提供帮助,在评论和/或更新后报告您的发现。

贾罗德。

答案 1 :(得分:0)

感到无聊所以我掀起了一个我认为正在发生的事情的例子。

本质上,我完全渲染到缓冲区(这里是BufferedImage)。然后将渲染绘制到画布上。这可能是也可能不是你做的,但我只是举例说。

看到你说它在左上角工作得很好,我得出的结论是缩放就是问题,因为左上角附近的x,y值逼近0,0 * scale = 0 ,即使1000的缩放也不会有任何偏移。问题是,当您向我们演示时,左上角的那些组件

希望这能回答你的问题。至于解决它,您可以适应缩放,或使用letterboxing technique。除了这两个,还有很多其他方法可以解决这个问题(例如修复屏幕大小)。

import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;

/**
 * @author Obicere
 */
public class GraphicScale {

    public GraphicScale(){
        final JFrame frame = new JFrame("Graphic Scale Example");
        final MyPanel panel = new MyPanel();

        final Timer repaintTimer = new Timer(50, e -> frame.repaint());

        frame.add(panel);
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);

        repaintTimer.start();
    }

    public static void main(final String[] args){
        SwingUtilities.invokeLater(GraphicScale::new);
    }

    public class MyPanel extends JPanel {

        private final Rectangle box = new Rectangle(100, 100, 100, 50);
        private final Dimension size = new Dimension(500, 500);
        private final BufferedImage render = new BufferedImage(500, 500, BufferedImage.TYPE_INT_RGB);

        @Override
        public void paintComponent(final Graphics g){
            super.paintComponent(g);

            render.flush();
            render();
            g.drawImage(render, 0, 0, getWidth(), getHeight(), this); // Trick is that this gets rescaled!
        }

        public void render(){
            final Graphics2D g = (Graphics2D) render.getGraphics();
            g.setColor(Color.WHITE);
            g.fillRect(0, 0, render.getWidth(), render.getHeight());

            final Point mouse = getMousePosition();
            if(mouse != null){
                if(box.contains(mouse)) {
                    g.setColor(Color.GREEN);
                    g.fill(box);
                }
                g.setColor(Color.DARK_GRAY);
                g.drawOval(mouse.x - 3, mouse.y - 3, 6, 6);
            }
            g.setColor(Color.BLACK);
            g.draw(box);
        }

        @Override
        public Dimension getPreferredSize(){
            return size;
        }
    }
}

答案 2 :(得分:0)

好的,事实证明框架有一些缩放,但我不知道它来自哪里。我准备好游戏可扩展,所以我把所有的绘画都做到了最佳尺寸的BufferedImage然后我将那个图像缩放到了框架。但是,即使我删除了鼠标位置仍然偏移。最后,我通过完成缩放优化来克服它,这需要通过将当前宽度和高度除以最佳宽度和高度来找到框架的比例。然后将鼠标位置除以该值。
我只是想出来了。在添加组件后设置组件的大小并打包框架,导致实际框架为该大小(计算边框),但是当您检索框架的大小时,它会忽略边框...为什么会发生这种情况?

解决

当我进行游戏屏幕缩放时,我使用实际框架的高度和宽度来缩放屏幕,而不是画布的高度和宽度。我改变了,现在它完美无缺!