Doom в excel как запустить

Обновлено: 04.07.2024

Скучная офисная программа не только изменила работу финансистов, но и стала универсальной творческой средой.

Excel и Google Таблицы — набор «бухгалтерских» программ, которые превращаются в творческий инструмент в умелых руках.

Энтузиасты отмечают День Таблиц 17 октября — в этот день в 1979 году появилась VisiСalc, первая программа для таблиц. Она стала буквально революционной для финансистов и бухгалтеров и способствовала успеху Apple, потому что писалась именно под новый персональный компьютер Apple II.

Первая версия Excel вышла в 1985 году для Macintosh, а спустя два года вышла на Windows. Формально, «рисовать» в Excel можно было с самой первой версии, однако первые официальные инструменты — в том числе графики — внедрили в 1990 году. Спустя несколько лет Excel дал возможность самостоятельно расширять функционал программы на встроенном языке Visual Basic for Applications (VBA).

Несмотря на сугубо «офисную» ипостась Excel, сами разработчики вдохновляли смотреть на свой продукт иначе. В 1995 году в Excel включили «пасхалку» — 3D-комнату со списком имён разработчиков под названием Hall of Tortured Souls («Зал Измученных Душ»). В последующих версиях появились скрытые симулятор полётов и автогонки.

Вокруг Excel и Google Таблиц выросла своя творческая культура — рисование, создание анимаций, игр и даже музыки. TJ рассказывает про одни из самых примечательных творений, созданных в ячейках.

Excel изобразительный: «азарт борьбы с неудобным инструментом»

Excel буквально создан для пиксель-арта — даже не имея навыков рисования можно легко собрать буквы или человека из закрашенных блоков-кирпичиков. Но художники пошли дальше и использовали инструменты контура, встроенных фигур, математических формул и VBA.

81-летний японец Тацуо Хориучи (Tatsuo Horiuchi) создаёт картины в Excel на протяжении двадцати лет. Всё началось перед выходом на пенсию в 2000 году — он решил не тратиться на холсты, кисти или софт, а освоил Excel-инструмент Autoshape. Хориучи не ожидал быстрых результатов, поэтому написал 10-летний план прогресса. Цель — нарисовать картину, которую не стыдно было бы показать людям.

Первые три года он учился рисовать отдельные предметы, чаще тренируясь на овощах. Последующие три года ушло на то, чтобы собирать всё в единую композицию. В 2006 году Хориучи выиграл конкурс картин Excel Autoshape Art Contest. А спустя несколько лет он стал обучать студентов и выставляться в музее искусства Gunma. Несмотря на славу и звание «Excel-Микеланджело», художник утверждает, что его картины трудно продать.

«Создание картин в Excel — это очень скучное занятие, но я продолжаю на азарте борьбы с неудобным инструментом», — рассказал TJ украинский художник Алексей Сай. На одну картину уходит от недели до месяца. Алексей начал делать работы в 2004 году — и через 3 года накопилось на выставку.

Монотонность создания Excel-картин отражает саму суть работы в Excel — долгую и скрупулёзную. Это способ отразить реальность офисной работы и растущий объём информации. «Я использовал элементы визуального языка, который будет понятен человеку корпоративной культуры — самой молодой из сформировавшихся человеческих культур», — описывает Алексей одну из своих работ.

Две дамы смотрели на работу с цветами и сказали: «кошмар». Я этого и добивался. Это был самый адекватный отзыв. Чаще всего картины в Excel кажутся людям грустным искусством — это так и есть.

В 2018 году прошла вторая выставка Алексея «Что я здесь делаю?». Его Excel-работы существуют в единственном варианте и продаются по цене от 2 до 6 тысяч долларов. Ньюйоркская художница Даниэль Уберт (Danielle Aubert) тоже зарабатывала на Excel-картинах. Даниэль на протяжении 16 месяцев рисовала в таблицах, а после собрала полуабстрактные картины в бумажную книгу, издавая её на протяжении трёх лет до 2008 года.

Искусство привлекло внимание брендов — Microsoft пишет о картинах в своём блоге, а Google в 2016 году организовал коллаборацию двух иллюстраторов для создания картины в Google Таблицах. Результат перенесли на стену дома в Бруклине в качестве рекламной кампании.

Марина Эсмеральдо и Меллори Хейер на фоне их совместной картины, созданной в Google Таблицах Блог Марии Эсмеральдо

У известного художника Филипе Веласкеса (Felipe Velasquez) ушло 13 часов, чтобы нарисовать трансформера и три часа на Мастера Йоду. Те же картины можно получить через генераторы таблиц — уже минимум десять лет доступны утилиты, плагины и онлайн-сервисы, переводящие любое изображение в ячейки.

Ещё один способ «рисовать» в таблицах — написать сложную математическую формулу, которая образует график. Дата-аналитику Девану Мэтью (Devan Matthews) пришлось около четырёх лет экспериментировать в программе, пока не решил наконец распечатать свои абстрактные работы. В 2016 году его фракталами восхитился Microsoft.

Одну из первых картин — что-то вроде кругов спирографом — Мэтью получил с помощью формулы Z=1.618^(abs(X)). Рисунки ниже потребовали более серьёзных вычислений:

Excel позволяет рисовать и псевдообъёмные картины. А российский иллюстратор Алексей Шелковников утверждает, что создание 3D-изображений в таблицах — «экономия времени, сил и нервов». Это знакомая многим программа, а поэтому привычный интерфейс помогает разобраться. В доказательство Алексей показывает изображения, полностью сделанные в Excel без посторонней обработки:

Ускоренное видео создания этой работы из серии Gadgefication Алексей Шелковников

Шелковников также провёл эксперимент по созданию одного и того же изображения в Excel и в Cinema 4D. Обе иллюстрации заняли около 12 часов, но в случае Cinema 4D ушло немного больше времени.

Сравнение финальных версий, нарисованных в Excel и в Cinema 4D Алексей Шелковников

Трассировка лучей — это трёхмерная графика, изображающая свет на предметах. То, как лучи света падают, отражаются, преломляются и дают тень. Рассчитать все детали — трудная задача даже в специализированных программах. Но YouTube-блогер s0lly сделал это в Excel с анимацией шаров в 2019 году, а через два года превзошёл себя и улучшил первую версию. На gif-картинке внизу — вариант анимации 2021 года.

Отрывок из видео с 3D-анимацией, показывающая игру света и тени в Excel YouTube-канал s0lly

Основной способ создания анимаций и Excel-игр — макросы и язык программирования Visual Basic for Applications (VBA). Макрос — это встроенная функция Excel, которая по команде воспроизводит записанные пользователем действия. Например, выделяет все отрицательные суммы красным. VBA — язык, на котором пишутся макросы и более сложные алгоритмы внутри Excel.

Анимация шаров состоит из ряда формул, макрос отвечает за круговое движение. Версия на видео ускорена — в реальной жизни каждый кадр занимает около 2 секунд на процессинг даже на относительно мощном компьютере.

Отрывок из видео про анимацию американских горок в Excel. В начале показан объём расчётов, который позволяет осуществить движение YouTube-канал EngineeringFun

Музыкальный клип Joe Penna — не анимация, а набор кадров, каждый из которых он создавал вручную. На минутное видео ушло примерно 730 пиксельных автопортретов. Пожалуй, это самый весёлый видеоклип, созданный в таблицах.

Отрывок из стоп-моушен клипа Joe Penna на песню Cuban Pete

YouTube-пользователь Alex C создал аналогичную стоп-моушен анимацию с реалистичной фигурой ребёнка, играющего в кубики. Но в его случае все движения программировались в VBA.

Игры в Excel — это целый отдельный жанр, в котором есть тысячи игр: от простого ячеечного тетриса и аркад до многоуровневых стратегий. Некоторые популярные игры обрели своих Excel-близнецов: Змейка, 2048, Скрэббл, Цивилизация, Minecraft, прототип легендарной Legend of Zelda под названием Excelda и другие.

Одна из самых известных игр на Excel появилась в 2013 году — Arena.Xlsm сделана в жанре RPG: больше 2000 видов врагов, 1131 магический предмет и 100 достижений. Её создал канадский бухгалтер Кэри Уолкин (Cary Walkin) во время учёбы на MBA. Практика с продвинутыми инструментами в Excel натолкнула его на мысль, что с этим можно создать полноценную игру. На финальную версию ушло пять месяцев.

Игра Arena.Xlsm моментально завирусилась: спустя пару недель её скачали более 250 тысяч раз, про неё написали десятки медиа, включая «Би-би-си» и Gizmodo.

Пользователь играет от лица бунтаря, чьё восстание против Императора провалилось и теперь он должен сражаться на арене против чудищ, чтобы выжить. Союзники извне присылают письма — сквозь них раскрываются другие персонажи, появляются инструкции и подсказки. У игры четыре концовки.

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

Стратегия не требует знания Excel — достаточно лишь скачать версию Excel 2007, 2010 или 2013 для Windows и включить макросы. Игра не совместима с Google Таблицами и MacOS.

По словам Уолкина, после выпуска Arena.Xlsm множество людей захотело выпускать собственные игры. Поэтому он выпустил курс с пошаговыми инструкциями по созданию игровых механик в Excel. А затем и инвестиционную Excel-игру Candy Number Crunch Saga с открытым исходным кодом, чтобы пользователи могли его исследовать и создавать свои собственные игры.

Основная активность вокруг Arena.Xlsm угасла около семи лет назад. Её создатель рассказал TJ, что сделал улучшенную версию игры для платформы Steam, но из-за проблемы с правами на дистрибуцию Excel игра так и не вышла.

В какой-то момент Кэри Уолкину пришлось выбрать приоритет: он работал в IT-компании, делал игры, консультировал других разработчиков и преподавал в университете по вечерам. Нагрузка была слишком высокая, и в итоге он покинул игровую индустрию и теперь работает в сфере SaaS.

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

В рамках курса по созданию Excel-игр Уолкина другой разработчик Джордан Голдмайер (Jordan Goldmeier) написал 3D-лабиринт для Excel:

Делать сложные игры можно и без кода: в 2018 году блогер C Bel создал игровой 3D-движок, используя только формулы. Этот движок годится для шутеров от первого лица типа Doom и даёт похожий визуал: с поворотом вида, перемещением в пространстве, изменением освещения и столкновением со стенами.

Первый полноценный 3D-шутер в Excel появился тоже в 2018 году — его создал украинец Александр Шумаков вместе с сыном. По сюжету игры под названием Dave vs Ziggy главный герой сражается с инопланетянами на корабле. У него есть пять типов оружия: винтовой ключ, дробовик, квадроган, взрывчатка и плазменная пушка. Можно убивать не только монстров, но и частично разрушать пространство и по пути сыграть во внутреннюю мини-игру «Понг».

Начальная версия игры с двумя уровнями заняла два года работы. Оставшиеся пять уровней вышли в 2019 году. Стало больше локаций, вариантов действий, игра усложнилась и сюжетно, и графически. В последствии шутер больше не обновляли, судя по блогу разработчика.

Dave vs Ziggy полностью написана на макросах Excel и включает стандартную палитру из 56 цветов. Музыку к игре тоже писал сам Шумаков.

Отрывок из геймплея первого уровня Excel-шутера Dave vs Ziggy YouTube-канал Александр Шумаков

В 2019 году Excel стал драм-машиной — YouTube-блогер Дилан Толлчиф (Dylan Tallchief) настроил таблицу таким образом, чтобы воспроизводить отмеченный ритм. Сама таблица не воспроизводит звук — она отсылает сигнал к встроенному программному синтезатору Microsoft GS Wavetable Synth. На Mac воспроизвести этот файл не получится. Но вместо этого плагина можно подключить другой девайс.

Спустя четыре месяца Дилан выпустил ремейк «Take On Me» группы a-ha на Excel. Его табличная драм-машина получила серьёзную прибавку функций, став программой для создания музыки. Кроме ударных появились и другие инструменты и ряд настроек звука. Конечно, этот проект не заменит настоящий музыкальный софт: например, нельзя подключать плагины.

Проигрывание музыки через Excel — давно известная возможность программы. В 2015 году YouTube-блогер DJ Oamen показал, как создать и сыграть на мини-пианино в Excel, другие объясняли, как таблица проигрывает звук в зависимости от числового значения или как открыть медиаплеер внутри таблицы.

Несмотря на сотни арт-работ и игр, Excel как программа для искусства остаётся популярным только среди узкой группы людей, периодически вирусясь в интернете. Иногда это творчество выходит не только в офлайн-выставки: например, в Японии проводятся мастер-классы по рисованию Excel-картин в традиционном стиле. А 82-летняя программистка Масако Вакамия (Masako Wakamiya) нарисовала обложку для своей книги в Excel и печатает вееры и пакеты с узорами, созданными в таблицах. На встречу с императором Японии она пришла в одежде с Excel-принтами.

Excel пытались сделать «мессенджером»: в клипе Dilemma 2002 года певица Келли Роланд (Kelly Rowland) якобы переписывалась в Excel, напечатав вопрос в ячейке, и даже рассердилась, когда ей не ответили. Вскоре момент попал в мемы. Спустя 17 лет после съёмок Роланд призналась, что до сих не знает, что это за программа. И слава Богу, потому что когда Excel станет ещё и чатом, всё остальное придётся удалять.

Статья создана участницей Лиги авторов. О том, как она работает и как туда вступить, рассказано в этом материале.

Мастера сложных таблиц и создатели креативных презентаций могут не подозревать, что кто-то использует программы Microsoft Office не по прямому назначению. Тем временем, умельцы превращают таблицы в драм-машину и стол для пинг-понга, а простые слайды — в 3D-мультфильмы.

Из Microsoft Excel можно сделать MIDI-контроллер, который будет запускать звуки в нужной последовательности. Так сделал YouTube-блогер Дилан Толлчиф, который привязал инструменты к разным ячейкам и отметил в них последовательность звуков.

Excel подаёт внешнему редактору сигналы, какую ноту нужно озвучить. Сначала у блогера получилось что-то вроде драм-машины. Но во второй, улучшенной версии таблицы он записал полноценный кавер на песню «Take On Me» группы a-ha. Можно попробовать повторить его эксперимент со своей любимой песней.

Что вам понадобится:

Таблица, в которой у каждого инструмента будет своя строчка, а в столбиках — очерёдность нот в мелодии;

Другой пользователь Excel написал программное обеспечение для трёхмерной игры по мотивам шутера Doom. Для этого ему понадобилась только таблица с математическими формулами.

Да, в программе, где вы, возможно, ведёте статистический учёт, кто-то бродит по лабиринту и атакует лазером красных призраков. Можете попробовать так же.

Что вам понадобится:

  • Встроенный язык программирования VBA, но можно обойтись и без него;
  • Хорошо прокачанный навык работы с формулами;
  • Но быстрее и проще будет обойтись аналогом Doom, который уже написал информатик и специалист по Excel.

Можно попробовать написать в Excel нейронную сеть. Пускай простую и небольшую. Такая нейросеть сможет, например, различать в таблице вертикальные и горизонтальные линии или цвета.

Что вам понадобится:

  • Подать на вход матрицу;
  • Определиться со структурой, которая позволит нейросети обучаться;
  • Написать макросы, которые будут автоматически размножать объекты;
  • Обучить нейросеть, руководствуясь эффективным примером.

Ещё одна игра, доступная знатокам таблиц и формул — пинг-понг. По современным меркам он будет выглядеть примитивно, но главное — есть стол, две платформы-ракетки и мячик.

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

Что вам понадобится:

  • Макросы VBA и точечная диаграмма в таблице;
  • Формулы, задающие значение для всего — от параметров игрового стола до кнопки запуска игры;
  • Знание технических деталей, которые подробно прописаны в инструкции.

Игра «Жизнь» — клеточный автомат, придуманный ещё в 1970-е. Сегодня его можно воссоздать в файле Excel. Таблица станет игровым пространством — «вселенной», а её клетки вы поделите на «мёртвые» и «живые».

После запуска игры остаётся лишь наблюдать, как в зависимости от выбранной вами конфигурации будет развиваться жизнь во «вселенной» вашего файла.

Что вам понадобится:

  • Три листа в Excel — для наблюдения за игрой, формирования следующего «поколения» и начального распределения клеток;
  • VBA — встроенный в Microsoft Office язык программирования;
  • Или файл с уже написанной игрой.

В PowerPoint можно создать небольшой мультфильм. В этом поможет анимация 3D-объектов, которую Microsoft добавил в приложение в 2019 году.

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

Что вам понадобится:

Установленный Microsoft Office 365;

Опробовать эти и многие другие возможности пакета Microsoft Office можно на современном ноутбуке ASUS с предустановленной Windows 10, SSD и мощным процессором AMD Ryzen. При его покупке до 30 апреля 2020 года в «Ситилинк» годовую подписку на Office 365 персональный можно получить в подарок.

Зарегистрировав покупку ноутбука ASUS и приняв участие в розыгрыше пяти авиабилетов на двоих, вы сможете на практике проверить, на сколько нестандартных задач хватит его батареи.


Эта статья посвящена тому, как я смог написать 3D-движок только на формулах Excel. Я реализовал следующий функционал:

  • бесконечная процедурно генерируемая карта лабиринта
  • рендеринг трассировкой лучей в реальном времени
  • вычисление окклюзии
  • рендеринг простейшего освещения
  • шейдер освещения и вычислений
  • движок естественного движения
  • в 3D-движке не используются макросы

Можете скачать файл и протестировать его самостоятельно!

Файлы

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

Поначалу, какой бы мудрой ни казалась эта фраза, упоминание в этом списке Excel выглядело глупо…

Затем, после изучения машины Тьюринга, фраза стала для нас полностью верной, хотя и не вполне реализуемой.

Получив многолетний опыт работы с Excel, мы уже поняли, что единственное ограничение формулы Excel — недостаток способов ввода-вывода.

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

Как бы то ни было, эта работа — не просто какое-то хвастовство… У меня были для неё серьёзные причины.

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

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

А начав изучать его, они пытаются использовать его для решения любых видов задач, даже для простого поиска или визуализации.

Сегодня я преподаю Excel, поэтому постараюсь объяснить людям, почему написание макроса на VBA для решения любой задачи без хорошего знания программирования — это не только пустая трата времени, но и серьёзный риск снижения качества электронной таблицы.

При использовании в бизнесе формулы обладают следующими преимуществами перед макросами:

  • Их быстрее писать для любого человека, если он не профессиональный программист-аналитик
  • Их проще поддерживать любому человеку, а не только профессиональному программисту. (Чаще всего макросы становятся бесполезны после ухода их разработчика.)
  • Гарантированное качество благодаря постоянной проверке значений. (Принудительное применение техники «разработка через тестирование»)
  • Они более эффективны в долговременной перспективе благодаря процессу создания формул в стиле «думай, прежде чем писать».
  • И они совершенно точно гораздо лучше интегрированы в сам инструмент создания электронных таблиц и следуют изначальному паттерну разработки электронных таблиц, в то время как макросы часто оказываются специфическими конструкциями, требующими в дальнейшем активной поддержки.

Вот так я пришёл к написанию своей игры: она стала наглядной демонстрацией того, что макросы обычно не нужны даже для решения самых сложных задач.

Если конкретнее, то я нашёл всего два случая, когда потребовался VBA:

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

Моя электронная таблица должна была стать игрой в стиле Doom в лабиринте.

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

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

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

Начальные состояния генератора случайных чисел должны быть позициями (x;y) на карте, чтобы мы могли получать разные значения для каждой позиции, и мы не можем получить результат предыдущего случайного числа как начальное состояние для следующего, или нам придётся хранить всю карту с самого начала.

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

Эксперименты с фрактальным генератором тоже оказались довольно затратными и давали интересные результаты только для небольшой части карты.

Тогда я обнаружил метод средних квадратов (middle-square method), который на самом деле не очень «случаен», потому что в нём используются последовательные начальные состояния. Но он подсказал мне идею того, что можно брать десятичную часть любого другого вычисления.

Я выяснил, что если брать десятичные части sin(x)+cos(y), то наконец-то получаются красивые числа без какого-либо прослеживаемого паттерна, а время вычислений при этом на удивление малО.

Для получения десятичных частей математические функции mod() и floor() гораздо более эффективны по сравнению с текстовой функцией подстроки mid().

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

То есть нам нужны тонкие стены с двумя возможными стенами для каждого квадрата. Тогда мы сможем брать два блока чисел вместе с тем же случайным значением.

Плотностью размещения стен управляют два параметра.

С учётом этих правил мы можем или отображать лабиринт, или тестировать любую стену с заданной позицией с помощью трассировки лучей.

Стоит заметить, что карта «плоская», без подъёмов и спусков. Можно было добавить рельеф с помощью генератора рельефа (подошёл бы алгоритм Diamond-Square, потому что его можно написать без рекурсивной функции), но весь последующий процесс сильно облегчило бы вырезание отверстий в полу и потолке с дополнительным значением уровня.


Так, похоже, мы в аду

Трассировщик лучей должен определять для каждого пикселя экрана, какой первой поверхности касается луч, и получать от неё информацию (расстояние, угол падения света, цвет и т.д.).

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

Окклюзия

Первым сложным моментом будет нахождение первого объекта на пути каждого луча.

Поскольку лабиринт на самом деле плоский с горизонтальными стенами, то ближайшая найденная стена будет одинаковой для всех пикселей одного столбца.

То есть процесс можно упростить до горизонтального «радара» в одном измерении.

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

Определение того, какую стену нужно проверять — это всего лишь тригонометрическая задача.

И поскольку у нас всего два типа стен, мы можем тестировать оба типа, а потом сохранять только ближайшую.

Одно из ограничений Excel заключается в отсутствии условного цикла и для экономии времени можно только пропускать тело цикла. Поэтому нам нужно ограничить максимальное расстояние проверки, считая, что если на этом расстоянии стена не найдена, то её нет.

Пол и потолок

Чтобы определить потолок и пол, нам достаточно определить, где заканчивается стена.

Отдельный лист изменяет расстояние до пола или потолка в зависимости от вертикального угла.

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

Эффективное сравнение реализовано использованием только проекции расстояния до стены и до пола/потолка по оси камеры. Конечное расстояние затем получается с помощью предварительно вычисленного коэффициента расстояния в шейдере расстояний. Постоянные предварительно вычисленные значения нужны для экономии ресурсов.

Освещение

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

Когда поверхность точно горизонтальна к лучу света, также добавляется отражение.

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

Для каждого угла радара мы получаем угол между лучом и ближайшей найденной стеной.

Коэффициент отражения — это просто функция угла.

В конце концов освещение становится результатом функции коэффициента расстояния, потолка/пола или разрешения стен, коэффициента отражения и коэффициента шейдера освещения.

Экран дисплея

Эффективный дисплей реализуется с помощью условного форматирования — градиент цвета зависит от значения ячейки.

Сокрытие значения выполняется форматированием ячейки.

Игрок не должен проходить сквозь стены, иначе это разрушит весь смысл лабиринта.

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

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

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

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

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


Привет, красное привидение!

Графический рендеринг

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

Целый отдельный лист посвящён вычислению формы сфер с учётом горизонтального радиуса и вертикальной высоты овоида. Для анимирования существа используется соотношение высоты/ширины.

В рендеринге стен и потолка используется градиент только по одному цвету, однако Excel позволяет использовать два последовательных (не сливающихся) градиента. Поэтому врагов можно отображать другим цветом. Для этого градиента можно использовать диапазон значений ниже 0, при том, что значение 0 — это чёрный цвет.

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

На границе сферы низкая толщина сохраняет только значение цвета по умолчанию стены за ней с отрицательным коэффициентом для превращения его в цвет монстра. Фильтр цвета освещения обеспечивает прозрачность на границе сферы.

Здесь вычисления тоже производятся в горизонтальной плоскости, а максимальный объём вычислений подготавливается перед завершением 3D-вычислений для каждого пикселя.

Поведение врагов

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

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

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

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

Можно уменьшать/увеличивать сетку повторов, чтобы повышать/снижать плотность расположения врагов. При этом следует внимательно следить за конечным смещением монстра, чтобы оно не было чрезмерным, и за скоростью, изменяющейся при масштабировании.

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

Атаки врагов

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

Область видимости каждого монстра вычисляется на вкладке радара с учётом расположения стен.

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

Это создаёт эффект наносимого игроку урона — простой эффект негативного цвета во весь экран.

Добавлен также ещё один эффект — отмена рендеринга всех остальных врагов при нанесении урона игроку.

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

Атаки игрока

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

Эта упрощённая модель позволяет игроку предотвратить атаку врага, снизив его жизнь до нуля.

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

При убийстве враг просто переходит в состояние бездействия и медленной регенерации. Так как по всей карте повторяется несколько врагов, ни одного из них нельзя уничтожать полностью.

Смерть и перезапуск

Когда жизнь игрока снижается до нуля, бОльшая часть его действий приостанавливается и появляется экран конца игры.

Этот экран рендерится с помощью ещё одного шейдера освещения. К цвету применён эффект негатива, чтобы подчеркнуть нанесение урона.

Очки должны отрисовываться с помощью пикселей шрифтом очень низкого разрешения.

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


Эта статья посвящена тому, как я смог написать 3D-движок только на формулах Excel. Я реализовал следующий функционал:

  • бесконечная процедурно генерируемая карта лабиринта
  • рендеринг трассировкой лучей в реальном времени
  • вычисление окклюзии
  • рендеринг простейшего освещения
  • шейдер освещения и вычислений
  • движок естественного движения
  • в 3D-движке не используются макросы

Можете скачать файл и протестировать его самостоятельно!

Файлы

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

Поначалу, какой бы мудрой ни казалась эта фраза, упоминание в этом списке Excel выглядело глупо…

Затем, после изучения машины Тьюринга, фраза стала для нас полностью верной, хотя и не вполне реализуемой.

Получив многолетний опыт работы с Excel, мы уже поняли, что единственное ограничение формулы Excel — недостаток способов ввода-вывода.

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

Как бы то ни было, эта работа — не просто какое-то хвастовство… У меня были для неё серьёзные причины.

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

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

А начав изучать его, они пытаются использовать его для решения любых видов задач, даже для простого поиска или визуализации.

Сегодня я преподаю Excel, поэтому постараюсь объяснить людям, почему написание макроса на VBA для решения любой задачи без хорошего знания программирования — это не только пустая трата времени, но и серьёзный риск снижения качества электронной таблицы.

При использовании в бизнесе формулы обладают следующими преимуществами перед макросами:

  • Их быстрее писать для любого человека, если он не профессиональный программист-аналитик
  • Их проще поддерживать любому человеку, а не только профессиональному программисту. (Чаще всего макросы становятся бесполезны после ухода их разработчика.)
  • Гарантированное качество благодаря постоянной проверке значений. (Принудительное применение техники «разработка через тестирование»)
  • Они более эффективны в долговременной перспективе благодаря процессу создания формул в стиле «думай, прежде чем писать».
  • И они совершенно точно гораздо лучше интегрированы в сам инструмент создания электронных таблиц и следуют изначальному паттерну разработки электронных таблиц, в то время как макросы часто оказываются специфическими конструкциями, требующими в дальнейшем активной поддержки.

Вот так я пришёл к написанию своей игры: она стала наглядной демонстрацией того, что макросы обычно не нужны даже для решения самых сложных задач.

Если конкретнее, то я нашёл всего два случая, когда потребовался VBA:

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

Моя электронная таблица должна была стать игрой в стиле Doom в лабиринте.

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

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

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

Начальные состояния генератора случайных чисел должны быть позициями (x;y) на карте, чтобы мы могли получать разные значения для каждой позиции, и мы не можем получить результат предыдущего случайного числа как начальное состояние для следующего, или нам придётся хранить всю карту с самого начала.

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

Эксперименты с фрактальным генератором тоже оказались довольно затратными и давали интересные результаты только для небольшой части карты.

Тогда я обнаружил метод средних квадратов (middle-square method), который на самом деле не очень «случаен», потому что в нём используются последовательные начальные состояния. Но он подсказал мне идею того, что можно брать десятичную часть любого другого вычисления.

Я выяснил, что если брать десятичные части sin(x)+cos(y), то наконец-то получаются красивые числа без какого-либо прослеживаемого паттерна, а время вычислений при этом на удивление малО.

Для получения десятичных частей математические функции mod() и floor() гораздо более эффективны по сравнению с текстовой функцией подстроки mid().

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

То есть нам нужны тонкие стены с двумя возможными стенами для каждого квадрата. Тогда мы сможем брать два блока чисел вместе с тем же случайным значением.

Плотностью размещения стен управляют два параметра.

С учётом этих правил мы можем или отображать лабиринт, или тестировать любую стену с заданной позицией с помощью трассировки лучей.

Стоит заметить, что карта «плоская», без подъёмов и спусков. Можно было добавить рельеф с помощью генератора рельефа (подошёл бы алгоритм Diamond-Square, потому что его можно написать без рекурсивной функции), но весь последующий процесс сильно облегчило бы вырезание отверстий в полу и потолке с дополнительным значением уровня.


Так, похоже, мы в аду

Трассировщик лучей должен определять для каждого пикселя экрана, какой первой поверхности касается луч, и получать от неё информацию (расстояние, угол падения света, цвет и т.д.).

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

Окклюзия

Первым сложным моментом будет нахождение первого объекта на пути каждого луча.

Поскольку лабиринт на самом деле плоский с горизонтальными стенами, то ближайшая найденная стена будет одинаковой для всех пикселей одного столбца.

То есть процесс можно упростить до горизонтального «радара» в одном измерении.

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

Определение того, какую стену нужно проверять — это всего лишь тригонометрическая задача.

И поскольку у нас всего два типа стен, мы можем тестировать оба типа, а потом сохранять только ближайшую.

Одно из ограничений Excel заключается в отсутствии условного цикла и для экономии времени можно только пропускать тело цикла. Поэтому нам нужно ограничить максимальное расстояние проверки, считая, что если на этом расстоянии стена не найдена, то её нет.

Пол и потолок

Чтобы определить потолок и пол, нам достаточно определить, где заканчивается стена.

Отдельный лист изменяет расстояние до пола или потолка в зависимости от вертикального угла.

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

Эффективное сравнение реализовано использованием только проекции расстояния до стены и до пола/потолка по оси камеры. Конечное расстояние затем получается с помощью предварительно вычисленного коэффициента расстояния в шейдере расстояний. Постоянные предварительно вычисленные значения нужны для экономии ресурсов.

Освещение

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

Когда поверхность точно горизонтальна к лучу света, также добавляется отражение.

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

Для каждого угла радара мы получаем угол между лучом и ближайшей найденной стеной.

Коэффициент отражения — это просто функция угла.

В конце концов освещение становится результатом функции коэффициента расстояния, потолка/пола или разрешения стен, коэффициента отражения и коэффициента шейдера освещения.

Экран дисплея

Эффективный дисплей реализуется с помощью условного форматирования — градиент цвета зависит от значения ячейки.

Сокрытие значения выполняется форматированием ячейки.

Игрок не должен проходить сквозь стены, иначе это разрушит весь смысл лабиринта.

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

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

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

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

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


Привет, красное привидение!

Графический рендеринг

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

Целый отдельный лист посвящён вычислению формы сфер с учётом горизонтального радиуса и вертикальной высоты овоида. Для анимирования существа используется соотношение высоты/ширины.

В рендеринге стен и потолка используется градиент только по одному цвету, однако Excel позволяет использовать два последовательных (не сливающихся) градиента. Поэтому врагов можно отображать другим цветом. Для этого градиента можно использовать диапазон значений ниже 0, при том, что значение 0 — это чёрный цвет.

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

На границе сферы низкая толщина сохраняет только значение цвета по умолчанию стены за ней с отрицательным коэффициентом для превращения его в цвет монстра. Фильтр цвета освещения обеспечивает прозрачность на границе сферы.

Здесь вычисления тоже производятся в горизонтальной плоскости, а максимальный объём вычислений подготавливается перед завершением 3D-вычислений для каждого пикселя.

Поведение врагов

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

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

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

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

Можно уменьшать/увеличивать сетку повторов, чтобы повышать/снижать плотность расположения врагов. При этом следует внимательно следить за конечным смещением монстра, чтобы оно не было чрезмерным, и за скоростью, изменяющейся при масштабировании.

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

Атаки врагов

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

Область видимости каждого монстра вычисляется на вкладке радара с учётом расположения стен.

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

Это создаёт эффект наносимого игроку урона — простой эффект негативного цвета во весь экран.

Добавлен также ещё один эффект — отмена рендеринга всех остальных врагов при нанесении урона игроку.

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

Атаки игрока

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

Эта упрощённая модель позволяет игроку предотвратить атаку врага, снизив его жизнь до нуля.

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

При убийстве враг просто переходит в состояние бездействия и медленной регенерации. Так как по всей карте повторяется несколько врагов, ни одного из них нельзя уничтожать полностью.

Смерть и перезапуск

Когда жизнь игрока снижается до нуля, бОльшая часть его действий приостанавливается и появляется экран конца игры.

Этот экран рендерится с помощью ещё одного шейдера освещения. К цвету применён эффект негатива, чтобы подчеркнуть нанесение урона.

Очки должны отрисовываться с помощью пикселей шрифтом очень низкого разрешения.

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

Читайте также: