Перейти к содержимому

Ритм программы

Шестьдесят итераций в секунду нужны редко. Разбираемся, как выбрать ритм и чем его задать

Программа без wait работает на полной скорости всегда. Для мигающей лампы это ничего не меняет, а для программы, которая опрашивает десяток блоков, — меняет всё: она будет делать это сотни раз в секунду, хотя достаточно двух.

тик 0
Информация0
=
у
Операция1
=
Ждать2
@counter0number
медьnullnull
проверокnullnull

Нажмите «пуск». проверок растёт по два в секунду, и этого хватает: медь в контейнере не меняется шестьдесят раз в секунду, а если бы и менялась — вы бы этого не увидели.

Задача Разумный ритм
следить за запасом на складе 2–5 раз в секунду
включать и выключать блоки по условию 5–10 раз в секунду
вести юнита, рисовать на дисплее каждый тик, без wait
считать что-то раз в волну раз в несколько секунд

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

Своих инструкций у процессора ровно @ipt за тик, и этот запас он тратит на себя — чужие процессоры от вашей спешки не страдают. Платят другим:

  • Строками ниже. Пока программа крутит первый цикл, до остального она не доходит. Тесный цикл без wait — это не «быстро», а «только это и ничего больше».
  • Читаемостью. Программа, которая делает всё каждый тик, не имеет формы: в ней нельзя сказать, что и когда происходит.
  • Дисплеем. Рисовать чаще, чем обновляется кадр, бессмысленно: буфер всё равно сбросится один раз.

Иногда ждать нельзя — например, программа должна и следить за складом, и вести юнита. Тогда медленную часть отмеряют временем: у процессора есть @time — игровое время в миллисекундах, — и программа держит в переменной срок, раньше которого за медленную часть не берётся.

тик 0
Операция0
=
Прыжок -> 01
если
Операция2
=
Информация3
=
у
Операция4
=
@counter0number
итерацийnullnull
срокnullnull
медьnullnull
проверокnullnull

Нажмите «пуск» и посмотрите на две переменные: итераций бежит десятками, а проверок прибавляется по единице в секунду. Читается программа так: «если время ещё не дошло до срока — начать итерацию заново»; когда дошло, назначается следующий срок на секунду вперёд и делается медленная часть.

За первую секунду итерация проходит под шестьдесят раз, а sensor срабатывает один.

wait отмеряет время по тикам игры, а тик — это 1/60 секунды при нормальной скорости. Когда игра тормозит или ускорена, тики идут иначе, и wait 1 окажется не ровно секундой по часам. Для логики это обычно неважно: программа живёт во времени игры, а не в вашем.

Рассчитывать на wait как на точный таймер не стоит ещё и потому, что ожидание начинается с момента выполнения строки, а не с конца предыдущей итерации: время работы программы прибавляется к паузе.

Неофициальный проект, с Anuke не связан. Спрайты, шрифты и переводы Mindustry © Anuke, используются по GPL-3.0; Fira Code — по OFL-1.1. Код сайта — GPL-3.0.