为什么我 运行 我保存的文件没有在游戏中使用?

Why is my saved file not being used in game when I run it?

我目前正在开发一个简单的 2D 游戏,类似于 Eclipse 中的 Minecraft Java。我目前正在尝试调试的功能之一是将生成的 2D 噪声图保存到与根文件夹 resources 分开的源文件夹中,然后使用保存的同一文件生成将在游戏 运行秒。我遇到的问题是我的程序不显示保存的最近生成的地图,它会显示以前的地图(来自其他测试 运行s)。

程序能够显示最近生成的地图的不同时间是:

  1. 我运行程序,关闭它,在Eclipse中点击刷新,然后再次运行程序。
  2. 找到工程文件,进入bin文件夹,删除之前Java编译生成的地图。
  3. 注释掉显示地图的代码,运行带有生成地图代码的程序,然后运行再次带有显示地图代码的程序。
  4. 在 Eclipse 中打开包含地图数据的文件,对其进行更新,然后 运行 程序。
  5. 运行程序多次,直到决定更新。

我可以确认程序成功生成了地图,并在每个 运行 中保存了它,所以我认为在这个意义上没有任何错误。我的假设是程序可以将地图数据保存到资源源文件夹,但由于某种原因在 运行 时间内不可用?这很奇怪,因为该程序看起来与存储地图数据以显示给玩家的位置相同。如果有人能指出我正确的方向或至少注意到我做错了什么,将不胜感激。

下面是截图和代码:

[文件结构][1]

调用对象的主要结构:

public GamePanel() {
    this.setPreferredSize(new Dimension(screen_width,screen_height));
    this.setBackground(Color.gray);
    this.setDoubleBuffered(true);
    
    key_handler = new KeyEvents();
    this.addKeyListener(key_handler);
    this.setFocusable(true);
        
    player = new Player(this,key_handler);
    
    //generate map and save map data
    map_generator = new TileMap(this); 
    
    //load saved map data to be displayed   
    tile_manager = new TileManager(this);
}

保存地图数据的map_generator对象的功能:

void saveMap(String map) {
        Path resource_path = Paths.get("resources","map_files");
        String map_path = resource_path.toFile().getAbsolutePath() + "\" + map;
        
        try {
            OutputStream map_stream = new FileOutputStream(map_path);
            for (int r=0; r<map_height; r++) {
                String map_row = "";
                for (int c=0; c<map_width; c++) {
                    map_row = map_row + map_array[r][c] + " ";
                }
                byte[] bytes = map_row.getBytes();
                map_stream.write(bytes);
                if (r!=map_height-1)
                    map_stream.write(10);
            }
            map_stream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

加载要显示给玩家的地图数据的tile_manager对象的函数

public void loadMap(String map) {
        try {
            InputStream map_stream = getClass().getResourceAsStream(map);
            BufferedReader map_reader = new BufferedReader
                    (new InputStreamReader(map_stream));
            
            int col = 0;
            int row = 0;
            while (col < game_panel.col_size && row < game_panel.row_size) {
                String map_line = map_reader.readLine();
                
                while (col < game_panel.col_size) {
                    String numbers[] = map_line.split(" ");
                    int num = Integer.parseInt(numbers[col]);
                    map_file[col][row] = num;
                    col++;
                }
                if (col == game_panel.col_size) {
                    col = 0;
                    row++;
                }
            }
            map_reader.close();
            
        } catch(IOException e) {
            e.printStackTrace();
        }
    }

我能够成功解决我的问题,现在我的程序使用它生成的地图数据并在 运行 时将其显示给玩家没有问题。解决方案是使用 VGA 关于使用已知来源的提示(在我的例子中是 Windows %APPDATA% 文件夹),而不是必须将数据读取和写入程序文件(特别是考虑到我想把它做成一个 jar将来导出并由其他人播放的文件)。

代码改动如下: saveMap 函数的顶部:

String working_directory = System.getenv("AppData") + "\" + map;
        
//Path resource_path = Paths.get("resources","map_files");
//String map_path = resource_path.toFile().getAbsolutePath() + "\" + map;

loadMap 函数的顶部:

String working_directory = System.getenv("AppData") + "\" + map;
        
        try {
            //InputStream map_stream = getClass().getResourceAsStream(map);
            InputStream map_stream = new FileInputStream(working_directory);

两个函数的第一行,System.getenv("AppData"),允许Java获取被标记的AppData文件夹的路径作为计算机 运行 最近版本 Windows OS 中的环境变量。默认情况下,AppData 文件夹是隐藏的,包含三个文件夹;本地、LocalLow 和漫游。测试时,地图数据保存在漫游中,我相信这是默认的,但我可能是错的。

在对此进行研究时,我确实发现这种方法很好,但在用户 运行 旧版本 Windows OS/Computer 或如果他们手动更改了系统中的 %APPDATA% 环境变量。在这些情况下,建议使用 Windows 本机 API 调用,即使它不是默认文件夹,它也会为您找到文件夹。有一个堆栈溢出 post,详细说明了如何通过 link 上的 java 实现本机 API 调用,如下所示: Is there a Java library to access the native Windows API?

由于我正在制作游戏并计划将其导出,所以我也很乐意展示如何执行此操作,但这将在程序充实和完善后稍后实施。谢谢大家的帮助和提示!