gpt4 book ai didi

java - 线程中对象的速度不准确

转载 作者:太空宇宙 更新时间:2023-11-04 11:23:22 25 4
gpt4 key购买 nike

我有一个 MainThread 类,它用作游戏循环。然后在我的面板中,我有这些矩形,它们是音符和线条,它们是乐谱的小节线(我解析音乐 XML 文件并根据解析的数据绘制它们),我还解析速度,我希望它们根据速度移动。我有一个函数 updateX(float x) 可以更新对象的 x 位置。在线程启动时,我设置了一个变量 startTime = System.CurrentTimeMillis(),然后计算 elapsedTime = System.CurrentTimeMillis() - startTime。那么 delta x 就是速度*耗时,其中速度 =(小节的长度/节拍数)*(60000 毫秒/节奏)。但问题是,当我用节拍器测试时,它并不准确。此外,音符(矩形)往往比线条移动得快一些。这是主线程:

public class MainThread extends Thread{
public static final int MAX_FPS = 30;
private double averageFPS;
private SurfaceHolder surfaceHolder;
private PlayPanel playPanel;
private boolean running;
public static Canvas canvas;

public MainThread(SurfaceHolder surfaceHolder, PlayPanel playPanel) {
super();
this.surfaceHolder = surfaceHolder;
this.playPanel = playPanel;
}
ScheduledExecutorService scheduler =
Executors.newScheduledThreadPool(1);
ScheduledFuture scheduledFuture;

long tick = 0;
int count = 1;
public void start() {

final Runnable runnable = new Runnable() {
@Override
public void run() {

canvas = null;

if (metronomeOn) {
if (tick == 0) {
// System.out.println(TAG + " Running " + tick + " " + 60000/tempo);
if (count % beat == 1) {
sendMidi(0x99, 77, 64);
// System.out.println("TICK");
} else {
sendMidi(0x99, 76, 64);
// System.out.println("TACK");
}
count++;
tick++;

} else if (tick >= 600/tempo - 1) {
tick = 0;
} else {
// System.out.println(TAG + " Running " + tick + " " + 60000/tempo);
tick++;
}
} else if (!metronomeOn) {
tick = 0;
count = 1;
}

try {
canvas = surfaceHolder.lockCanvas();
playPanel.update();
playPanel.draw(canvas);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (canvas != null) {
try {
surfaceHolder.unlockCanvasAndPost(canvas);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
};

scheduledFuture =
scheduler.scheduleAtFixedRate(runnable, 0, 100, TimeUnit.MILLISECONDS);
}


public void cancel() {
scheduledFuture.cancel(true);
}

这是 updateX 函数:

// updates the x_position of the notes
public void updateX(float x) {
rectangle.set(x, rectangle.top, x+rectangle.width(), rectangle.bottom);
rectangle2.set(x, rectangle2.top, x+rectangle2.width(), rectangle2.bottom);
if (ledger != null) {
ledger.updateX(x);
}
}

// updates the x position of the lines
public void updateX(float x) {
startX = x;
stopX = x;
}

和更新函数:

 // updates the notes with the given speed
public void update(float s, long startTime) {
float elapsedTime = (float)(System.currentTimeMillis() - startTime);
//System.out.println(TAG + "elapsed time float: " + elapsedTime + " elapsed time long " + (System.currentTimeMillis() - startTime));
for (Notes n : notes) {
n.decrementX(s * elapsedTime);
}

有人知道为什么会发生这种情况或者有解决办法吗?提前致谢。

补充一下,我已经使用 countDownTimer 实现了一个节拍器,并且根据节奏是准确的,所以我想知道我是否可以使用 countDownTimer 实现游戏循环?!

最佳答案

Thread.sleep 对于您的目的来说不够准确。当线程退出 sleep 状态时,它可能不会被安排立即执行。 sleep 结束和恢复执行之间的时间是未定义的,例如取决于系统当前的繁忙程度。

我建议您查看java.util.concurrent.ScheduledExecutorService.scheduleAtFixedRate()。您可以将其配置为以固定时间间隔运行更新代码。它在测量时间方面可能会比您自己的 while 循环做得更好。

关于java - 线程中对象的速度不准确,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44657943/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com