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
相关产品推荐
相关产品推荐

