我一直在尝试为我正在开发的小游戏实现基本的文字气泡。我开始时并不想太花哨,只用一个带有边框的基本圆角矩形来包含一些文本:
然后,我决定文本气泡在预设时间后应该淡出。这就是我遇到问题的地方:当我尝试在测试窗口中显示气泡时,一切都正常工作,但当我在游戏中显示它们时,当气泡淡出时会出现扭曲。我进行了更多的测试和调试,并发现两种情况之间唯一的区别是,在测试窗口上,我使用paintComponent方法的图形来绘制气泡,而在游戏中,我使用BufferedImages模拟图层,并使用来自image.createGraphics的图形。我成功地复制了这个错误:
在这里,您可以看到当左侧的气泡消失时,其圆角与消失前相比发生了形状变化,而右侧的气泡的圆角没有变化。的确,左侧的气泡是绘制在一个BufferedImage上,然后绘制在面板上,而右侧的气泡是直接绘制在面板上。我已经隔离出需要复制问题的代码:
这是上述代码产生的结果:
总之,这表明绘制到BufferedImage是导致问题的原因,但目前放弃BufferedImages不是一个选项。
我尝试调试代码以查看可能导致此差异的原因,并且只能注意到当涉及透明度时,图形对象使用不同的组件进行绘制,但是这并不能帮助我解决我的问题,因为即使可以强制图形执行我想要的操作,如果可能的话,我宁愿避免黑客攻击。
有人知道相对简单和高效的方法来解决这个问题或解决方法吗?
无论如何,感谢您抽出时间阅读这篇文章:)
PS:正如我在评论中所说,游戏是基于像素艺术的,因此我宁愿不使用反走样,而是保持圆角矩形的基本像素化外观。
![Basic Text Bubble](https://istack.dev59.com/qHToK.webp)
![Gif displaying the bug](https://istack.dev59.com/H3jnr.gif)
public static void main(String[] args) {
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setSize(400, 400);
JPanel panel = new JPanel() {
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
BufferedImage image = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB);
Graphics graphics = image.createGraphics();
paintExampleBubble(graphics, 50, 50);
g.drawImage(image, 0, 0, this);
paintExampleBubble(g, 250, 50);
}
};
frame.getContentPane().add(panel);
frame.setVisible(true);
}
private static final Color background = new Color(1f, 1f, 1f, 0.5f);
private static final Color foreground = new Color(0f, 0f, 0f, 0.5f);
private static final int borderRadius = 16;
private static final int width = 100;
private static final int height = 50;
private static void paintExampleBubble(Graphics g, int x, int y) {
g.setColor(background);
g.fillRoundRect(x, y, width, height, borderRadius, borderRadius);
g.setColor(foreground);
g.drawRoundRect(x, y, width, height, borderRadius, borderRadius);
}
这是上述代码产生的结果:
![Minimal code bug reproduction image](https://istack.dev59.com/5y2h0.webp)
我尝试调试代码以查看可能导致此差异的原因,并且只能注意到当涉及透明度时,图形对象使用不同的组件进行绘制,但是这并不能帮助我解决我的问题,因为即使可以强制图形执行我想要的操作,如果可能的话,我宁愿避免黑客攻击。
有人知道相对简单和高效的方法来解决这个问题或解决方法吗?
无论如何,感谢您抽出时间阅读这篇文章:)
PS:正如我在评论中所说,游戏是基于像素艺术的,因此我宁愿不使用反走样,而是保持圆角矩形的基本像素化外观。
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON)
,其中g
是Graphics2D
的实例。 - copeg