Info Guide #12
31 декабря 2017

Код - Посекторный движок для 3D-шутера от Destr.

     Посекторный движок
     Посекторный движок для 3D-шутера
Destr

   Основная  идея двига - это движок, опи─
санный  в  "Adventurer #13: Обмен опытом -
Как написать 3D игру типа DOOM". 
(http://zxpress.ru/article.php?id=10028)
   Но мне не удалось переделать их код под
свои  представления, поэтому изложу просто
общие  принципы. Основное отличие - это не
заливать стенки.
   Т.е. имеем  мир, устроеный  из выпуклых
секторов и отображем только пол и потолок.
Всё  это для ускорения (хочется ведь побо─
льше фреймов).
   Итак, берется сектор - например, такой:



   Камера  находится  в точке  0, "взгляд"
направлен по стрелке.
   Надо  спроецировать все точки сектора в
перспективу и обрезать ПО ГРАНИЦАМ ЭКРАНА.
Как  именно проецировать - решать каждому,
но очевидно,что перспективная проекция тут
наиболее приемлема,т.е. "вверх" на рисунке
- это Z ("вглубь" экрана).
   Получим что-то типа того:



   Красный прямоугольник - это экран, т.е.
всё, что снаружи, - уже невидимо.
   "Пол" у нас есть :)
   Теперь, если мы хотим высоту пола и по─
толка  во всех секторах одинаковыми (а это
даст прирост кадров в секунду,т.е. потолок
не  надо проецировать отдельно), то "пото─
лок"  можно  получить  простым  отражением
"пола" вверх ногами.



   Если разные высоты потолка всё таки хо─
чется, а тратить время на проекцию потолка
всё равно жалко, то можно пойти на компро─
мисс - печатать  потолок  не  с серединным
отражением, а со смещением.

 

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

 

   Но, как  видно на рисунке, придётся ещё
раз клипировать по верхней границе.
   Это не идёт на пользу в плане скорости.
   Теперь осталось соединить углы (те, что
видны на экране)- и вид "в комнату" готов.

 

   Чтобы визуальный эффект объёма был ощу─
тимей - надо бы залить пол и потолок.

 

   На Speccy  для этого достаточно заливки
"через строчку" (опять же, для скорости).
   Итак мы получили залитый пол, потолок и
голые  стенки. Накладывать на них текстуру
- долго, а  у нас  ставка на скорость. Для
шутера вполне пойдёт,если все стенки будут
белыми,- главное атмосфера.

   Теперь о связи между секторами. Для то─
го, чтоб из одного сектора видеть содержи─
мое других,надо пробежаться обработчиком и
по  соседним. Какой из них видим полностью
или  частично, выяснить  нетрудно, а вот с
отображением есть нюансы.
   Сперва надо построить самый дальний ви─
димый сектор,потом тот,что поближе - и так
по мере приближения к камере. Но! Построе─
ние  идёт после ПОЛНОЙ обработки всех сек─
торов, что  ближе к камере,- и вот почему.
Допустим, мы  хотим расширить наш мини-мир
на один сектор, например, так:



   Зелёным  цветом показана "спайка" между
секторами.
   Проецируем:

 

   Разворачиваем "потолок"

 

   Здесь  синим  цветом  выделены  ГРАНИЦЫ
КЛИПИРОВАНИЯ  для "дальнего" сектора. Если
из него видно что-то ещё более далёкое,оно
будет клипироватся уже по следующему ребру
"спайки" (или  границе  экрана, если ребро
за него вылазит).
   Здесь выигрыш в скорости в том, что эти
границы - всегда строго вертикальны,а зна─
чит,математика получается не сильно затра─
тная. Потолки рисуются последовательно, и,
соответственно, их стыки не будут даже ви─
дны (ведь заливать всё это можно побайтно,
а то и по паре байт).
   Если оставлять  одинаковую высоту пола/
потолка  для всех секторов, то можно их не
заливать  и получить движок, который будет
довольно шустрым, но примитивным. По слож─
ности он будет как классический квадратный
рейкастовый  двиг, но с возможностью любых
углов, зато без текстур.
   Если  делать  возможность  разных высот
потолка, то можно делать не просто коридо─
ры-комнаты, но и межкомнатные двери (и они
даже  смогут раздвигаться, открывая взору,
что  там  за ними), но скорость расчётов и
отрисовки так упадёт, что шутер уже не по─
строишь,а красивую бродилку-лабиринт можно
сделать и на движке 3D Construction Kit...
   Для  всего этого (даже для самого прос─
того варианта,без заливок) нужна математи─
ка хорошая (8.8 как минимум) и быстрая.Где
такую взять, мне неизвестно,а то,что я сам
наизобретал, показывать крайне не рекомен─
дуется.
   Наверняка  можно адаптировать Адвенчур─
ный #13 двиг из статьи (которыйDUKEmain), 
но сперва  придётся  разложить его по пол─
кам, что у меня, опять же, не вышло.
   Однако  если  всё-таки  удастся сделать
проволочную  бегалку, то  встаёт  в полный
рост вопрос,что там делать.Нужны ведь вра─
ги, нужно  оружие, а выводить это всё тоже
очень долго. Скрепя сердце, можно выводить
оружие развёрнутыми (и,следовательно,боль─
шими  по  объёму памяти) процедурами, но с
масштабированными врагами такое, наверное,
не получится.

  Также довольно остро стоит вопрос о пе─
ремещениях  внутри  сектора и "упирания" в
стенку. Тут  могут  помочь заранее просчи─
таные  массивы всех стенок для всех секто─
ров, но  даже в этом случае довольно много
времени  после  КАЖДОГО  шага игрока будет
тратиться  на  проверку "не пытаемся ли мы
лезть на стену", чтобы если это так,то пе─
ремещения не делать. В таких случаях поло─
жено  "скользить"  вдоль стены, а это тоже
непростая задача. Правда,можно хранить ка─
ждый сектор не только как массив координат
описывающих точек,но и ещё как набор неких
"векторов", тогда достаточно будет склады─
вать их направление с направлением текуще─
го  взгляда  и делать шаг в результирующем
направлении. Но  это в теории, на практике
неизвестно, получится ли.

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

                  * * *

   Ред.:
   Смотрите демоверсию в приложении.
   Чтобы  быстрее  заливать  пол и потолок
серым цветом,лучше использовать чересстро─ 
чную сеточку, например, 25-процентную. 

   (Предполагается, что  экран  изначально
очищен значением#ff,линии нарисованы но─ 
ликами.) 
   Идём  сверху  каждого столбца экрана до
середины, изначальноc=#ff:

  ld a,c
  and (hl);накапливаем нолики в столбце
  inc h
  and (hl);накапливаем нолики в столбце
  ld c,a
;c=маска, какие биты в этом байте надо 
 ;затекстурить (единички), напр. %11111000
;(hl)=линии, которые надо наложить (нолики 
 ;на фоне единичек), напр. %11111001
  and d;e;строка текстуры,напр.%10111011
;a=%10111000 
  cpl
;a=%01000111 
  and c
;a=%01000000 
  xor (hl)
  cpl
  ld (hl),a;%10111001
  inc h

   или
   (Предполагается, что  экран  изначально
очищен  значением #00, линии  нарисованы 
единичками,c=#00.) 

  ld a,c
  or (hl);накапливаем единички в столбце
  inc h
  or (hl);накапливаем единички в столбце
  ld c,a
;c=маска, какие биты в этом байте надо 
 ;затекстурить (нолики), напр. %00000111
;(hl)=линии, которые надо наложить (1 
 ;на фоне 0), напр. %00000110
  or d;e;строка текстуры, напр.%01000100
;a=%01000111 
  cpl
;a=%10111000 
  or c
  cpl
;a=%01000000 
  or (hl)
  ld (hl),a;%01000110
  inc h

   Аналогично  заливаем  пол - идём  снизу
каждого столбца экрана до середины. 

   Оба  варианта  занимают  50 тактов на 2
байта, но работают прямо в экране. 
   Если работаем в буфере, а штриховки на─
кладываются  целыми знакоместными столбца─ 
ми,то можно залить столбец через 
  xor (hl):ld (hl),a:inc l
(18 тактов на байт), 
а потом  перебросить  на экран с текстурой 
через 
  pop bc
  ld a,c:and e:ld (hl),a:inc h
  ld a,b:and d:ld (hl),a:inc h
(24 такта на байт). 
   Итого 42. Это при сплошной текстуре.
   При чересстрочной убирается каждый вто─
рой ld (hl),a в заливке  и каждый второй 
ld a,b:and d:ld (hl),a  (с возможной заме─
нойinc h:inc hнаld h,N)  в текстуриро─ 
вании, остаётся 20(19) тактов на байт. 

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




Темы: Игры, Программное обеспечение, Пресса, Аппаратное обеспечение, Сеть, Демосцена, Люди, Программирование

Похожие статьи:
Новости - новости от фирмы WELCOME.
Scene - Бунтующий демосценер.
Вступление - Заполняйте и присылайте анкеты.

В этот день...   24 сентября