Java “爪哇鼠标”;“手电筒”;效果如何?
我正在编写一个简单的2D迷宫游戏,你可以在其中穿过许多房间。我想通过限制球员的视野来增加挑战性。起初我想将框架内的默认鼠标图标替换为半透明的PNG椭圆,但后来我意识到我需要屏蔽它周围的内容 我能想到的唯一方法是将鼠标指针图标做成一个比边框大的图像(因此当用户移动到一个角落时,它仍然是黑色的)填充它,然后在指针区域放置一个清晰的褪色椭圆 我想知道的是,这有可能吗?我该怎么做?我正在学习java,所以示例和oracle文档将对我有很大帮助。提前谢谢 从这里可以看到(加载需要一段时间)PS:我正在使用eclipseJava “爪哇鼠标”;“手电筒”;效果如何?,java,swing,mouseevent,Java,Swing,Mouseevent,我正在编写一个简单的2D迷宫游戏,你可以在其中穿过许多房间。我想通过限制球员的视野来增加挑战性。起初我想将框架内的默认鼠标图标替换为半透明的PNG椭圆,但后来我意识到我需要屏蔽它周围的内容 我能想到的唯一方法是将鼠标指针图标做成一个比边框大的图像(因此当用户移动到一个角落时,它仍然是黑色的)填充它,然后在指针区域放置一个清晰的褪色椭圆 我想知道的是,这有可能吗?我该怎么做?我正在学习java,所以示例和oracle文档将对我有很大帮助。提前谢谢 从这里可以看到(加载需要一段时间)PS:我正在使用
你想要的是一种更常见的“聚光灯”效果。正如本文所解释的,您将需要使用JLayer 以下是本教程的代码摘录:
class SpotlightLayerUI extends LayerUI<JPanel> {
private boolean mActive;
private int mX, mY;
@Override
public void installUI(JComponent c) {
super.installUI(c);
JLayer jlayer = (JLayer)c;
jlayer.setLayerEventMask(
AWTEvent.MOUSE_EVENT_MASK |
AWTEvent.MOUSE_MOTION_EVENT_MASK
);
}
@Override
public void uninstallUI(JComponent c) {
JLayer jlayer = (JLayer)c;
jlayer.setLayerEventMask(0);
super.uninstallUI(c);
}
@Override
public void paint (Graphics g, JComponent c) {
Graphics2D g2 = (Graphics2D)g.create();
// Paint the view.
super.paint (g2, c);
if (mActive) {
// Create a radial gradient, transparent in the middle.
java.awt.geom.Point2D center = new java.awt.geom.Point2D.Float(mX, mY);
float radius = 72;
float[] dist = {0.0f, 1.0f};
Color[] colors = {new Color(0.0f, 0.0f, 0.0f, 0.0f), Color.BLACK};
RadialGradientPaint p =
new RadialGradientPaint(center, radius, dist, colors);
g2.setPaint(p);
g2.setComposite(AlphaComposite.getInstance(
AlphaComposite.SRC_OVER, .6f));
g2.fillRect(0, 0, c.getWidth(), c.getHeight());
}
g2.dispose();
}
@Override
protected void processMouseEvent(MouseEvent e, JLayer l) {
if (e.getID() == MouseEvent.MOUSE_ENTERED) mActive = true;
if (e.getID() == MouseEvent.MOUSE_EXITED) mActive = false;
l.repaint();
}
@Override
protected void processMouseMotionEvent(MouseEvent e, JLayer l) {
Point p = SwingUtilities.convertPoint(e.getComponent(), e.getPoint(), l);
mX = p.x;
mY = p.y;
l.repaint();
}
}
类SpotlightLayerUI扩展了LayerUI{
私有布尔运算;
私人int mX,我的;
@凌驾
public void installUI(JComponent c){
super.installUI(c);
JLayer JLayer=(JLayer)c;
jlayer.setlayerventmask(
AWTEvent.MOUSE\u事件\u掩码|
AWTEvent.MOUSE\u MOTION\u EVENT\u MASK
);
}
@凌驾
公共用户界面(JComponentC){
JLayer JLayer=(JLayer)c;
jlayer.setlayerventmask(0);
super.ui(c);
}
@凌驾
公共空隙涂料(图形g、J组件c){
Graphics2D g2=(Graphics2D)g.create();
//绘制视图。
超级油漆(g2,c);
if(mActive){
/创建一个径向梯度,在中间透明。
java.awt.geom.Point2D center=new java.awt.geom.Point2D.Float(mX,mY);
浮动半径=72;
float[]dist={0.0f,1.0f};
Color[]colors={新颜色(0.0f,0.0f,0.0f,0.0f),Color.BLACK};
径向梯度涂料=
新的RadialGradientPaint(中心、半径、距离、颜色);
g2.setPaint(p);
g2.setComposite(AlphaComposite.getInstance(
AlphaComposite.SRC_超过0.6f);
g2.fillRect(0,0,c.getWidth(),c.getHeight());
}
g2.dispose();
}
@凌驾
受保护的void进程MouseEvent(MouseEvent e,JLayer l){
如果(e.getID()==MouseEvent.MOUSE_ENTERED)mActive=true;
如果(e.getID()==MouseEvent.MOUSE_退出)mActive=false;
l、 重新油漆();
}
@凌驾
受保护的void processMouseMotionEvent(MouseEvent e,JLayer l){
点p=SwingUtilities.convertPoint(e.getComponent(),e.getPoint(),l);
mX=p.x;
mY=p.y;
l、 重新油漆();
}
}
我建议您阅读Swing上的文章,以便了解侦听器是如何工作的,以及整个代码是如何工作的。因此您已经确定了基本需求
- 您需要一个鼠标侦听器来监视鼠标的移动,以便更新聚光灯的位置。通读
- 您需要在图像上渲染聚光灯效果
RadialGradientPaint
在图像上绘制“聚光灯”。它使用mousemotionlistener
来监视鼠标的位置,并在移动时更新聚光灯
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();
}
}
}
当然有可能,我个人基本上会从鼠标向外发射的位置创建一个渐变,使每个像素逐渐变暗,在距离鼠标的x、y位置一定距离后变黑,这可能是一个更有效的方法soltuion@zachlatta哈哈,我喜欢林克韦尔,我不熟悉鼠标侦听器和鼠标事件侦听器。所以我甚至不确定从哪里开始,更不用说开始编写代码了。不过,我知道如何使用常规动作听者,所以我认为它们没有太大的不同。如果你以前没有使用过,为什么不尝试使用它们呢?我相信你能在网上找到一个好地方。学习编程完全是为了实验。不要害怕打破东西!对不起,回复太长了!我现在正在看这两个例子,谢谢你们!谢谢你的例子!我仍在阅读,这两个例子似乎都非常有用。我认为这一个更容易应用到我的小程序,但这两个答案都很有用。这正是我决定使用的。PS:我喜欢Wall-E的形象!你知道艺术家的名字吗?