2015-07-25 2 views
2

Я строил эту игру на Java. В основном это minecraft в 2D. Я сделал так, чтобы объекты блока удалялись при нажатии. Мой рендеринг блока объектов иногда дает исключение nullpointer после нажатия/удаления блока (случайным образом после примерно 200 блоков). Кажется, что объект иногда удаляется, когда игра находится в renderloop. Когда я добавляю try-catch, в следующем цикле рендеринга больше нет ошибки. Любые идеи, что вызывает это? Является ли этот gameloop прочным, я подозреваю, что именно это и вызывает мою ошибку.редко встречающийся nullpointer исключение (программирование игры Java)

метод визуализации в моем обработчике:

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); 
    } 
} 

Удаление с

ввода мышкой
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

Я предполагаю, что ваш обработчик ввода мышь работает как отдельный поток. В этом случае удаление блока может происходить в вашем цикле рендеринга.

Решение состоит в том, чтобы не удалять блоки непосредственно в обработчике мыши, а сохранять блоки для удаления в отдельном массиве. Эти блоки могут обрабатываться в выделенной позиции в вашем основном цикле прямо перед рендерингом.

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 
    } 
} 

Это может быть лучше рафинированным больше узнать о структуре вашего кода, но он должен получить вы идете в правильном направлении.

0

Предполагая, что вы используете разные темы для обновления состояния игры и рендеринга, это поведение не кажется мне таким странным, поскольку один поток может удалить объект, поскольку другой пытается его отобразить.

Хороший способ отладить это, чтобы заставить последовательный выполнение вашего кода. Проверьте, сохраняется ли текущее поведение. Хорошее введение (Android) в игровые циклы можно найти here

Смежные вопросы