2.5D Renderer

Stage 2: Отрисовка секторов

Уровень из секторов

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

Также вместо понятия «отрезок» Linedef будем использовать понятие «сегмент» Seg, поскольку линия в дальнейшем может быть разбита на несколько частей. Теперь сектор будем описывать как множество сегментов:


  interface Sector {
    segs: Seg[];
  }

  interface Seg extends Linedef {}

Уровень на основе линий

Вид сверху

Уровень на основе секторов

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

И если раньше мы строили проекции на основе множества Linedef из уровня:


  function render25d(
    ctx: CanvasRenderingContext2D,
    settings: Settings,
  ) {
    const camera = settings.camera;
    // ..

    settings.level.linedefs.forEach(function(linedef, index) {
      const projection = projectLinedef(camera, linedef);
      // ..

То теперь строим на основе множества Seg, которое содержит каждый сектор:


  function render25d(
    ctx: CanvasRenderingContext2D,
    settings: Settings,
  ) {
    const camera = settings.camera;
    // ..

    settings.level.sectors!.forEach(function(sector) {
      sector.segs.forEach(function(seg, index) {
        const projection = projectLinedef(camera, seg);
        // ...

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

Реализация шага на github