我正在编写一个简单的2D迷宫游戏,你可以通过很多房间。我想通过限制玩家的观点来使其有点挑战。起初我想过将框架中的默认鼠标图标替换为半透明的PNG椭圆,但后来我意识到我需要阻止它周围的内容。
我能想到的唯一方法是将鼠标指针图标设置为大于框架的图像(因此当用户移动到角落时仍然是黑色时)将其填入然后放置清除指针区域中的渐变椭圆。
我想知道的是,这是可能的,我将如何做到这一点?我正在学习java,所以示例和oracle文档对我很有帮助。提前谢谢!
从这里可以看出这个link(加载需要一段时间)PS:我正在使用eclipse。
答案 0 :(得分:8)
所以你已经确定了基本要求。
以下示例基本上使用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;
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();
}
}
}
答案 1 :(得分:5)
您正在寻找的东西通常被称为“聚光灯”效果。您将需要使用JLayer,因为tutorial解释了这一点。
以下是教程中的代码摘录:
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();
}
}
我建议在Swing上阅读entire tutorial,以便了解听众的工作方式以及整个代码的工作原理。