You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java游戏地图加载异常与地图切换功能故障求助

Java游戏地图加载与切换问题修复方案

一、地图加载异常问题修复

问题根源

  1. loadMaps()循环加载所有地图,后续地图会覆盖mapTileNum数组,最终仅保留最后一张地图数据;
  2. loadMap()未处理文件读取到末尾的null情况,易引发数组越界异常;
  3. TileManager未与MapLoader的地图数据关联,导致加载的数据无法渲染。

修复代码

修改MapLoader类的地图加载逻辑

// 替换原loadMaps方法,改为只加载当前索引的地图
public void loadCurrentMap() {
    loadMap(mapPaths.get(currentMapIndex));
}

// 完善loadMap方法的异常与边界处理
public void loadMap(String filePath) {
    try {       
        InputStream is = getClass().getResourceAsStream(filePath);
        if (is == null) {
            System.err.println("地图文件不存在: " + filePath);
            return;
        }
        BufferedReader br = new BufferedReader(new InputStreamReader(is));
        
        int col = 0;
        int row = 0;
        
        while(row < gp.maxScreenRow) {
            String line = br.readLine();
            if (line == null) break;
            
            String numbers[] = line.trim().split("\\s+"); // 兼容多空格分隔
            col = 0;
            // 避免数组越界,同时处理每行数据不足的情况
            while(col < gp.maxScreenCol && col < numbers.length) {
                int num = Integer.parseInt(numbers[col]);
                mapTileNum[col][row] = num;
                col++;
            }
            // 补全行中缺失的列,默认填充草地
            while(col < gp.maxScreenCol) {
                mapTileNum[col][row] = 0;
                col++;
            }
            row++;
        }
        // 补全缺失的行
        while(row < gp.maxScreenRow) {
            for(col = 0; col < gp.maxScreenCol; col++) {
                mapTileNum[col][row] = 0;
            }
            row++;
        }
        br.close();
        System.out.println("成功加载地图: " + filePath);
    }catch(Exception e) {
        System.err.println("加载地图失败: " + filePath);
        e.printStackTrace();
    }
}

关联TileManager与MapLoader数据

修改TileManager类,让其获取MapLoader的地图数据用于渲染:

public class TileManager {
    GamePanel gp;
    MapLoader mapLoader;

    public TileManager(GamePanel gp) {
        this.gp = gp;
        this.mapLoader = gp.mapLoader; // 关联GamePanel中的MapLoader实例
    }
    
    public void draw(Graphics2D g2) {
        // 遍历地图数据绘制地形
        for(int row = 0; row < gp.maxScreenRow; row++) {
            for(int col = 0; col < gp.maxScreenCol; col++) {
                int tileNum = mapLoader.mapTileNum[col][row];
                int x = col * gp.tileSize;
                int y = row * gp.tileSize;
                // 根据tileNum绘制对应地形(草地/沥青路/沙地)的逻辑
            }
        }
    }
}

调整GamePanel初始化逻辑

public GamePanel() {
    this.setPreferredSize(new Dimension(screenWidth, screenHeight));
    this.setBackground(Color.gray);
    this.setDoubleBuffered(true);
    this.addKeyListener(keyH);
    this.setFocusable(true);
    mapLoader.loadCurrentMap(); // 初始化时加载当前索引的地图
}

二、地图切换功能失效修复

问题根源

  1. 玩家坐标判断未考虑自身尺寸,导致触发条件偏差;
  2. 切换地图后未强制触发重绘,新地图无法显示;
  3. GamePanel的main方法重复创建MapLoader实例,导致数据不统一。

修复代码

修改MapLoader的切换方法

public void switchToNextMap() {
    if (currentMapIndex < mapPaths.size() - 1) {
        currentMapIndex++;
        loadCurrentMap();
        System.out.println("切换到地图: " + (currentMapIndex + 1));
    } else {
        System.out.println("已到达最后一张地图");
    }
}

public void switchToPreviousMap() {
    if (currentMapIndex > 0) {
        currentMapIndex--;
        loadCurrentMap();
        System.out.println("切换到地图: " + (currentMapIndex + 1));
    } else {
        System.out.println("已到达第一张地图");
    }
}

完善GamePanel的切换触发逻辑

public void update() {
    player.update();
    
    int playerX = player.getX();
    int playerY = player.getY();
    int tileSize = this.tileSize;

    // 考虑玩家自身尺寸,判断是否到达右侧边缘
    if (playerX + player.getWidth() >= screenWidth) {
        mapLoader.switchToNextMap();
        player.setX(0);
        repaint(); // 强制重绘新地图
    } 
    // 判断是否到达底部边缘
    else if (playerY + player.getHeight() >= screenHeight) {
        mapLoader.switchToNextMap();
        player.setY(0);
        repaint();
    }
}

清理GamePanel的main方法

public static void main(String[] args) {
    GamePanel gamePanel = new GamePanel();
    
    JFrame frame = new JFrame("F1 Monaco");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setContentPane(gamePanel);
    frame.pack();
    frame.setLocationRelativeTo(null);
    frame.setVisible(true);
    
    gamePanel.startGameThread(); // 启动游戏线程,无需重复创建MapLoader
}

额外建议

  • 确保地图文件路径正确:/maps/map01.txt对应项目的resources/maps/目录(Maven/Gradle结构)或src根目录下的maps文件夹;
  • 在Player类中添加getWidth()和getHeight()方法,返回玩家精灵实际尺寸,提升坐标判断准确性;
  • 可在MapLoader中添加地图加载完成的回调,通知TileManager主动刷新渲染。

内容的提问来源于stack exchange,提问作者yufka man

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 06:44:57