Java:加速我的代码
我一直在编写一个应用程序来渲染图块和GUI以及所有这些。我似乎遇到了一个问题,那就是我的paintComponent似乎占用了太多CPU,并且在我的小型计算机上运行速度不能超过10 FPS。我想知道是否有更有效的方式来运行这个代码或者通过线程来提高计算速度。这里是我的代码:Java:加速我的代码
import java.awt.Color; import java.awt.Font;
import java.awt.Graphics;
import javax.swing.JPanel;
@SuppressWarnings("serial")
public class M1 extends JPanel implements Runnable {
public static double zoom = 1.25;
public static double charZoom = 1;
public static boolean breaking = false;
public void run() {
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
if(zoom <= 0.03) zoom = 1.25;
for(int cy = 0; cy < 3; cy++) {
for(int cx = 0; cx < 3; cx++) {
for(int y = 0; y < 16; y++) {
for(int x = 0; x < 16; x++) {
g.drawImage(Tiles.tileImages.get(C0.chunk[x][y][cx][cy]),
(int)((C0.cX[cx][cy] * C0.chunkWidth) * zoom) + ((int)(32 * zoom) * x) +
((M0.gameFrame.getWidth()/2)) - (int)(PEntity.x.getValue() * zoom),
(int)((C0.cY[cx][cy] * C0.chunkHeight) * zoom) + ((int)(32 * zoom) * y) +
((M0.gameFrame.getHeight()/2)) - (int)(PEntity.y.getValue() * zoom) + (int)(24.25 * zoom),// <-- 24.25 used to correctly position charatcter
(int)(32 * zoom), (int)(32 * zoom), this);
if(C0.chunk[x][y][cx][cy].equals("a05")) {
g.drawImage(Tiles.treetop,
(int)((C0.cX[cx][cy] * C0.chunkWidth) * zoom) + ((int)(32 * zoom) * x) +
((M0.gameFrame.getWidth()/2)) - (int)(PEntity.x.getValue() * zoom),
(int)((C0.cY[cx][cy] * C0.chunkHeight) * zoom) + ((int)(32 * zoom) * y) +
((M0.gameFrame.getHeight()/2)) - (int)(PEntity.y.getValue() * zoom) + (int)(24.25 * zoom)
- (int) (32 * zoom),// <-- 24.25 used to correctly position charatcter
(int)(32 * zoom), (int)(32 * zoom), this);
}
}
}
}
}
if(breaking) {
g.drawImage(M3.currentBreak, (int)((C0.cX[M3.cx][M3.cy] * C0.chunkWidth) * zoom) + ((int)(32 * zoom) * M3.x) +
((M0.gameFrame.getWidth()/2)) - (int)(PEntity.x.getValue() * zoom),
(int)((C0.cY[M3.cx][M3.cy] * C0.chunkHeight) * zoom) + ((int)(32 * zoom) * M3.y) +
((M0.gameFrame.getHeight()/2)) - (int)(PEntity.y.getValue() * zoom) + (int)(24.25 * zoom),
(int)(32 * zoom), (int)(32 * zoom), this);
}
M3.placeX = (48 * zoom);
M3.placeY = (48 * zoom);
if(M0.HUDenabled) {
g.drawImage(PEntity.currentChar,
(M0.gameFrame.getWidth()/2) - (int)((16 * charZoom) * zoom),
(M0.gameFrame.getHeight()/2) - (int)((32 * charZoom) * zoom),
(int)((32 * charZoom) * zoom), (int)((64 * charZoom) * zoom), this);
g.setColor(Color.BLACK);
g.setFont(new Font("Dialog", 1, 12));
g.drawString("Terrem" + " By Tyler D :)", 5, 15);
g.drawString("X: " + PEntity.x.getValue(), 5, 28);
g.drawString("Y: " + PEntity.y.getValue(), 5, 41);
g.drawString("ChunkX: " + C0.currentChunkX.getValue(), 5, 54);
g.drawString("ChunkY: " + C0.currentChunkY.getValue(), 5, 67);
g.drawString("BlockX: " + C0.currentBlockX.getValue(), 5, 80);
g.drawString("BlockY: " + C0.currentBlockY.getValue(), 5, 93);
g.drawString("Zoom: " + zoom, 5, 106);
g.drawString(M4.tileArea[0][0] + "_" + M4.tileArea[1][0] + "_" + M4.tileArea[2][0], 5, 126);
g.drawString(M4.tileArea[0][1] + "_" + M4.tileArea[1][1] + "_" + M4.tileArea[2][1], 5, 139);
g.drawString(M4.tileArea[0][2] + "_" + M4.tileArea[1][2] + "_" + M4.tileArea[2][2], 5, 152);
g.drawString("FPS: " + (int) FPS.currentFPS, 5, 172);
//GUI
g.drawImage(M0.GUIbar, (M0.gameFrame.getWidth() - (624))/2, (M0.gameFrame.getHeight() - 80), 624, 40, this);
for(int i = 0; i < 9; i++) {
g.drawImage(Item.Item_Img.get(PEntity.PInv[i]), ((M0.gameFrame.getWidth() - (624))/2) + 6 + (36 * i),
(M0.gameFrame.getHeight() - 74), 28, 28, this);
if(Item.Item_Img.get(PEntity.PInv[i]) != null) {
g.drawString("" + (PEntity.stk[i] + 1), ((M0.gameFrame.getWidth() - (624))/2) + 6 + (36 * i),
(M0.gameFrame.getHeight() - 47));
}
}
}
repaint();
FPS.calculateFrameRate();
}
public M1() {
M0.gameFrame.setVisible(true);
Clock.Start();
setBackground(new Color(242, 220, 121));
System.out.println("M1 loaded...");
}
}
而且我可以告诉它是大循环,因为我评论说,部分关闭,我的FPS射击高达约250
回答:
好像你可以在方法的顶部多线程一些外部的for-loops,如果你使用的Graphics2D实例是线程安全的。可能需要为此保留一个ThreadPoolExecutor,然后将外部的for-loop分解为Runnable的实例。这完全取决于抽奖的顺序是否与你有关 - 很难仅从你发布的代码中知道。
另一件跳出我的是你如何访问你的4-D图像数组。回想一下,多维Java数组实际上是对其他数组的引用的数组。您可能会更好地获取每个循环顶部的特定子数组的引用,并访问您保存的子数组引用,而不是直接对原始数组编制索引。这将为您节省大量不必要的内存提取。
回答:
作为杀死了大约200 FPS在这一点上一般的规则,尽量预先计算 - 例如您正在构建的字符串。
不要在每一帧上创建一个新的Font
,创建一次并重用它。
正如评论所暗示的,如果这对于您的应用程序来说是合理的,请将tile预渲染到可重用的BufferedImage上。
你有好几个常见的子表达式,M0.gameFrame.getHeight()
和(32 * zoom)
,虽然热点编译器可以以及这些整理出来,如果你重复运行(单个帧的测试是没有好)。如果你将这些因素分解出来,它将澄清代码,无论如何,这是一件好事。
除此之外,你需要做一些分析,看看哪些部分最耗时...
回答:
而是在每一个重绘建设新的字符串(字符串连接),你可以缓存字符串,只有重建他们如果数据发生了变化。
另一个想法:将每个字符串的静态部分与字符串的动态部分分开绘制。您可以使用FontMetrics确定某些字符串的宽度,以帮助您将动态部分排列在静态部分旁边。
一般来说,缓存也是很好的性能策略,可以在很多情况下应用。见例如Bufferedimage
。
回答:
看来您每次调用paintComponent时都会重新绘制整个屏幕。
最好是将最初的空白图像绘制到离屏缓冲区。每次更新磁贴时都将其标记为脏。当绘制paintComponent时,只会重绘脱机屏幕缓冲区中过期的部分。这应该会为你节省很多的努力。然后将整个缓冲区一次绘制到屏幕上。绘制单个大图像通常比绘制大量小图像要快得多。
例如。
public void paintComponent(Graphics g) { updateOffscreenBuffer();
// ^-- contains all the nested for loops, but does minimal work
g.drawImage(getOffscreenBuffer());
// ^-- draw the entire buffer all in one go to the screen
drawHUD(g);
}
以上是 Java:加速我的代码 的全部内容, 来源链接: utcz.com/qa/257208.html