О псевдо-3D играх
Недавно я натолкнулся на одно видео и решил попробовать написать по нему в будущем свою игру (на Python) по такому же принципу, как и была написана данная игрушка. Меня очень привлек возможный результат, который можно получить буквально в считанные минуты! Vektozavr-ilinblog в своем не очень длинном видео рассказал ужасную правду: многим полюбившиеся игры Doom и Wolfenstein 3d, которые покорили всех геймеров прорывом в 3D игроиндустрии, далеко не являются 3D играми...
Для начала давайте разберем код Vektozavr-а. Данный ютубер выбрал C++ для написания иллюзии 3D. В своем видео и статье программист говорил о неком методе Ray casting. По статье в Википедии это:
Один из методов рендеринга в компьютерной графике, при котором сцена строится на основе замеров пересечения лучей с визуализируемой поверхностью
Если говорить проще, это один из методов получения изображения в компьютерной графике, когда оно создается посредством различных измерений пересекающихся лучей (некого "зрения" игрока) и поверхностей в визуализации, допустим, игры. Ниже я более подробно объясню о употреблении метода "бросания лучей" в создании собственной игры. Возвращаясь к началу: некий Иван Ильин писал в своей статье, что был вдохновлен видео Code-It-Yourself! First Person Shooter (Quick and Simple C++) с канала javidx9 (OneLoneCoder):
Мне настолько понравилась идея и простота её реализации, что я просто не мог сдержаться, чтобы не рассказать о ней!
Давайте, прежде чем познавать простоту геймдева, вернемся немного в прошлое и познакомимся с играми, которые стали маяком для создания чего-то ностальгического, и в тоже время нового и необычного, без невероятной графики и реализма, чего-то простого, но при этом затягивающего...Вообщем консольной игрушки,"екзешки"-называйте как хотите, а мы перейдем к сути:
Олды псевдо-3D игроиндустрии
В данной статье я не буду затрагивать такие недокументированные игры, как Maze War и SPASIM. Хочется поговорить немного именно о тех, которые стали неким переходом от тривиальных бродилок и консольных программок до полноценных 3D шутеров и «трипл-эй» (высокобюджетных) проектов
1) Wolfenstein 3d
Я начну с игры 1992 года, которая была разработана компанией id Software. Wolfenstein 3d является третьей игрой в серии игр Wolfenstein. В этой игре:
Игрок берёт на себя роль разведчика союзников Второй мировой войны Уильяма (Би-Джея) Бласковица, который пытается сбежать из места своего заключения — замка Вольфенштайн — и выполняет ряд диверсионных заданий против нацистского режима. На каждом уровне игрок должен сражаться с нацистскими солдатами, собаками и мутантами, используя нож и огнестрельное оружие, а также добраться до лифта или победить финального босса
Wolfenstein 3D стала первым после игр серии Commander Keen крупным проектом id Software. В середине 1991 года программист id Software Джон Кармак экспериментировал с «быстрым» псевдотрёхмерным игровым движком, который был использован командой в играх Hovertank 3D и Catacomb 3-D, впоследствии использованных в качестве прототипов Wolfenstein 3D
2) Doom(DooM или DOOM)
Компьютерная игра, разработанная и выпущенная компанией id Software в 1993 году. Doom является одной из самых значительных и влиятельных компьютерных игр в истории индустрии. Её популярность во многом определила дальнейшее развитие и распространение жанра шутеров от первого лица.
Игроку(игрок выступает в роли безымянного космического пехотинца ) предлагается поочередно исследовать уровни разной сложности, разгадывать пространственные и (редко) логические задачи, находить тайники, уничтожать как можно больше монстров и выживать.
Те, кто играли в эти игры, поймут, насколько ностальгическим покажется Вам эта бродилка.
Ray casting
Мы будем строить изображение в два цикла, изменяя во внешнем цикле координату по X и во внутреннем-по Y.
Для того, чтобы построить часть изображения - вертикальную полоску на экране, нужно найти расстояние от наблюдателя до предмета, который попадет в эту полоску.
У наблюдателя есть некоторый угол обзора, в который могут попасть предметы. Расстояние до них мы и будем пытаться найти:
Расстояние до стены будем искать итерационно: в начале мы имеем направление в котором хотим проверить наличие препятствия, после этого мы циклично, небольшими шагами идем в этом направлении. В конце концов возможно два результата: либо луч столкнулся с препятствием, либо он отправился в бесконечное путешествие
Тут все очень просто. Наш игрок, для того, чтобы определить расстояние до препятствия, если оно есть, будет идти к этому препятствию "в уме". И если он столкнется с препятствием, то количество шагов, потраченное во время "ходьбы" и будет этим условным расстоянием от игрока до препятствия
Чтобы не попадать в бесконечный цикл нужно ограничить радиус видимости. Если стенка не попала в радиус видимости, то мы будем воспринимать это как отсутствие препятствия в данном направлении
Выполнение данной мысли защищает нас от бесконечного цикла программы-игры, который не даст нам в принципе играть дальше.
Чем дальше находится стенка, тем меньше места она должна занимать на экране и тем больше места будут занимать небо и земля
В принципе, и здесь нет ничего сложного: здесь описан метод работы перспективы и метода Ray casting, к которому я обещал вернуться.
В дальнейшем идут математические расчеты: длины лучей по всему углу обзора игрока.
По сути, у нас теперь есть все для того, чтобы создать иллюзию 3D. Имея расстояние d до стенки в данном направлении, мы можем вычислить её высоту относительно экрана. Как это сделать? Нужно понять как изменяется относительная высота объектов при изменении расстояния до них
Ниже мы увидим явное применение подобия треугольников(вот и пригодилась геометрия...)
В своей статье программист предлагал к изучению множество формул для определения высоты стен, используя понятие перспективы. Их Вы уже увидите самостоятельно и изучите более детально.
Для отрисовки изображения мы пускаем лучи от наблюдателя в пределах угла обзора. В направлении каждого такого луча, идя маленькими шагами, считаем расстояние до ближайшего препятствия. Теперь на экране мы рисуем много вертикальных полосок разной высоты. Высоту этой полоски задаём таким образом, чтобы она была пропорциональна расстоянию до стенки в соответствующем направлении. На выходе получаем эффект третьего измерения
Отображение рёбер
В игре не хватает еще чего-то...В ней тяжело ориентироваться. Для этого мы добавим в игру ребра. Определить местоположение ребра очень просто. Поскольку мы теперь можем определить расстояние до препятствия и его размеры, то следовательно и местоположение ребра не сложно определить.
То есть у нас есть четыре вектора, которые направлены от наблюдателя точно в рёбра стенки. Если угол между испускаемым лучом и одним из этих векторов становится маленьким, то мы будем воспринимать эту часть стенки за ребро и рисовать её другим символом
Посредством написания еще нескольких строк кода получается неплохая бродилка 90-х годов. Скоро я напишу статью о интеграции Ray casting в Python. В эту же интеграцию я добавлю врагов, а значит попробую сделать полноценный шутер 90-х. С Вами был ДВ01ЧНЫЙ КОД, подписывайтесь на канал, переходите на канал Vektozavra, ведь там еще очень много интересного контента, а Вы не забывайте: игра-это не графика и геймплей, игра-это веха программирования, игра-это возможность вернуться в начало, чтобы двинуться дальше...в будущее!
Материал о играх Doom,Wolfenstein 3d и методе Ray casting был взят с сайта Википедия
Код на гитхабе javidx9