2016-12-06 8 views
0

Я пытаюсь создать игровой цикл с точным таймером. Я знаю, что TimeUnit использует thread.sleep();, который может варьироваться в зависимости от миллисекунд. Мой вопрос прост:Создание thread.sleep exact

Этот код делает thread.sleep(); более точным?

и далее

Что я могу сделать, чтобы исправить/сделать его лучше, или я должен отказаться от нее?

import java.util.concurrent.TimeUnit; 

public class Timer implements Runnable { 

public static void main(String[]args){ 
    new Timer().start(); 
} 

public int ups = 1; 

@Override 
public void run() { 
    int uc = 0; 
    long startTime = 0; 
    long result = 0; 
    long offset = 0; 
    while(true){ 
     startTime = System.nanoTime(); 
     uc++; 
     if(uc==1000/ups){ 
      update(); 
      uc=0; 
     } 
     result = System.nanoTime()-startTime; 
     if(1000000-result>0) 
      try { 
       int prefered = 1000000; 
       startTime = System.nanoTime(); 
       TimeUnit.NANOSECONDS.sleep(prefered-result-offset); 
       offset = System.nanoTime()-startTime-prefered+result+offset; 
      } catch (InterruptedException e) { 
       System.out.println("an error has occured"); 
      } 
    } 
} 

public void update(){ 
    System.out.println("Hello World"); 
} 

public void start(){ 
    new Thread(this).start(); 
} 
} 

Я уже видел this кстати. Я мог бы также добавить

Как это сравнить с другим циклом?

Edit: Это для настольной игры, а не мобильного

+1

Стандарта Java не собирается работать на микросекунды уровня в реальное время точности без внешней (т.е. родной библиотеки) помощи, если когда-либо , –

+0

@Jim Garrison Ну тогда у вас есть предложения? – cat16

+0

В зависимости от вашей среды - встроенный, рабочий стол, Pi и т. Д. Если вам нужна точность в микросекундах, вам, вероятно, придется писать нечто похожее на аппаратное обеспечение, которое компилируется для машинных инструкций (т. Е. Не интерпретируемых байт-кодов), таких как C. –

ответ

0

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

Timer timer = new Timer() 
timer.scheduleAtFixedRate(new TimerTask() { 
    @Override 
    public void run() { 
    // Your periodic code here 
    } 
}, 0, 1);