gpt4 book ai didi

java - 为什么绘制 slick.Image.getGraphics() 这么慢?

转载 作者:行者123 更新时间:2023-12-01 12:45:35 25 4
gpt4 key购买 nike

我正在使用 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());

太慢了:

  1. 您应该避免在频繁调用的方法中使用 new 运算符,因为它很慢,尤其是在创建新的图像上下文时(必须创建纹理和内部缓冲区)。如果您确实必须做这样的事情,请尝试实现一些缓冲,例如在初始化时创建一张图像并在方法中重用它,而不是重新创建。

  2. 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/

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