【发布时间】:2014-06-02 03:27:09
【问题描述】:
我正在制作一款塔防游戏,我将有一些标记,根据它们的放置位置,它们有可能被绘制到游戏网格之外。我一直在我的游戏类的一个画布上绘制所有东西,我想知道是否有一种方法可以只在设定的区域(在本例中是我的游戏网格)中绘制某些东西。
为了更好地解释它,如果要在游戏网格的边缘画一个圆圈,就像要切断的悬垂一样。
我的 gui 是什么样子的:
【问题讨论】:
我正在制作一款塔防游戏,我将有一些标记,根据它们的放置位置,它们有可能被绘制到游戏网格之外。我一直在我的游戏类的一个画布上绘制所有东西,我想知道是否有一种方法可以只在设定的区域(在本例中是我的游戏网格)中绘制某些东西。
为了更好地解释它,如果要在游戏网格的边缘画一个圆圈,就像要切断的悬垂一样。
我的 gui 是什么样子的:
【问题讨论】:
一种方法可能是调整Graphics 上下文的剪辑。我个人不喜欢弄乱剪辑,因为如果你不小心,它可能会严重影响你。
查看Clipping the Drawing Region了解更多详情
剪辑示例
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.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class TestClip {
public static void main(String[] args) {
new TestClip();
}
public TestClip() {
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 img;
public TestPane() {
setBackground(Color.BLACK);
try {
img = ImageIO.read(new File("Lurk.png"));
} catch (IOException ex) {
ex.printStackTrace();
}
}
@Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setColor(Color.RED);
g2d.drawRect(100, 100, 200, 200);
g2d.setClip(101, 101, 199, 199);
g2d.drawImage(img, 300 - (img.getWidth() / 2), (getHeight() - img.getHeight()) / 2, this);
g2d.dispose();
}
}
}
另一种方法可能是生成一个透明的BufferedImage 作为图层,您可以确保将绘画限制为正确的大小,将这些附加元素绘制到其上,然后绘制生成的BufferedImage地图上方
图层示例
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.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class TestClip {
public static void main(String[] args) {
new TestClip();
}
public TestClip() {
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 img;
private BufferedImage layer;
public TestPane() {
setBackground(Color.BLACK);
try {
img = ImageIO.read(new File("Lurk.png"));
layer = new BufferedImage(199, 199, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = layer.createGraphics();
g2d.drawImage(img,
layer.getWidth() - (img.getWidth() / 2),
(layer.getHeight() - img.getHeight()) / 2,
this);
g2d.dispose();
} catch (IOException ex) {
ex.printStackTrace();
}
}
@Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setColor(Color.RED);
g2d.drawRect(100, 100, 200, 200);
g2d.drawImage(layer, 101, 101, this);
// g2d.setClip(101, 101, 199, 199);
// g2d.drawImage(img, 300 - (img.getWidth() / 2), (getHeight() - img.getHeight()) / 2, this);
g2d.dispose();
}
}
}
【讨论】: