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

Java Native方法FATAL ERROR报错修复求助(ShadowDance开发场景)

ShadowDance加载轨道图片时LWJGL Native致命错误修复方案

错误根源

这个致命错误是因为OpenGL上下文还没初始化完成,就调用了需要GL环境的纹理创建方法。你的代码在ShadowDance构造函数里直接调用readCSV()实例化LaneLeft等轨道类,而这些类会在实例化时加载图片(底层调用glGenTextures)——但此时Bagel框架的窗口和GL上下文还没完全建好,没有有效上下文的情况下调用GL原生方法直接导致JVM终止。

修复步骤

1. 拆分轨道配置读取与对象初始化

把原来的readCSV()拆成两步:先读轨道坐标存在变量里,等游戏启动(GL上下文就绪)再创建轨道对象:

public class ShadowDance extends AbstractGame  {
    // 原有成员变量保留...
    // 新增存储轨道坐标的变量
    private Double leftLaneX, rightLaneX, upLaneX, downLaneX;

    public ShadowDance(){
        super(WINDOW_WIDTH, WINDOW_HEIGHT, GAME_TITLE);
        // 只读取CSV里的轨道坐标,不创建轨道对象
        readLaneCoordinates();
    }

    private void readLaneCoordinates() {
       try (BufferedReader br = new BufferedReader(new FileReader(WORLD_FILE))) {
            String text;
            while ((text = br.readLine()) != null) {
                String[] lanes = text.split(",");
                if(lanes[0].equals("Lane")){
                    switch(lanes[1]){
                        case LEFT: leftLaneX = Double.parseDouble(lanes[2]); break;
                        case RIGHT: rightLaneX = Double.parseDouble(lanes[2]); break;
                        case UP: upLaneX = Double.parseDouble(lanes[2]); break;
                        case DOWN: downLaneX = Double.parseDouble(lanes[2]); break;
                    }
                }       
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    protected void update(Input input) {
        if (input.wasPressed(Keys.ESCAPE)){
            Window.close();
        }

        BACKGROUND_IMAGE.draw(Window.getWidth()/2.0, Window.getHeight()/2.0);

        if (!start){
            TITLE_FONT.drawString(GAME_TITLE, TITLE_POINT.x, TITLE_POINT.y);
            INSTRUCTION_FONT.drawString(INSTRUCTION, INSTRUCTION_POINT.x, INSTRUCTION_POINT.y);
            if(input.wasPressed(Keys.SPACE)){
                start = true;
                // 游戏启动时再初始化轨道,此时GL上下文已经就绪
                initAllLanes();
            }
        }
        else{
            laneLeft.update();
            // 别忘了加上其他轨道的update调用
            laneRight.update();
            laneUp.update();
            laneDown.update();
        }
    }

    // 专门初始化轨道对象的方法
    private void initAllLanes(){
        if(leftLaneX != null) laneLeft = new LaneLeft(leftLaneX);
        if(rightLaneX != null) laneRight = new LaneRight(rightLaneX);
        if(upLaneX != null) laneUp = new LaneUp(upLaneX);
        if(downLaneX != null) laneDown = new LaneDown(downLaneX);
    }
}

2. 确认轨道类的图片加载逻辑

确保LaneLeft等类的图片是在实例化时加载(现在实例化时机已经正确),比如:

public class LaneLeft {
    private final Image LANE_IMG = new Image("res/laneLeft.png");
    private double xPos;

    public LaneLeft(double x){
        this.xPos = x;
    }

    public void update(){
        LANE_IMG.draw(xPos, Window.getHeight()/2.0);
        // 其他轨道逻辑...
    }
}

关键注意事项

  • 所有涉及加载纹理(Image、Font)的操作,必须放在update方法执行之后或者内部,只有此时Bagel的GL上下文才完全初始化好。
  • 绝对不要在构造函数、静态代码块里加载资源,这些时机都早于GL上下文的创建,必然触发类似错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 12:17:45