Android Studio 可以在执行时更改 TimerTask() 周期吗?

Android Studio changing TimerTask() period while executing possible?

我有一个小游戏,它会在随机位置生成一个敌人,并每秒传送到另一个随机位置。 我的问题是,随着计时器不断减少,我不知道如何使传送速度更快。

我的计时器从 60 秒开始,然后逐渐减少,直到达到“还剩 0 秒”,游戏结束。

我想将“传送”的延迟更改为 -> 还剩 45 秒时每 0.8 秒或还剩 25 秒时每 0.5 秒等。

所以定时器的周期会在经过一定时间后自动改变。

这是我到目前为止尝试过的方法,但没有任何作用。在整个 60 秒内,传送仍然每 1 秒发生一次。

static int period;
static int periodCounter = 0;
// Load progressBar from 0s to 60s

    private void progressLoad() {
        final int[] counter = {pgrBar.getProgress()};
        final Timer timer = new Timer();
        final TimerTask timerTask = new TimerTask() {

            @Override
            public void run() {
                counter[0]++;
                periodCounter++;
                pgrBar.setProgress(counter[0]);

                runOnUiThread(new Runnable() {
                    public void run() {
                        tv_progress.setText("Zeit verbleibend: " + (60 - counter[0]));
                    }
                });

                if (counter[0] == 60)
                    timer.cancel();
                if (counter[0] == 60)
                    gameOver();
            }

        };

        timer.schedule(timerTask, 0, 1000);

    }
// Change period variable depending on seconds left

    private void changePeriod() {
        if (periodCounter <= 10)
            period = 1000;
        else if (periodCounter <= 20)
            period = 800;
        else if (periodCounter <= 30)
            period = 600;
        else  if (periodCounter <= 40)
            period = 475;
        else if (periodCounter <= 50)
            period = 350;
    }
// TimerTask for teleporting the enemy to random position (x,y) starting at every 1 sec

timer.schedule(new TimerTask() {
            @Override
            public void run() {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        Random R = new Random();
                        float dx = R.nextFloat() * width[0];
                        float dy = R.nextFloat() * height[0];
                        if (dx > (width[0] - imWidth[0]))
                            dx = width[0] - imWidth[0];
                        if (dy > (height[0] - imHeight[0]))
                            dy = height[0] - imHeight[0];
                        iv_muecke.animate()
                                .x(dx)
                                .y(dy)
                                .setDuration(0)
                                .start();
                    }
                });
            }
        }, 0, period);
private void teleportEnemy() {
    final Timer timer = new Timer();
    timer.schedule(new TimerTask() {
        @Override
        public void run() {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    Random R = new Random();
                    float dx = R.nextFloat() * width[0];
                    float dy = R.nextFloat() * height[0];
                    if (dx > (width[0] - imWidth[0]))
                        dx = width[0] - imWidth[0];
                    if (dy > (height[0] - imHeight[0]))
                        dy = height[0] - imHeight[0];
                    iv_muecke.animate()
                            .x(dx)
                            .y(dy)
                            .setDuration(0)
                            .start();
                }
            });
        }
    }, 0, period);
}

根本原因

在Android中,Timer安排任务一次性执行,或定期重复执行。这解释了为什么当您调用 schedule() 并传递 period 时,它会在该时间后定期重复。

解决方案

如果要安排在动态时间执行的任务,则使用 Handler。因此,将您的代码更改为。

private void teleportEnemy() {
    Handler handler = new Handler(Looper.getMainLooper());
    handler.post(new Runnable() {
        @Override
        public void run() {
            Random R = new Random();
                    float dx = R.nextFloat() * width[0];
            float dy = R.nextFloat() * height[0];
            if (dx > (width[0] - imWidth[0]))
                dx = width[0] - imWidth[0];
            if (dy > (height[0] - imHeight[0]))
                dy = height[0] - imHeight[0];
            iv_muecke.animate()
                    .x(dx)
                    .y(dy)
                    .setDuration(0)
                    .start();

            if (!isGameOver()) {
                handler.postDelayed(this, period);
            }
        }
    });
}

private boolean isGameOver() {
    return pgrBar.getProgress() == 60;
}