当前位置: 代码迷 >> java >> 罕见的空指针异常(游戏编程Java)
  详细解决方案

罕见的空指针异常(游戏编程Java)

热度:50   发布时间:2023-07-17 20:02:37.0

我正在用Java开发这款游戏。 基本上是2D模式下的Minecraft。 我做到了,以便在按下时删除块对象。 在单击/删除一个块之后,我的块对象渲染有时会给出nullpointerexception(大约在200个块之后随机)。 似乎游戏在渲染循环中有时会删除该对象。 当我添加try-catch时,下一个渲染周期不再有错误。 任何想法是什么原因造成的? 这是一个可靠的游戏循环吗,我怀疑是造成我错误的原因。

我的处理程序中的渲染方法:

LinkedList<GameObject> object = new LinkedList<GameObject>();

public void render(Graphics g){
    for(int i = 0; i < object.size(); i++){
        GameObject tempObject = object.get(i);//sometimes nullpointer when getting the object I clicked on
        tempObject.render(g);
    }
}

使用mouseInput删除

for(int i = 0; i < handler.object.size(); i++){
        if(handler.object.get(i).getID() == ID.Block){
            int x1 = (int) handler.object.get(i).getX();
            int y1 = (int) handler.object.get(i).getY();
            //if mouse is over object
            if((MouseX >= x1+1 && MouseX <= (x1 +32-1)) && (MouseY >= y1+1 && MouseY <= (y1 +32-1))){
                Block b = (Block) handler.object.get(i);
                inventory.addInventoryBlocks(b.getType(), 1);
                handler.removeObject(handler.object.get(i));
            }
        }
    }

Gameloop:

public void run() {
    this.requestFocus();
    long lastTime = System.nanoTime();
    double amountOfTicks = 60;
    double ns = 1000000000 / amountOfTicks;
    double delta = 0;
    long timer = System.currentTimeMillis();
    int frames = 0;
    while(running){
        long now = System.nanoTime();
        delta += (now - lastTime) / ns;
        lastTime = now;
            while(delta >= 1){
                tick();
                delta--;
            }
        if(running)
            render();
        frames++;

        if(System.currentTimeMillis() - timer > 1000){
            timer += 1000;
            //System.out.println("FPS: " + frames);
            frames = 0;
        }
    }
    stop();
}

我假设您的鼠标输入处理程序作为单独的线程运行。 在这种情况下,可以在渲染循环中删除块。

一种解决方案不是在鼠标处理程序中立即删除这些块,而是将要删除的块保存在单独的数组中。 在渲染之前,可以在主循环中的专用位置处处理这些块。

鼠标处理程序很可能在AWT线程中运行,而渲染器在另一个线程中运行。 在这种情况下,您将遭受并发麻烦。

尝试使用关键部分。

public static Object lock = new Object();

public void render(Graphics g){
    synchronized(lock)
    {
        for(int i = 0; i < object.size(); i++){
            GameObject tempObject = object.get(i);//sometimes nullpointer when getting the object I clicked on
           tempObject.render(g);
        }
    }
}

void mouseInputHandler()
{
    synchronized( lock )
    {
        code
    }
}

更好地了解代码结构可能会更好,但它应该使您朝正确的方向前进。

假设您使用不同的线程来更新游戏状态和渲染,这种行为对我来说似乎并不奇怪,因为一个线程可能删除了一个对象,而另一个线程则试图渲染它。

调试此错误的一种好方法是强制代码顺序执行。 检查当前行为是否仍然存在。 可以在找到游戏循环的不错介绍(Android)

  相关解决方案