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

121 lines
4.5 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
title: "🕐 Реализуем sleep() в GameMaker"
date: 2022-12-06T23:28:06+03:00
draft: false
tags: [gamedev, tips, gamemaker]
---
## Немного слов о sleep
В [GameMaker](https://gamemaker.io/) отсутсвует функция **sleep();**
Не помню, была ли она в ранних версиях, но в v2022.11,
использование этой функции вызывает Debugger в браузере.
## Зачем мне sleep?
У меня появилась необходимость в функции `sleep()`,
когда я столкнулся с одним багов при экспорте проекта в HTML5.
Баг был связан с генерацией рандомных чисел функццией `irandom_range()`;
## Разбираем код
Имеется объект, допустим `oPwd`.
В событии `Create` я создаю переменную `pwd`, которая вызывает функцию `password_generate()`;
```cpp
// Create event
pwd = password_generate(6);
```
Фукнкция `password_generate()` принимает в качестве аргумента длину пароля,
который необходимо сгенерировать и возвращает его переменной.
```cpp
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()`](https://manual.yoyogames.com/GameMaker_Language/GML_Reference/Maths_And_Numbers/Number_Functions/randomise.htm)
отработать правильно.
В англоязычном интернете, особенно на Reddit и форуме GM много тем,
про функцию `sleep()` и как её можно реализовать.
Однако я подсмотрел рабочее, но не очень элегантное решение,
это использовать оператор [`repeat`](https://manual.yoyogames.com/GameMaker_Language/GML_Overview/Language_Features/repeat.htm).
```cpp
repeat (<expression>)
{
<statement>;
<statement>;
...
}
```
При использовании оператора `repeat` блок кода повторяется столько раз,
сколько указано в выражении.
Я добавил `repeat` в свою функцию `password_generate()` и код получился таким:
```cpp
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.
Если у тебя имеется идея по лучше, пожалуйста предлагай.
Если я сам найду решение лучше, я обязательно оставлю здесь ссылку.