如何在Libgdx上制作精确的计时器?

时间:2016-11-20 18:47:43

标签: java libgdx

基本上我刚才创建的计时器是float timer += 1 * deltaTime,它每秒会加1,但我在使用它时遇到了问题。

if(timer < 2){
    //do something
}

我希望if语句在计时器为2秒时停止运行代码,因为我无法执行if(timer != 2f)因为它不会检测2秒因为它太快。这意味着我必须设置一个条件timer < 2f,这个条件不准确并且总是给我提供真实的结果。

2 个答案:

答案 0 :(得分:0)

为什么不使用Task和布尔值?

,而不是使用手工制作的计时器

下面的伪代码;

boolean stop = false;

Timer.schedule(new Task() {

    @Override
    public void run() {
        stop = true;
    }
}, 2f);

然后在你的渲染方法中;

 render() {

     if (!stop) {

         // Freefall
     }
 }

答案 1 :(得分:0)

如果我正确理解了您的问题,您希望您的代码处理X秒而不是更多(其中X可以是浮点值,例如12.556秒)。

我将提出一个单线程替代方案,你有一个自定义Timer类来管理你的freefall逻辑,如下所示。它监视进度,如果它看到大于持续时间的东西,它“趴在”内部逻辑,这样你的逻辑只执行指定的时间量(在我们玩浮点数时可配置的误差范围内)

下面的示例演示了这种不使用libGDX的事情(以防万一使用其他库的人感兴趣),但将模拟的getDeltaTime()方法换成Gdx.graphics.getDeltaTime()将是微不足道的。 / p>

package tech.otter.timing;

/**
 * Created by john on 11/20/16.
 */
public class TimingExample {
    public static void main(String... args) {
        boolean complete = false;

        Timer t = new Timer(15f) {
            // You could implement your logic here.
            @Override
            void action(float delta) {
                System.out.println(progress);
            }
        };

        while(!complete) {
            complete = t.update(getDeltaTime());
        }

        assert t.progress < t.duration;
        assert t.progress + t.errorMargin > t.duration;
    }

    /**
     * Simulates processing time by returning 0-100ms.
     * @return The number of milliseconds that have allegedly elapsed since the last call.
     */
    public static float getDeltaTime() {
        return (float)(Math.random() / 10);
    }

    abstract static class Timer {
        private float duration;
        protected float progress;
        private float errorMargin;

        public Timer(float duration) {
            this(duration, 0.0001f);
        }
        public Timer(float duration, float errorMargin) {
            this.duration = duration;
            this.errorMargin = errorMargin;
            this.progress = 0f;
        }

        /**
         * Update the timer based on how long since the last call.
         * @param delta The amount of time since the last call.
         * @return Whether the timer's progressed has met the duration.
         */
        public boolean update(float delta) {
            // This if-statement "caps" the delta so that we will never exceed the duration.
            if(progress + delta > duration) {
                delta = duration - progress;
            }
            progress += delta;
            action(delta);

            // Return "true" if the progress is equal to the duration (+/- a small margin just in case since we use floats).
            return progress + errorMargin > duration && progress - errorMargin < duration;
        }

        /**
         * Override this method with your game logic.
         * You should not call it directly.
         * @param delta The amount of time that has elapsed since the timer was last updated.
         */
        abstract void action(float delta);
    }
}