Книга: Игровой баланс. Точная наука геймдизайна (Электронная)
Назад: 33. Организационное форматирование
Дальше: 35. Итеративные вычисления

34. Функции даты и времени

Одна из тех вещей, которые мы еще не успели рассмотреть, — форматирование дат. Хотя дни и даты почти не используются при выполнении задач, связанных с игровым балансом (исключение составляет разве что обработка получаемых с игрового сервера аналитических данных с временными метками), этот тип данных может быть очень полезен при организации рабочего времени и планировании графиков работ. В крупных игровых компаниях планированием графиков работ и бюджета обычно занимаются не геймдизайнеры, а продюсеры/менеджеры проектов, но в небольших фирмах (или когда есть необходимость в составлении личного плана работ) эту задачу может взять на себя и геймдизайнер. В электронных таблицах предусмотрен целый ряд функций для работы с датой и временем.

В частности, очень полезна функция TODAY(), которая не принимает параметров и выдает в качестве результата текущую дату обычно в формате даты мм/дд/гггг (при желании можете изменить способ представления даты путем форматирования ячеек точно так же, как это делается в случае числовых значений).

На первый взгляд функция TODAY() кажется не особенно нужной, ведь узнать текущую дату (а заодно и текущее время) можно, просто посмотрев в угол экрана компьютера, но вы сразу поймете, насколько она полезна, когда увидите, что в сочетании с ней операции сложения и вычитания работают именно так, как должны работать с датами (например, операция вычитания дает в результате разницу между двумя датами в виде количества дней). Это позволяет вам вычислить количество дней, остающихся до предельной даты завершения работ, путем вычитания из нее функции TODAY() или получить будущую дату, до которой остается еще несколько дней, добавив к функции TODAY() это количество дней (например, формула =TODAY()+7 выдаст дату, до которой остается неделя). Вы также можете использовать эту функцию в операциях сравнения. Так, формула =IF(G7<TODAY(), "ПРОСРОЧЕНО","") выдаст строку ПРОСРОЧЕНО, если ячейка G7 содержит прошедшую дату, и пустую строку в противном случае.

Распределяя задачи по неделям, можно использовать функцию WEEKNUM(), которая принимает один параметр, представляющий собой дату, и выдает в качестве результата номер текущей недели в пределах года (в диапазоне от 1 до 53, поскольку год на один-два дня длиннее 52 недель, его последние дни приходятся на 53-ю неделю). Если функция WEEKNUM() выдает для двух дат одинаковый результат, значит, эти две даты входят в одну и ту же неделю — по крайней мере при условии, что они относятся к одному и тому же году. Узнать, к какому году относится дата, можно с помощью функции YEAR(), которая принимает в качестве параметра дату и выдает год в виде целого числа.

Если вы распределяете задачи по месяцам, используйте функцию MONTH(), которая работает так же, как функция WEEKNUM(), но в отличие от нее возвращает число в диапазоне от 1 (что соответствует январю) до 12 (что соответствует декабрю). Если вам нужно подсчитать, какое количество задач должно быть выполнено в текущем месяце, то с помощью функции MONTH() определите в отдельном столбце, в каждой строке, на какой месяц приходится дата завершения работ, а затем с помощью функции COUNTIF() подсчитайте, сколько ячеек в этом столбце содержат такое же значение, какое выдает вызов функции MONTH(TODAY().

В редакторе Google Sheets дата может включать в себя не только день/месяц/год, но и время суток — в нем нет отдельного формата времени, поскольку время считается здесь составной частью даты. Чтобы получить и текущую дату, и текущее время, используйте функцию NOW(), которая работает так же, как функция TODAY(), но в отличие от нее наряду с датой выдает текущие час, минуту и секунду. Для выделения из этого значения отдельных составляющих времени можно применять функции HOUR(), MINUTE() и SECOND(), которые принимают в качестве параметра значение даты/времени и возвращают номер часа (от 0 до 23), минуты (от 0 до 59) и секунды (от 0 до 59) соответственно. Обратите внимание на то, что, как и функции RAND() и RANDBETWEEN(), функции TODAY() и NOW() обновляют свой результат только при изменении данных на листе или активации принудительного пересчета с помощью сочетания клавиш Ctrl+R. Выбрав в меню File (Файл) пункт Spreadsheet Settings (Настройки таблицы), можно настроить конкретную таблицу так, чтобы она автоматически пересчитывала результаты с интервалом в одну минуту или в один час. (Однако нельзя задать интервал 1 секунда или дать указание не выполнять пересчет даже при изменении ячеек, и чтобы реализовать это, придется искать обходные пути.)

Вы также можете использовать функцию TIMEVALUE(), которая принимает в качестве параметра значение даты/времени и возвращает дробное число от 0 до 1, указыва­ющее, какая часть текущего дня уже прошла (где 0 соответствует полночи, а 1 — 23 часам 59 минутам). Умножив эту дробь на количество секунд в сутках, которое составляет 24 × 60 × 60 = 86 400, вы можете получить количество прошедших секунд. Если нужно произвести арифметические действия со временем суток, вычислить разность между двумя значениями времени или добавить к значению времени определенное количество секунд, используйте функцию TIMEVALUE(). Если вы попытаетесь применить для этой цели функцию, возвращающую значение даты/времени, например NOW(), то целые числа будут интерпретироваться как дни, а не как время суток. Но можно сделать это и с помощью данной функции, если добавлять или отнимать дробное значение, представляющее некоторую часть суток. Например, формула =NOW()+0.25 дает в результате текущее значение даты и времени, увеличенное на 6 часов.

При составлении графиков работ и списков задач часто требуется помечать готовые задачи, чтобы можно было с течением времени отслеживать их выполнение или выделять те, которые не удалось закончить в срок. Некоторые редакторы электронных таблиц позволяют разместить в ячейке флажок, но редактор Google Sheets такой возможности не предоставляет (по крайней мере напрямую). Простейшая альтернатива состоит в том, чтобы попросить пользователя помечать задачу как выполненную, вводя в ячейку символ x или *, а затем подсчитать количество выполненных или невыполненных задач. Мы уже говорили о функции COUNTIF(), которая позволяет определить, сколько ячеек в обозначенном диапазоне содержит указанное значение, но в данном случае, вероятно, будет проще подсчитать количество пустых или непустых ячеек, чтобы можно было использовать какой угодно символ и не беспокоиться, например, о разнице между символами x и X. Это можно сделать с помощью функций COUNTBLANK() и COUNTA(), которые принимают в качестве параметра ячейку или диапазон ячеек. Функция COUNTBLANK() возвращает количество содержащихся в указанном диапазоне пустых ячеек, а функция COUNTA() — количество непустых. Существует также функция ISBLANK(), которая принимает в качестве параметра одну ячейку и возвращает значение TRUE, если она пуста, и значение FALSE, если что-то содержит. Эту функцию удобно применять в качестве условия в функции IF().

Побочные квесты

Побочный квест 34.1

Чтобы попрактиковаться в применении функций для работы с графиками событий, создайте электронную таблицу со списком ваших текущих задач и вводимыми вручную предельными датами завершения каждой из них. Включите в эту таблицу столбец, позволяющий каким-либо образом пометить задачу как выполненную.

Таблица должна подсчитывать количество дней, оставшихся до выполнения задания: пусть соответствующее поле будет пустым, если оно уже выполнено, содержит слово ПРОСРОЧЕНО, если еще не выполнено и предельная дата его завершения уже прошла, и содержит количество остающихся дней, если задание не выполнено и предельная дата его завершения наступила сегодня или должна наступить в будущем. Также в верхней части таблицы, выше списка задач, создайте ячейки для отображения количества незавершенных и просроченных задач.

Побочный квест 34.2

Чтобы попрактиковаться в применении описанных в этой главе возможностей, создайте на основе электронной таблицы реализацию простейшей игры-кликера, в которой игрок начинает с нулевого количества очков опыта и 1-го уровня и набирает очки опыта со скоростью 1 очко в секунду. Создайте отдельную ячейку для текущих значений времени и даты, получаемых с помощью функции NOW(), и еще одну ячейку для времени и даты создания персонажа (сделайте ее входным полем, которое можно будет заполнить начальными данными путем копирования и вставки формулы =NOW() в режиме копирования только значений ячеек). Создайте треугольную кривую уровня, в которой некоторое количество очков опыта будет соответствовать переходу на 2-й уровень и все большее количество очков опыта — переходу на каждый следующий уровень. В еще четырех ячейках должны отображаться:

• текущий уровень;

• текущее количество очков опыта;

• количество очков опыта, необходимое для перехода на следующий уровень;

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

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

Более сложная задача. Создайте в электронной таблице кнопки, позволяющие щелчком кнопкой мыши добавить 1 очко опыта (при этом общее количество очков опыта должно включать в себя и очки, добавляемые с помощью кнопок, и очки, получаемые с течением времени). Хотя почти все редакторы электронных таблиц предлагают определенные способы добавления кнопок и наделения их функциональностью с помощью скриптов, как и в случае построения графиков внутри ячеек, в разных редакторах это делается по-разному. В Google Sheets сначала нужно выбрать в меню Insert (Вставка) команду Drawing (Рисунок) и создать изображение кнопки. Затем щелкнуть на созданном изображении и перетащить его в нужное место внутри электронной таблицы, после чего, выбрав в меню Tools (Инструменты) пункт Script Editor (Редактор сценариев), создать скрипт, увеличивающий на единицу значение нужной ячейки. Это довольно сложные и насыщенные техническими подробностями возможности, рассмотрение которых выходит за рамки данной книги, но при желании вы легко найдете их описание в документации редактора электронных таблиц.

Задача-максимум. Реализуйте полноценную игру-кликер, в которой игрок может приобретать за очки опыта определенные средства повышения мощности и таким образом повышать скорость получения очков опыта. Не позволяйте игроку тратить настолько много очков опыта, чтобы его приходилось возвращать на более низкий уровень, и предоставляйте ему определенный бонус за достижение каждого следующего уровня, например увеличивающий количество очков опыта, получаемых с помощью каждого щелчка кнопкой мыши. Возможно, для этого нужно будет создать несколько кнопок с разными скриптами.

Назад: 33. Организационное форматирование
Дальше: 35. Итеративные вычисления