121 lines
4.5 KiB
Markdown
121 lines
4.5 KiB
Markdown
|
---
|
|||
|
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.
|
|||
|
|
|||
|
Если у тебя имеется идея по лучше, пожалуйста предлагай.
|
|||
|
Если я сам найду решение лучше, я обязательно оставлю здесь ссылку.
|