Dave vs ziggy excel скачать

Принято считать, что Microsoft Excel — это скучные таблицы и графики. Но это не совсем так. Разработчик Александр Шумаков и его сын Никита создали в ней полноценный трёхмерный шутер от первого лица.

Проект называется Dave vs Ziggy и рассказывает о секретной базе, которую захватили пришельцы. Вам же предстоит очистить её от врагов. В техническом плане игра написана на языке Visual Basic for Applications. Отмечается, что система позволила реализовать игровые механики, шейдеры, воксели, полигоны и так далее. Более того, в игре есть три слота для сохранения прогресса.

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

Сам проект начался в 2016 году, но сейчас дошёл до играбельного состояния. Для игры рекомендуется Office 2010, хотя, теоретически, хватит и 2003-й версии. Скачать необычный шутер можно здесь.

🕸 Вышел новый трейлер мультфильма «Человек-паук: Паутина вселенных»

  • Обзор Thunder Tier One. Кооперативный шутер от разработчиков PUBG, который шокирует вниманием к деталям
  • Российский шутер с открытым миром Pioner в духе S.T.A.L.K.E.R. готов на 50% и выйдет в 2022 году
  • «Пока, Rainbow Six Siege» и «То, чего я ждал после SWAT 4» — как геймеры в Steam оценили новый шутер Ready or Not

В прошлый раз я рассказал как малой кровью сделать подобие игры «3 в ряд» в рабочей книге Excel с использованием встроенного языка программирования Visual Basic for Applications (VBA).

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

С тех пор прошло почти три месяца, а Roguelike игра все еще находится в стадии «возможно когда-нибудь я к ней приступлю». Прости, храбрый воин, отстоявший честь жанра. Самурай тебя подвел. *Уходит делать сэппуку*.

На деле же за это время произошло много событий. Например, коллега заинтересовал меня программированием микроконтроллеров. Я поморгал встроенным светодиодом на WEMOS D1 Mini (на базе ESP8266), написал небольшую программу для подключения платы к домашнему WI‑FI, а потом задумался о перспективах этого направления.

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

Очевидно, в какой-то момент мне стало плохо от осознания своей беспомощности. Для человека, который вроде бы нормально знает VBA и плавает в CSharp (как написать название этого языка без проставления хэштэга?), попытка реализации игры на C/C++ смерти подобна.

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

Решение — притормозить с портативной консолью, сосредоточиться на алгоритмах игрового движка, а также использовать для этого более приятный в освоении язык!

Гениально, правда?

Примерно в это же время я нашел замечательный фреймворк Monogame для СSharp, написанный на базе XNA. Я не буду рассказывать о своей находке, потому что это уже сделали за меня.

ИТОГ РАЗ: проект консоли заморозить до лучших времён.

ИТОГ ДВА: игре быть (надеюсь, что в ближайшем будущем).

Наконец-то он перешел к делу

Что еще можно ожидать от человека, который занимается странными вещами и тестирует все самые безумные идеи в Excel?

Еще больше насилия над офисным инструментом и устаревшим языком программирования!

Так как игра изначально планировалась к реализации на базе маломощного процессора, то единственным очевидным решением было использовать ретро стиль, который не требует много ресурсов.

Какая игра портирована даже на осциллограф (Нет, это не Скайрим, отстань, Тодд) и не требует по современным меркам практически ничего?

Конечно, Doom (1993). Но графический движок Doom оказался для меня достаточно сложным в освоении, поэтому я обратил внимание на более старое творение id Software — Wolfenstein 3D.

Фактически, Wolfenstein 3D мог бы называться просто Wolfenstein. Приписка «3D» скорее всего появилась исключительно в коммерческих целях.

Графический движок Wolfenstein 3D представляет собой лишь проекцию 2D пространства, по которому перемещается главный герой. При этом пол и потолок располагаются на одном уровне, а стены всегда параллельны осям X и Y. Никакого разнообразия.

Вот так это выглядит (картинка нагло украдена с Вики):

Технология, которая позволяет добиться такого результата, называется Raycasting или «Бросание лучей».

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

​Схематически это выглядит так

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

В этом и заключается суть ядра графического движка Wolfenstein 3D.

А теперь немного извращений

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

Поле для вывода изображения

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

Сперва нужно определиться с размером «экрана». Я выбрал такие значения:

  • Высота — 64 ячейки.
  • Ширина — 96 ячеек.

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

Карта уровня

Карта уровня находится на соседнем листе:

Единички символизируют стены. «P» — это игрок.

Переменные и константы

Открываем встроенную IDE (как бы громко это ни звучало) и создаём модуль. Первым делом пишем следующий код:

Option Explicit
Option Base 0

‘Ширина и высота экрана, поле зрения, размер
‘одного блока
Const RENDER_H = 64
Const RENDER_W = 96
Const FOV = 75
Const cellHeight = 64
Const cellWidth = 64

‘Определяем переменные
Sub startRender()

Dim plX As Double, plY As Double, plPOV As Double, _
arrMap() As Variant, rngMap As Range, mapHeight As Long, mapWidth As Long, _
arrRender() As Variant

‘Определение размера карты
mapHeight = Sheets(«MAP»).Cells(Rows.Count, 1).End(xlUp).Row
mapWidth = Application.WorksheetFunction.CountA(Sheets(«MAP»).Rows(1))

‘Диапазон карты
Set rngMap = Sheets(«MAP»).Range(Sheets(«MAP»).Cells(1, 1), _
Sheets(«MAP»).Cells(mapHeight, mapWidth))

arrMap() = rngMap.Value

‘Расчёт положения игрока на карте
plX = GetPlayerCoord(arrMap(), «X»)
plY = GetPlayerCoord(arrMap(), «Y»)
‘То самое направление взгляда, изменение которого мне лень прописывать
plPOV = Application.WorksheetFunction.Radians(90)

‘Вызываем функцию, которая возвращает массив данных для отрисовки изображения
arrRender() = getArrayForRender(plX, plY, plPOV, arrMap())
Call renderImage(arrRender())

End Sub

Функция для определения положения игрока в системе координат выглядит следующим образом (на деле эту функцию можно сократить до нескольких строк, так как длина одного блока стены по X == его длине по Y. Для тестовой версии сойдёт и так):

Function GetPlayerCoord(arrMap() As Variant, strAxis As String) As Double

Dim countFD As Long, countSD As Long

For countFD = 1 To UBound(arrMap(), 1)

For countSD = 1 To UBound(arrMap(), 2)

If arrMap(countFD, countSD) = «P» Then

If strAxis = «X» Then

GetPlayerCoord = (cellWidth / 2) + (cellWidth * countSD)

ElseIf strAxis = «Y» Then

GetPlayerCoord = (cellHeight / 2) + (cellHeight * countFD)

End If

End If

Next

Next

End Function

P.S. Я уже почти нажал кнопку, чтобы опубликовать статью, и меня осенило, что можно вообще избавиться от переменной «размер блока» и этой функции. Я уже говорил, что не очень сообразительный?

Ядро движка

Теперь самое интересное. Для начала посмотрите на этот «профессиональный» чертеж:

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

Всего за цикл программа кастует ровно столько лучей, сколько пикселей занимает ширина поля вывода изображения. В нашем случае — 96 «ячеек-пикселей». В прошлом, когда компьютеры были слабые, это бы однозначно замедлило игру. Но мы живём во времена, когда не жалеют ресурсов даже для яиц коня, поэтому отрисовка целых 2 073 600 (1920 * 1080) различных пикселей не должна замедлить процессор. Конечно я говорю не про Excel, который подтормаживает даже при 6144 (96*64) «пикселях».

Первый луч будет «брошен» под углом, который рассчитывается по формуле: направление взгляда — поле обзора/2.

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

Угол последнего луча рассчитывается по формуле: направление взгляда + поле обзора/2.

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

Высота столбца рассчитывается исходя из высоты экрана и размера одного блока стены. Произведение этих двух показателей делится на полученные значения дистанции до стены (длину луча). Для того, чтобы в результате отрисовки стен не получился эффект «fish eye», полученное значение умножается на косинус разницы направления взгляда и поля обзора игрока.

Function getArrayForRender(plX As Double, plY As Double, _
plPOV As Double, arrMap() As Variant) As Variant

Dim arrRender(0 To 95) As Variant, countRays As Integer, countLength As Double, rayX As Double, rayY As Double, _
rayXMod As Long, rayYMod As Long, FOVAngle As Double, plFOV As Double

plFOV = Application.WorksheetFunction.Radians(FOV)

For countRays = 0 To 95 Step 1
‘Рассчитываем угол каждого последующего луча
FOVAngle = (plPOV — plFOV / 2) + (countRays * (plFOV / RENDER_W))

‘Цикл, который перемещает луч вперёд под установленным углом
For countLength = 0 To RENDER_H * 20 Step 0.05

‘Новые значения X и Y для каждой итерации цикла
rayY = plY + countLength * Sin(FOVAngle)
rayX = plX + countLength * Cos(FOVAngle)
‘Считаем, в каком элементе массива карты находится стена
rayYMod = Int(rayY / cellHeight)
rayXMod = Int(rayX / cellWidth)

‘Если луч встречает стену («1»)
If arrMap(rayYMod, rayXMod) = «1» Then
‘Записываем в массив высоту каждого столбца
arrRender(countRays) = (Int((RENDER_H * 64) / (countLength * Cos(plPOV — FOVAngle))))
Exit For

End If

Next

Next

getArrayForRender = arrRender()

End Function

Рендеринг изображения

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

Для этого пишем следующий метод:

Sub renderImage(arrRender() As Variant)

Dim rngField As Range, countColumns As Integer, countRows As Integer, firstRow As Integer
‘Запускаем оптимизацию: отключение обновления экрана
stuffM.startOpt

Set rngField = Sheets(«RENDER»).Range(Sheets(«RENDER»).Cells(2, 2), Sheets(«RENDER»).Cells(RENDER_H + 1, RENDER_W + 1))
rngField.Interior.Color = RGB(200, 200, 200)

For countColumns = 1 To 96
‘Каждое нечетное число приводим к четному для более плавной отрисовки
If arrRender(countColumns — 1) Mod 2 <> 0 Then

arrRender(countColumns — 1) = arrRender(countColumns — 1)

End If

‘Если столбец выше размера экрана, приводим его к размеру экрана
If arrRender(countColumns — 1) > 64 Then

arrRender(countColumns — 1) = 64

End If

‘Ячейка, с которой начинается отрисовка столбца
firstRow = RENDER_H / 2 — arrRender(countColumns — 1) / 2

‘Отрисовка столбцов
For countRows = firstRow To firstRow + arrRender(countColumns — 1)

rngField.Cells(countRows, countColumns).Interior.Color = vbWhite

Next

Next

‘Останавливаем оптимизацию
stuffM.stopOpt
End Sub

Вот что получается в итоге:

​Красной стрелкой — направление взгляда

Видео, которое демонстрирует процесс рендеринга

В заключение

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

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

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

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

P.S. Теперь, когда я испытал подобный опыт, тот клон Doom, который сделал в Excel один несчастный программист (с разрушением окружения, многоуровневостью и даже воксельными моделями), уже не кажется таким фантастическим. Конечно путь от простого рендеринга лабиринта до полноценной игры — сложный путь. Он требует огромного количества времени, сил, знаний и навыка усидчивости.

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

Skip to content

Блог

hzoRfL

Hi everyone! This went on for a very long time (even too much), but finally ended! We present to your attention the first custom version of the 3D shooter, made in the most ordinary Excel workbook as a macro. If you saw our old videos, then expect new details, mechanics, characters, references, user options and a more lively gameplay, scattered on seven scale levels of the notorious Project 7 base and in some places outside the Earth! And if this is your first encounter with our project, just be prepared to be surprised. This is not every day you see. So – that will give – the file at the bottom of the link:

Game File

(when you run the file, you will most likely notice that the sounds in the game are accompanied by the Windows system sound. To avoid this, after starting the game, click on the game icon in the quick access panel until the word “Compatibility mode” at the top of the Excel window changes color – unfortunately, this feature of Windows and Excel interaction could not be avoided).

14/10/2019

Some guys asked me for in-game music. Although all the music used in the trailers is already in the game file (yes, you just need to play the game to hear it))), but the level melodies are stored in MIDI format (to keep the game as small as possible and to maintain authenticity of first 3D shooters). Therefore, here I will post MP3 versions. Feel free to listen to this, but be sure to mention me if you want to use it in your media:

08/12/2019

I was asked to share layouts of the game levels. I don’t know if it will be helpful but OK – here is the 1st level of the game:

Some secret places were erased from this layout just to make further playing more interesting (indeed level 1 is full of secret places – much more then level 1 of classic Doom was).
PS.Some minor bugs were eliminated from engine, so new version of the game file was uploaded – check the link above).

22/03/2020

New update (a bit less in size, a bit faster). Check it and stay healthy (in term of COVID-19). Good luck!

07/04/2020

A couple of bugs eliminated and size reduced for a little. Check it again. Have a nice day!

Это ваша самая первая запись. Чтобы отредактировать или удалить её, нажмите кнопку «Изменить» или создайте новую запись. Если вы хотите написать что-нибудь ещё, расскажите читателям, почему завели блог и что планируете в нём публиковать. По всем вопросам вы можете обратиться к участникам форумов поддержки.

Над этим удивительным проектом Александр Шумаков работал вместе с сыном Никитой, создав команду под названием «DIY interactive». Как пишет Александр, у него есть некоторые навыки работы с Microsoft Excel и программу он ценит прежде всего за гибкость. Как-то он услышал об играх, написанных полностью на Excel и ему понравилась эта идея. Так родилась «Dave vs Ziggy» — ретро-пиксельная 3D-стрелялка, которую программировали на языке Visual Basic for Applications.

Аутентичный игровой движок позволяет создавать «многоэтажные» конструкции, шейдеры, воксельные и полигональные объекты, интерактивные механики, кровавые перестрелки и мини-игры наподобие Box World или Pong.

В «Dave vs Ziggy» вы можете проходить уровни секретной базы, захваченной пришельцами, убивать существ и сталкиваться с различными особенностями. Иногда в игре нужно использовать свою логику, чтобы двигаться дальше. В шутере даже можно сохранить свой прогресс в любое время (доступно 3 слота) и перезапустить.

Работа над проектом началась ещё в 2016 году. По словам авторов, это не просто очередная инди-игра в стиле ретро, а попытка усовершенствовать программирование на VBA и расширить границы использования Excel.

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

Понравилась статья? Поделить с друзьями:
  • Datum filter in excel
  • Datum another word for
  • Dating service in word
  • Dating and the s word
  • Datevalue in excel vba