2

所以我又和我的两个朋友一起为学校项目制作了一个小游戏。我们和以前有同样的想法,但现在都是图形化的(JPanel、JLabel 等)。我们有基本的 GUI,但它的运行速度非常慢。当我按箭头键时,它会在 1-2 秒内响应,如果我连续按快速键,则可能需要 15 秒以上。这是代码:

主要的

package game;

import java.awt.GridLayout;
import java.io.IOException;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class Gui extends JFrame{
private static final long serialVersionUID = 1L;
int n = 0;
int m = 0;
static MapMake mapMake = new MapMake();
static MapRefresh mapRefresh = new MapRefresh();
static JPanel panel = new JPanel();
static Fighting fighting = null;

public static void main(String[] args) throws IOException {
    Gui frame = new Gui();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setTitle("Dungeons and Dragons(and some food)");
    frame.setSize(1280, 720);

    mapMake.setDiscovered(0, 0, 1);
    panel.setLayout(new GridLayout(10, 10, 2, 2));
    mapRefresh.MapRefresh();
    frame.add(panel);
    frame.addKeyListener(new Listener());
    frame.setVisible(true);
}
}

地图制作

package game;

public class MapMake{
static int[][] discovered = new int[10][10];
static int[][] content = new int[10][10];
static int heroX = 0;
static int heroY = 0;
public void MapMake(){
    discovered[0][0] = 1;
    for (int row = 0; row < 10; row++) {
        for (int col = 0; col < 10; col++) {
            discovered[row][col] = 0;
        }
    }
    discovered[0][0] = 1;
    int dragon1 = 3;
    int dragon2 = 5;
    int dragon3 = 7;
    int dragon4 = 9;
    int dragon5 = 1;
    int food = 25; // id 6

    while (dragon1 != 0) {
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                int x = (int) (Math.random() * 2);
                if (x != 1 && dragon1 != 0 && content[i][j] == 0
                        && (i > 0 && i < 3 || j > 0 && j < 3)) {
                    dragon1--;
                    content[i][j] = 1;
                }
            }
        }
    }
    while (dragon2 != 0 && food != 0) {
        for (int i = 0; i < 5; i++) {
            for (int j = 0; j < 5; j++) {
                int x = (int) (Math.random() * 2);
                if (x != 1 && dragon2 != 0 && content[i][j] == 0
                        && (i > 2 && i < 5 || j > 3 && j < 5)) {
                    dragon2--;
                    content[i][j] = 2;
                }
            }
        }
    }
    while (dragon3 != 0) {
        for (int i = 0; i < 7; i++) {
            for (int j = 0; j < 7; j++) {
                int x = (int) (Math.random() * 2);
                if (x != 1 && dragon3 != 0 && content[i][j] == 0
                        && (i > 4 && i < 7 || j > 4 && j < 7)) {
                    dragon3--;
                    content[i][j] = 3;
                }
            }
        }
    }
    while (dragon4 != 0) {
        for (int i = 0; i < 9; i++) {
            for (int j = 0; j < 9; j++) {
                int x = (int) (Math.random() * 2);
                if (x != 1 && dragon4 != 0 && content[i][j] == 0
                        && (i > 6 && i < 9 || j > 6 && j < 9)) {
                    dragon4--;
                    content[i][j] = 4;
                }
            }
        }
    }
    while (dragon5 != 0) {
        for (int i = 0; i < 10; i++) {
            for (int j = 0; j < 10; j++) {
                int x = (int) (Math.random() * 2);
                if (x != 1 && dragon5 != 0 && content[i][j] == 0
                        && (i > 8 && i < 10 || j > 8 && j < 10)) {
                    dragon5--;
                    content[i][j] = 5;
                }
            }
        }
    }
    while (food != 0) {
        for (int i = 0; i < 10; i++) {
            for (int j = 0; j < 10; j++) {
                int x = (int) (Math.random() * 2);
                if (x != 1 && food != 0 && content[i][j] == 0) {
                    food--;
                    content[i][j] = 6;
                }
            }
        }
    }
    discovered[0][0] = 1;
}
public int getDiscovered(int i, int j) {
    return discovered[i][j];
}
public int getContent(int i, int j) {
    return content[i][j];
}
public int getHeroX() {
    return heroX;
}
public int getHeroY() {
    return heroY;
}
public void setDiscovered(int i, int j, int k) {
    MapMake.discovered[i][j] = k;
}
public void setContent(int i, int j, int k) {
    MapMake.content[i][j] = k;
}
public void setHeroX(int heroX) {
    this.heroX = heroX;
}
public void setHeroY(int heroY) {
    this.heroY = heroY;
}
}

地图刷新

package game;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class MapRefresh extends Gui{
static MapMake mapMake = Gui.mapMake;

@SuppressWarnings("unused")
public void MapRefresh() {
    BufferedImage hall = null;
    BufferedImage valge = null;
    JPanel panel = Gui.panel;
    for (int i = 0; i < 10; i++) {
        for (int j = 0; j < 10; j++) {
            //              panel.add(new JButton("" + content[i][j]));
            if (mapMake.getDiscovered(i, j) == 1) {
                panel.add(new JLabel("hero on siin peal"));
            } else if (mapMake.getDiscovered(i, j) == 0) {
                try {
                    panel.add(new JLabel(new ImageIcon(hall = ImageIO.read(new File("C:/hall.jpg")))));
                } catch (IOException e) {
                } catch (NullPointerException e){

                }
            } else {
                try {
                    panel.add(new JLabel(new ImageIcon(valge = ImageIO.read(new File("C:/valge.jpg")))));
                } catch (IOException e) {
                } catch (NullPointerException e){

                }
            }
        }
    }
}
}

和听众

package game;

import java.awt.event.*;

import javax.swing.JPanel;

public class Listener extends Gui implements KeyListener{
static MapRefresh mapRefresh = new MapRefresh();
static MapMake mapMake = Gui.mapMake;
static JPanel panel = Gui.panel;
static Fighting fighting = null;
@Override
public void keyPressed(KeyEvent e) {
}

@Override
public void keyReleased(KeyEvent e) {
    int x = mapMake.getHeroX();
    int y = mapMake.getHeroY();
    if (e.getKeyCode() == 37 && y > 0){
        mapMake.setDiscovered(x, y-1, 1);
        mapMake.setDiscovered(x, y, 2);
        mapMake.setHeroY(y - 1);
    } else if(e.getKeyCode() == 38 && x > 0){
        mapMake.setDiscovered(x-1, y, 1);
        mapMake.setDiscovered(x, y, 2);
        mapMake.setHeroX(x - 1);
    } else if (e.getKeyCode() == 39 && y < 9){
        mapMake.setDiscovered(x, y+1, 1);
        mapMake.setDiscovered(x, y, 2);
        mapMake.setHeroY(y + 1);
    } else if (e.getKeyCode() == 40 && x < 9){
        mapMake.setDiscovered(x+1, y, 1);
        mapMake.setDiscovered(x, y, 2);
        mapMake.setHeroX(x + 1);
    }
    int z = mapMake.getContent(x, y);
    panel.removeAll();
    System.out.println(e.getKeyCode());
    mapRefresh.MapRefresh();
    panel.validate();
    panel.repaint();

}

@Override
public void keyTyped(KeyEvent e) {      
}

}

我读到“Try Catch”正在减慢速度。是这样吗?如果是这样,我怎样才能使它变得更好?或者这就像完全的垃圾?

请记住,这是我们的第一个学期!这里也是它的一个 pastebin 副本http://pastebin.com/VM1cTvyX

4

3 回答 3

4

在您的MapRefresh类中,每次MapRefresh调用该方法时,您最多加载一个图像 100 次 - 2 个嵌套循环,每个循环 10 次迭代。这听起来像是你缓慢的根源。我只会在构造函数中加载这两个图像一次,然后在需要时引用它们。

于 2013-04-18T19:15:18.367 回答
2

在我自己看来,问题在于每次按下键时都会加载图像。它在硬盘驱动器上进行一些非常慢的读取操作。

在游戏开始时加载您的资源并稍后使用它们。

对于 try/catch 块,当您到达 catch 块时它会很慢,这会迫使 JVM 构建堆栈跟踪。在这里,您似乎永远无法到达 catch 块。

于 2013-04-18T19:15:56.133 回答
2

MapRefresh()方法每次更新都会大量加载这些图像。在 MapRefresh 构造函数期间存储一次图像是有益的,如下所示:

private ImageIcon imageIcon;

public class MapRefresh extends Gui{
static MapMake mapMake = Gui.mapMake;

imageIcon = new ImageIcon(hall = ImageIO.read(new File("C:/hall.jpg")));

//...
}

然后在添加到面板时只需使用:

panel.add(new JLabel(imageIcon));

您也可以为其他图像重复此操作。这应该允许您使用可以大大提高速度的方法消除“try/catch”块。

于 2013-04-18T19:24:25.900 回答