Java鼠标“手电筒”影响? [英] Java Mouse "Flashlight" effect?

查看:95
本文介绍了Java鼠标“手电筒”影响?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个简单的2D迷宫游戏,你可以通过很多房间。我希望通过限制玩家的观点来使其变得有点挑战。起初我想过将框架中的默认鼠标图标替换为半透明的PNG椭圆,但后来我意识到我需要阻止它周围的东西。



唯一的方法我可以想到这样做是为了使鼠标指针图标大于框架的图像(所以当用户移动到角落时它仍然是黑色)填充它然后将清晰褪色的椭圆放在该区域指针。



我想知道的是,这是可能的,我将如何做到这一点?我正在学习java所以示例和oracle文档对我很有帮助。提前致谢!



从这里可以看出这个

  • 您需要在图像上渲染聚光灯效果



  • 以下示例基本上使用 RadialGradientPaint 在图像上绘制聚光灯。它使用 MouseMoitionListener 来监控鼠标的位置并随时更新聚光灯。



      import java.awt.BorderLayout; 
    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.EventQueue;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.Paint;
    import java.awt.Point;
    import java.awt.RadialGradientPaint;
    import java.awt.event.MouseAdapter;
    import java.awt.event.MouseEvent;
    import java.awt.image.BufferedImage;
    import java.io.File;
    import java.io.IOException;
    import javax.imageio.ImageIO;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.UIManager;
    import javax.swing.UnsupportedLookAndFeelException;

    公共类MouseCover {

    public static void main(String [] args){
    new MouseCover();
    }

    public MouseCover(){
    EventQueue.invokeLater(new Runnable(){
    @Override
    public void run(){
    try {
    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
    } catch(ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex){
    }

    JFrame框架= new JFrame(Testing);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setLayout(new BorderLayout());
    frame.add(new TestPane());
    frame.pack();
    frame.setLocationRelativeTo(null);
    frame.setVisible(true);
    }
    });
    }

    公共静态类TestPane扩展JPanel {

    public static final int RADIUS = 200;
    private Point mousePoint = null;
    私有BufferedImage背景;

    public TestPane(){

    MouseAdapter mouseHandler = new MouseAdapter(){
    @Override
    public void mouseMoved(MouseEvent e){
    mousePoint = e.getPoint();
    repaint();
    }

    @Override
    public void mouseExited(MouseEvent e){
    mousePoint = null;
    repaint();
    }
    };

    addMouseMotionListener(mouseHandler);
    addMouseListener(mouseHandler);
    try {
    background = ImageIO.read(...);
    } catch(IOException ex){
    ex.printStackTrace();
    }
    }

    @Override
    public Dimension getPreferredSize(){
    return background == null? new Dimension(200,200):new Dimension(background.getWidth(),background.getHeight());
    }

    @Override
    protected void paintComponent(Graphics g){
    super.paintComponent(g);
    Graphics2D g2d =(Graphics2D)g.create();

    if(background!= null){
    int x =(getWidth() - background.getWidth())/ 2;
    int y =(getHeight() - background.getHeight())/ 2;
    g2d.drawImage(background,x,y,this);
    }

    Paint paint = Color.BLACK;
    if(mousePoint!= null){
    paint = new RadialGradientPaint(
    mousePoint,
    RADIUS,
    new float [] {0,1f},
    new Color [] {new Color(0,0,0,0),new Color(0,0,0,255)});
    }

    g2d.setPaint(paint);
    g2d.fillRect(0,0,getWidth(),getHeight());

    g2d.dispose();
    }
    }
    }


    I'm coding a simple 2D maze game where you go through many rooms. I want to make it a bit challenging by limiting the view of the player. At first I thought of replacing the default mouse icon within the frame to a translucent PNG ellipse, but then I realized I needed to block out what's around it.

    The only way I could think of doing this was to make the mouse pointer icon an image that is bigger than the frame (so when the user moves to a corner it would still be black) filling it in and then placing the clear-faded ellipse in the area of the pointer.

    What I want to know is, is this possible, and how would I go about doing this? I'm learning java so examples and oracle documents will help me a lot. Thanks in advance!

    As seen from here and this link (it takes a while to load) PS: I'm using eclipse.

    解决方案

    So you've identified the basic requirements.

    • You need a mouse listener to monitor the movements of the mouse, so you can update the position of the spot light. Take a read through how to write a mouse listener
    • You need to render the spot light effect over the image

    The following example basically uses a RadialGradientPaint to paint a "spotlight" over an image. It uses a MouseMoitionListener to monitor the position of the mouse and updates the spotlight as you go.

    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.EventQueue;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.Paint;
    import java.awt.Point;
    import java.awt.RadialGradientPaint;
    import java.awt.event.MouseAdapter;
    import java.awt.event.MouseEvent;
    import java.awt.image.BufferedImage;
    import java.io.File;
    import java.io.IOException;
    import javax.imageio.ImageIO;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.UIManager;
    import javax.swing.UnsupportedLookAndFeelException;
    
    public class MouseCover {
    
        public static void main(String[] args) {
            new MouseCover();
        }
    
        public MouseCover() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    }
    
                    JFrame frame = new JFrame("Testing");
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.setLayout(new BorderLayout());
                    frame.add(new TestPane());
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }
    
        public static class TestPane extends JPanel {
    
            public static final int RADIUS = 200;
            private Point mousePoint = null;
            private BufferedImage background;
    
            public TestPane() {
    
                MouseAdapter mouseHandler = new MouseAdapter() {
                    @Override
                    public void mouseMoved(MouseEvent e) {
                        mousePoint = e.getPoint();
                        repaint();
                    }
    
                    @Override
                    public void mouseExited(MouseEvent e) {
                        mousePoint = null;
                        repaint();
                    }
                };
    
                addMouseMotionListener(mouseHandler);
                addMouseListener(mouseHandler);
                try {
                    background = ImageIO.read(...);
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
    
            @Override
            public Dimension getPreferredSize() {
                return background == null ? new Dimension(200, 200) : new Dimension(background.getWidth(), background.getHeight());
            }
    
            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                Graphics2D g2d = (Graphics2D) g.create();
    
                if (background != null) {
                    int x = (getWidth() - background.getWidth()) / 2;
                    int y = (getHeight() - background.getHeight()) / 2;
                    g2d.drawImage(background, x, y, this);
                }
    
                Paint paint = Color.BLACK;
                if (mousePoint != null) {
                    paint = new RadialGradientPaint(
                            mousePoint,
                            RADIUS,
                            new float[]{0, 1f},
                            new Color[]{new Color(0, 0, 0, 0), new Color(0, 0, 0, 255)});
                }
    
                g2d.setPaint(paint);
                g2d.fillRect(0, 0, getWidth(), getHeight());
    
                g2d.dispose();
            }
        }
    }
    

    这篇关于Java鼠标“手电筒”影响?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆