gpt4 book ai didi

Java ImageIcons 和 Action 监听器

转载 作者:行者123 更新时间:2023-11-29 07:58:44 25 4
gpt4 key购买 nike

我正在创建一个简单的游戏,在这个游戏中,一个人点击一张图片,得分会增加一分。这看起来很简单,对吧?关键是——图片将部分隐藏在其他图片后面!

目前,我正在使用多个 imageIcons 来设置我的场景。例如,我的前景有一个图像“foreground.png”,我的背景是“background.png”,我隐藏在两者之间的图像是“hiding.png”。

我的第一个想法是简单地获取 imageIcon 隐藏的坐标,将 height() 和 width() 添加到它们,并创建一个只在该指定区域工作的鼠标监听器。但是,这会给我一个供用户单击的矩形,这会破坏隐藏对象的目的(有人可以单击前景后面图形的刚性边界)。

对于如何使鼠标 Action 监听器仅在 imageIcon 的可见像素上工作,您有什么建议吗?是的,我知道 Action 监听器只能应用于组件(例如按钮) 但是“按钮”并不能满足我对这个项目的要求。

最佳答案

示例 1

这基本上是在 JLayeredPane 上使用了一系列 JLabel。每个标签都有自己的鼠标监听器,当您将鼠标悬停在它上面时,它会变成红色。但是,如果上面有标签,它不会响应鼠标事件...

enter image description here

import java.awt.AlphaComposite;
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.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class ClickMyImages {

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

public ClickMyImages() {
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 class TestPane extends JLayeredPane {

public TestPane() {
try {
BufferedImage img1 = ImageIO.read("/Image1");
BufferedImage img2 = ImageIO.read("/Image2");
BufferedImage img3 = ImageIO.read("/Image3");
BufferedImage img4 = ImageIO.read("/Image4");
BufferedImage img5 = ImageIO.read("/Image5");

JLabel label1 = new ClickableLabel(new ImageIcon(img1));
JLabel label2 = new ClickableLabel(new ImageIcon(img2));
JLabel label3 = new ClickableLabel(new ImageIcon(img3));
JLabel label4 = new ClickableLabel(new ImageIcon(img4));
JLabel label5 = new ClickableLabel(new ImageIcon(img5));

Dimension masterSize = getPreferredSize();

Dimension size = label1.getPreferredSize();
label1.setBounds((masterSize.width - size.width) / 2, (masterSize.height - size.height) / 2, size.width, size.height);
Point masterPoint = label1.getLocation();
size = label2.getPreferredSize();
label2.setBounds(
masterPoint.x - (size.width / 2),
masterPoint.y - (size.height / 2),
size.width, size.height);
size = label3.getPreferredSize();
label3.setBounds(
masterPoint.x + (size.width / 2),
masterPoint.y - (size.height / 2),
size.width, size.height);
size = label4.getPreferredSize();
label4.setBounds(
masterPoint.x - (size.width / 2),
masterPoint.y + (size.height / 2),
size.width, size.height);
size = label5.getPreferredSize();
label5.setBounds(
masterPoint.x + (size.width / 2),
masterPoint.y + (size.height / 2),
size.width, size.height);

add(label1);
add(label2);
add(label3);
add(label4);
add(label5);

} catch (Exception e) {
e.printStackTrace();
}
}

@Override
public Dimension getPreferredSize() {
return new Dimension(800, 800);
}
}

// This is for demonstration purposes only!
public class ClickableLabel extends JLabel {

private boolean isIn = false;

public ClickableLabel(Icon image) {
super(image);
addMouseListener(new MouseAdapter() {
@Override
public void mouseEntered(MouseEvent e) {
isIn = true;
repaint();
}

@Override
public void mouseExited(MouseEvent e) {
isIn = false;
repaint();
}
});
}

@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (isIn) {
Graphics2D g2d = (Graphics2D) g.create();
g2d.setComposite(AlphaComposite.SrcOver.derive(0.5f));
g2d.setColor(Color.RED);
g2d.fillRect(0, 0, getWidth(), getHeight());
g2d.dispose();
}
}
}
}

示例 2

此示例使用 paintComponent 方法来渲染图像。它检查鼠标点处图像的像素 alpha,以确定鼠标事件是否应该落空。

我使用 255 的 alpha 值有点严格,但您可以根据您的需要稍微软化它(例如 225 之类的东西)...

我已经对图层进行了硬编码,以便树始终位于松鼠上方,但是按照您希望它们出现的顺序将所有图像添加到 List 并不难简单地沿着列表向下运行,直到你被击中。

enter image description here

import java.awt.AlphaComposite;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Composite;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
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 ClickMyDrawnImages {

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

public ClickMyDrawnImages() {
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 class TestPane extends JPanel {

private BufferedImage tree;
private BufferedImage squirrel;
private BufferedImage mouseOver;

public TestPane() {
try {
tree = ImageIO.read(new File("Tree.png"));
squirrel = ImageIO.read(new File("Squirrel.png"));
} catch (IOException exp) {
exp.printStackTrace();
}
addMouseMotionListener(new MouseAdapter() {
@Override
public void mouseMoved(MouseEvent e) {
if (withinTree(e.getPoint())) {
mouseOver = tree;
} else if (withinSquirrel(e.getPoint())) {
mouseOver = squirrel;
} else {
mouseOver = null;
}
repaint();
}
});
}

@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}

protected boolean withinTree(Point p) {
return withinBounds(p, getTreeBounds(), tree);
}

protected boolean withinSquirrel(Point p) {
return !withinBounds(p, getTreeBounds(), tree) && withinBounds(p, getSquirrelBounds(), squirrel);
}

protected Rectangle getTreeBounds() {
int width = getWidth();
int height = getHeight();

int x = (width - tree.getWidth()) / 2;
int y = (height - tree.getHeight()) / 2;

return new Rectangle(x, y, tree.getWidth(), tree.getHeight());
}

protected Rectangle getSquirrelBounds() {
Rectangle bounds = getTreeBounds();

return new Rectangle(
bounds.x - (squirrel.getWidth() / 4),
(getHeight() - squirrel.getHeight()) / 2,
squirrel.getWidth(), squirrel.getHeight());
}

@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
int width = getWidth();
int height = getHeight();

int x = (width - tree.getWidth()) / 2;
int y = (height - tree.getHeight()) / 2;

g.drawImage(highlight(squirrel), x - (squirrel.getWidth() / 4), (height - squirrel.getHeight()) / 2, this);
g2d.drawImage(highlight(tree), x, y, this);

g2d.dispose();
}

protected BufferedImage highlight(BufferedImage img) {
BufferedImage highlight = img;
if (img.equals(mouseOver)) {
highlight = new BufferedImage(img.getWidth(), img.getHeight(), BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = highlight.createGraphics();
g2d.setColor(Color.RED);
g2d.drawImage(img, 0, 0, this);

g2d.setComposite(AlphaComposite.SrcAtop.derive(0.5f));
g2d.fillRect(0, 0, highlight.getWidth(), highlight.getHeight());
g2d.dispose();
}
return highlight;
}

protected boolean withinBounds(Point p, Rectangle bounds, BufferedImage image) {
boolean withinBounds = false;
if (bounds.contains(p)) {
int x = p.x - bounds.x;
int y = p.y - bounds.y;
int pixel = image.getRGB(x, y);
int a = (pixel >> 24) & 0xFF;
// could use a little weighting, so translucent pixels can be effected
if (a == 255) {
withinBounds = true;
}
}
return withinBounds;
}
}
}

关于Java ImageIcons 和 Action 监听器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15871530/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com