我正在用Java构建这个游戏。基本上它是2D中的我的世界。我做了它,以便在按下时删除块对象。我的块对象渲染有时在单击/删除块之后(在大约200个块之后随机)给出nullpointerexception。当游戏在renderloop中时,似乎有时会删除该对象。当我添加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();
}
答案 0 :(得分:0)
我假设您的鼠标输入处理程序作为单独的线程运行。在这种情况下,可以在渲染循环中删除块。
解决方案不是在鼠标处理程序中立即删除块,而是在单独的数组中保存要删除的块。在渲染之前,可以在主循环中的专用位置处理这些块。
答案 1 :(得分:0)
当渲染在另一个线程中运行时,很可能你的鼠标处理程序在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
}
}
这可以更好地了解您的代码结构,但它应该让您朝着正确的方向前进。
答案 2 :(得分:0)
假设您使用不同的线程来更新游戏状态和渲染,这种行为对我来说似乎并不奇怪,因为一个线程可能已经删除了一个对象,而另一个线程试图渲染它。
调试此方法的一种好方法是强制顺序执行代码。检查当前行为是否仍然存在。可以找到游戏循环的一个很好的介绍(Android)here