Blog/content/posts/2022/gamemaker/sleep-analog.md
2022-12-06 23:52:41 +03:00

4.5 KiB
Raw Blame History

title date draft tags
🕐 Реализуем sleep() в GameMaker 2022-12-06T23:28:06+03:00 false
gamedev
tips
gamemaker

Немного слов о sleep

В GameMaker отсутсвует функция sleep();
Не помню, была ли она в ранних версиях, но в v2022.11, использование этой функции вызывает Debugger в браузере.

Зачем мне sleep?

У меня появилась необходимость в функции sleep(), когда я столкнулся с одним багов при экспорте проекта в HTML5.

Баг был связан с генерацией рандомных чисел функццией irandom_range();

Разбираем код

Имеется объект, допустим oPwd.
В событии Create я создаю переменную pwd, которая вызывает функцию password_generate();

// Create event
pwd = password_generate(6);

Фукнкция password_generate() принимает в качестве аргумента длину пароля, который необходимо сгенерировать и возвращает его переменной.

function password_generate(_length) {
    var password = "";
    
    for (var i = 0; i < _length; i += 1) {
        randomize();

        var pwd_symbol = irandom_range(0, 9);

        password += string(pwd_symbol);
    }
    
    return password;
}

Код достаточно просто, но он не работает должныи образом.

При экспорте проекта в HTML5, пароль генерируется из одного числа.
Например: 111111, 999999, 444444.

Если добавить (для теста) в код вызов функции show_message(), пароль генерируется, как и задумывалось, рандомный.

Чиним баг генерации

Первое решение, которое пришло мне в голову, это использовать вызов функцииsleep(), чтобы хоть как-нибудь затормозить браузер и дать функции randomize() отработать правильно.

В англоязычном интернете, особенно на Reddit и форуме GM много тем, про функцию sleep() и как её можно реализовать.

Однако я подсмотрел рабочее, но не очень элегантное решение, это использовать оператор repeat.

repeat (<expression>)
{
    <statement>;
    <statement>;
    ...
}

При использовании оператора repeat блок кода повторяется столько раз, сколько указано в выражении.

Я добавил repeat в свою функцию password_generate() и код получился таким:

function password_generate(_length) {
    var password = "";
    
    for (var i = 0; i < _length; i += 1) {
        if (os_browser) {
            /*
             * Костыл специально для браузеров
             * Если не сделать "задержку",
             * то пароль будет состоять из одного числа
             */
            repeat ((current_month+current_day+current_hour+current_minute+current_second)*1000) {
                randomize();
            }
        }
        else {
            randomize();
        }
        
        var pwd_symbol = irandom_range(0, 9);

        password += string(pwd_symbol);
    }

    return password;
}

Решение вызывать фунцию randomize() несколько миллионов раз может быть и не самое умное, однако игра в браузере не лагает, CPU не нагружается, по этому решение имеет место быть.

P.S.

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