- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在使用 Java 和 Slick2D 库制作游戏。我有一个带有渲染方法的按钮类,如下所示:
public void render(Graphics g, int xOffset, int yOffset){
int renderX = x+xOffset;
int renderY = y+yOffset;
if(hasFocus()){
g.setColor(HIGHLIGHTEDBUTTONCOLOR);
}else{
g.setColor(BUTTONCOLOR);
}
g.fillRect(renderX, renderY, width, height);
g.setColor(BUTTONTEXTCOLOR);
g.drawString(text, renderX+(width/2) - (g.getFont().getWidth(text)/2), renderY+(height/2) - (g.getFont().getLineHeight()/2));
}
这非常有效,直到我需要仅渲染按钮的一部分(当其他部分位于可滚动容器的边界之外时)。我试过这个:
Image temp = new Image(myButton.getWidth(), myButton.getHeight());
myButton.render(temp.getGraphics(),this.x, this.y);
temp.getSubImage(0, 0, int temp.getWidth(), temp.getHeight()/2);
myGraphics.drawImage(temp, myButton.getX(), myButton.getY());
但这使我的 fps 从 4000 下降到 10。
我尝试事先制作一个空白图像,然后将其复制以在渲染时绘制,但这没有帮助。我尝试预渲染图像,它再次以 4000 fps 的速度运行,但每当我更改按钮文本或无论它是否突出显示时,我都必须重新绘制图像,从而导致卡住。
如何每帧仅渲染此按钮的一部分,而又不会太慢。还要记住我需要渲染更改的按钮部分,如果滚动它可能会更改每一帧。
最佳答案
永远不要在频繁调用且性能敏感的方法(例如 render(...) 或 update(...))中绘制图像的内部图形。
首先,这就是原因
Image temp = new Image(myButton.getWidth(), myButton.getHeight());
myButton.render(temp.getGraphics(),this.x, this.y);
temp.getSubImage(0, 0, int temp.getWidth(), temp.getHeight()/2);
myGraphics.drawImage(temp, myButton.getX(), myButton.getY());
太慢了:
您应该避免在频繁调用的方法中使用 new 运算符,因为它很慢,尤其是在创建新的图像上下文时(必须创建纹理和内部缓冲区)。如果您确实必须做这样的事情,请尝试实现一些缓冲,例如在初始化时创建一张图像并在方法中重用它,而不是重新创建。
getGraphics() 方法为图像创建一个新的 Graphics 实例,这在代码中的每一帧都被调用。如上所述,如果可能的话,在性能敏感的调用中应避免使用 new 运算符进行创建,并且在 render(..) 等方法中创建新的 Graphics 实例可能是应用程序中 fps 大幅下降的原因。
此外,与普遍的看法相反,getSubImage(..) 方法实际上对性能来说并没有那么糟糕,并且如果需要的话可以在经常调用的方法中使用,因为它基本上只是将缓冲区信息剪辑到给定的大小(但保留对原始图像的引用,因此,如果您通过以下方式修改子图像:在其上绘图,原始图像也会被修改!)。
作为问题的解决方案,您可以手动剪辑按钮并自行计算按钮框的边界。在你的情况下,你可以做这样的事情(因为你没有指定你的意思是哪种容器,我假设它是某种GUI元素并且它是一个简单的矩形,但是可以很容易地改变它以满足你的要求):
//some pseudo-code as a help
if (buttonX within container bounds) buttonStartX = buttonX
else if (buttonX smaller than container bounds) buttonStartX = containerMinX
if (buttonX + buttonWidth within container bounds) buttonBoxWidth = buttonWidth
else if (buttonX + buttonWidth greater than container bounds) buttonBoxWidth = containerMaxX - buttonStartX
//... and so on... (yes the horizontal logic is not complete, but I dont want you to just copy this
// without thinking but rather that you finish this yourself with the given approach :)
关于java - 为什么绘制 slick.Image.getGraphics() 这么慢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24729679/
在 drawToScreen 方法内调用 getGraphics() 时,我的 JPanel 预览返回 null。 Test 类也扩展了 JPanel,因为它被保存在 TabbedPane 中。该类还
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我正在尝试在扩展了 JComponent 类的地方呈现自定义 Swing 组件。 为了简化组件需求,让我们将我的组件总结为需要渲染几个字符串,每个字符串都有自己的字体。 我需要我的组件的大小完全符合我
我的应用程序看起来像这样,我在 draw() 方法中遇到空指针异常,准确地说是在 g.drawImage(img, 0, 0, null) 处 package com.ochs.game; impor
我正在做一个选择工具,我已经提供了这些解决方案,在第一个使用 JPanel getGraphics 方法中,我在鼠标拖动的地方绘制一个椭圆形,在第二个中,我重写 PaintComponent 方法来绘
我有一个带有 JPanel 和 PaintComponent() 的类。我还有一个实现 Runnable 的类,我计划在线程启动后将图像绘制到 PaintComponent 上。我的构造函数接收 JP
嗨,我是 java GUI 编程新手。我创建了 Jframe(MainFrame) 并添加了 JPanel(OutPanel),其中还有另一个 Jpanel(InnerPanel)。我尝试在 Inne
我开始学习用 Java 创建游戏,我使用的其中一种方法包括 BufferedImage。这是我得到的错误: "Exception in thread "main" java.lang.NullPoin
由于 Java 只支持单继承,我希望直接在 JPanel 的实例上绘制,它是类 面板。我从成员那里获取了一个 Graphics 的实例,然后在上面绘制我想要的任何东西。 我怎么能不继承 JCompon
我有底部导航,我也替换了 标记为 FragmentContainerView它给了我关于它没有设置 NavController 的错误,然后我被发布 this问题并解决了问题,但是当方向更改并在底部导
我想知道出了什么问题。我以前曾这样做过,但由于某种原因,这次我无法让它发挥作用。 我在 Netbeans 中设计了该项目。最相关的部分是 initTiras 方法,它应该绘制一些东西,但它没有。我包含
我正在尝试一个充当按钮但使用图像进行显示的对象。我的问题是,当调用 getGraphics() 时,它返回 null。我到处找也没找到原因? 我的构造函数的代码是...... public class
我在这里遇到了一些困难。我在尝试解决这个问题时在其他地方读到,你永远不应该 getGraphics()。问题是,我无法使用 Paint()/PaintComponent() 方法提供的 Graphic
下面是代码(我在这个类中扩展了 JFrame)(Point 'size' 是屏幕的大小): setVisible(true); backBuffer = createImage(size.x, siz
public void saveImage(String path){ BufferedImage image = (BufferedImage) createImage(500, 500);
如果我正在使用 JPanel,getGraphics 返回的 Graphics 对象与在 paintComponent 方法中传递的 Graphics 对象有什么区别? 最佳答案 getGraphic
我在调用 BufferedImage.getGraphics() 方法的某些框架 API 时遇到问题,从而导致内存泄漏。这个方法的作用是它总是调用 BufferedImage.createGraphi
如何在没有类(扩展 JFrame)的情况下绘制对象?我找到了 getGraphics 方法,但它没有绘制对象。 import javax.swing.*; import java.awt.*; pub
(这是 previous 问题的后续) 将 BufferedImage 从一种类型转换为另一种类型或制作副本的标准推荐方法是使用 getGraphics().drawImage() ( example
MadProgrammer 发表了评论here声明您永远不应该使用 Component.getGraphics,我普遍同意这一点:在几乎所有情况下,它都是错误的。 但以我多年前创建的这个类为例。我正在
我是一名优秀的程序员,十分优秀!