Онлайн-справочник по самым часто задаваемым вопросам из темы "Как сделать?" на форуме QSP.su

12.3. Создаю действия с помощью цикла, но они работают неправильно. Что делать?

В: Создаю действия с помощью цикла, но они работают неправильно. Что делать?

О:

Это классическая "грабля", с которой сталкиваются все новички из-за неполного понимания порядка работы кода.

Допустим мы создаём действие:

i=1

act "Действие номер "+i:
    *pl "Это действие номер "+i
end

Что мы при этом увидим на экране? Перед созданием действия переменной `i` присвоено значение 1. Значит название действия будет склеено из текста "Действие номер " и значения переменной `i`, то есть будет выглядеть так: "Действие номер 1".

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

То есть, если мы нажмём на действие, когда переменная `i` равна 1, мы увидим на экране текст: "Это действие номер 1". Но если переменную `i` изменить уже после создания действия, то когда мы нажмём на действие, мы увидим другой текст. Например:

i=1

act "Действие номер "+i:
    *pl "Это действие номер "+i
end

i=2

В этом случае мы увидим на экране действие с названием "Действие номер 1", а текст, который оно выведет на экран при нажатии, будет такой: "Это действие номер 2".

Теперь давайте посмотрим, что происходит при создании действий с помощью цикла:

loop local i=1 while i<6 step i+=1:
    act "Действие номер "+i:
        *pl "Это действие номер "+i
    end
end

В конце цикла значение переменной `i` будет равно 6, тогда как цикл создаст нам пять действий с названиями:

Действие номер 1

Действие номер 2

Действие номер 3

Действие номер 4

Действие номер 5

При этом, какое бы действие мы не нажимали, поскольку значение переменной `i` будет равно 6, мы всегда при нажатии на действие будем видеть на экране строку текста: "Это действие номер 6".

Однако, мы можем формировать действия с конкретными значениями с помощью оператора `dynamic`:

loop local i=1 while i<6 step i+=1:
    dynamic 'act "Действие номер "+<<i>>:
            *pl "Это действие номер "+<<i>>
        end'

end

Теперь на каждом проходе цикла, когда плеер будет встречать оператор `dynamic`, этому оператору будет передаваться строка текста:

'act "Действие номер "+<<i>>:
    *pl "Это действие номер "+<<i>>
end'

Перед выполнением оператора `dynamic` плеер будет раскрывать подвыражения, подставляя вместо них значение `i`, соответствующее проходу. На первом проходе оператору `dynamic` будет передан такой текст:

dynamic 'act "Действие номер "+1:
    *pl "Это действие номер "+1
end'

На втором проходе такой:

dynamic 'act "Действие номер "+2:
    *pl "Это действие номер "+2
end'

И так далее.

`dynamic` выполняет код записанный в виде текста, и поскольку мы передаём ему команды для создания действий, будут созданы пять действий с конкретными числами в коде действий.

Для лучшего понимания попробуйте запустить такой код, и объясните его работу:

loop local i=1 while i<6 step i+=1:
    dynamic 'act "Действие номер "+<<i>>:
            *pl "Это действие номер "+<<i>>
            *pl "Значение переменной i: "+i
        end'

end