Генерация случайного числа каждый раз в определенный интервал времени в Java - PullRequest
0 голосов
/ 04 января 2019

У меня есть метод, который рисует текстуры во время выполнения.

Я генерирую случайное число, которое изменяет высоту текстуры.

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

Я генерирую случайное число с:

Random r = new Random();
int low = 0;
int high = 30;
int result1 = r.nextInt(high-low) + low;

Вот мой drawTower() метод:

private void drawTower() {

    batcher.draw(AssetLoader.texture1, tower1.getX(), tower1.getY() + tower1.getHeight() - result1, 
           tower1.getWidth(), midPointY - (tower1.getHeight()));    
}

Вы можете видеть, что есть result1, который является случайно сгенерированным числом.

Теперь проблема : в моем методе render() я использую этот метод drawTower(), что является причиной создания всех возможных случайных чисел.

Как я могу исправить эту проблему? Я думал о генерации случайного числа, и через определенный промежуток времени генерируется новое случайное число. Но я не знаю, как это делается.

public void render(float runTime) {

    Wizard wizard = myWorld.getWizard();

    // Fill the entire screen with black, to prevent potential flickering.
    Gdx.gl.glClearColor(0, 0, 0, 1);
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

    // Begin ShapeRenderer
    shapeRenderer.begin(ShapeRenderer.ShapeType.Filled);

    // Draw Background color
    shapeRenderer.setColor(55 / 255.0f, 80 / 255.0f, 100 / 255.0f, 1);
    shapeRenderer.rect(0, 0, 136, midPointY + 66);

    // End ShapeRenderer
    shapeRenderer.end();

    // Begin SpriteBatch
    batcher.begin();      
    batcher.enableBlending(); 

    batcher.draw(AssetLoader.texture0,
            wizard.getX(), wizard.getY(), wizard.getWidth(), wizard.getHeight());

    // Draw Tower
    drawTower();

    // End SpriteBatch
    batcher.end();

}

1 Ответ

0 голосов
/ 04 января 2019

Вы можете создать объект, который предоставляет новое случайно сгенерированное значение с заданным интервалом, и назначить этот объект как поле в классе, содержащем метод drawTower. Обратите внимание, что этот объект генератора должен быть правильно синхронизирован, потому что один поток будет получать доступ к случайно сгенерированному значению, в то время как другой поток будет обновлять его:

public class TimedRandomNumberGenerator {

    private final AtomicInteger value = new AtomicInteger();
    private final Timer valueUpdater;

    public TimedRandomNumberGenerator(long updateRateInMs) {
        valueUpdater = new Timer();
        valueUpdater.schedule(createTimerTask(), 0, updateRateInMs);
    }

    private TimerTask createTimerTask() {
        return new TimerTask() {
            public void run() {
                value.set(generateNewValue());
            }
        };
    }

    private static int generateNewValue() {
        Random r = new Random();
        int low = 0;
        int high = 30;
        return r.nextInt(high-low) + low;
    }

    public int getValue() {
        return value.intValue();
    }
}

В классе, который содержит метод drawTower (обратите внимание, что для этого примера частота обновления установлена ​​на 1000 миллисекунды, но может быть изменена на любой желаемый период):

public class SomeClass {

    private final TimedRandomNumberGenerator generator = new TimedRandomNumberGenerator(1000);

    private void drawTower() {
        batcher.draw(
            AssetLoader.texture1,
            tower1.getX(), 
            tower1.getY() + tower1.getHeight() - generator.getValue(),
            tower1.getWidth(), midPointY - (tower1.getHeight())
        );    
    }
}

Синхронность TimedRandomNumberGenerator фиксируется при использовании AtomicInteger. Это защищает случайно сгенерированное значение от нескольких читателей и нескольких писателей (в данном случае один писатель: сам TimedRandomNumberGenerator). Метод createTimerTask является просто вспомогательным методом, поскольку класс TimerTask не является функциональным интерфейсом (и поэтому не может быть заменен лямбда-выражением). Вызов метода valueUpdater.schedule в конструкторе - это то, что планирует случайное число, которое будет обновлено после истечения желаемого периода времени.

...