Чистый CSS для реализации квеста

CSS
Чистый CSS для реализации квеста

предисловие

Всем привет, это волшебник CSS - alphardex.

Слово «побег из комнаты» должно быть всем знакомо, ведь в прошлую эпоху флэш-памяти это была одна из классических игр-головоломок. Игроки часто оказываются в ловушке в секретной комнате, и цель прохождения уровня — попытаться сбежать из секретной комнаты. Ниже представлена ​​самая ранняя игра, в которую я играл, — Crimson Room, которую также можно назвать прародительницей игр в жанре квеста.

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

Да, вы не ослышались, чистый CSS, что означает полное отсутствие JS. Некоторые люди задаются вопросом: что за CSS, язык верстки веб-страниц, на самом деле может писать игры? К сожалению, на CSS действительно можно писать игры. Далее войдите в эту невероятную страну вместе с автором.

Рейдеры

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

1. 左转,转动地球仪
2. 右转,发现一根锤子,点击捡起,记住墙上的数字
3. 左转,点击柜子,用锤子砸开它,获得一个圆盘
4. 点击墙上的壁画,壁画移开,看到一圆盘印,嵌入圆盘,获得一个usb
5. 右转2次,将usb插入电脑,电脑开启,输入墙上的密码,获得钥匙
6. 右转,用钥匙打开大门,游戏结束

выключатель

Сформулировав стратегию, необходимо приступить к определению ядра игры — переключателя. Говоря о переключателях, какой элемент в HTML, по вашему мнению, больше всего подходит для переключателя? Ответ - один флажок.

Говоря об одном флажке, мы должны упомянуть эти 2 CP——labelи родственный селектор.labelОтвечает за использование элемента с соответствующим флажкомforассоциироваться, а селектор одного уровня отвечает за:checkedПсевдокласс работает хорошо, и когда элемент проверяется, его соседние элементы будут затронуты им.

Во-первых, давайте рассмотрим пример простого переключателя.

<input type="radio" id="globe" class="globe-trigger" />
<input type="radio" id="hammer" class="hammer-trigger" />
<label for="globe" class="globe">
  <img src="https://i.loli.net/2020/10/25/YBnOQ2jVtSTmFkE.png" alt class="w-8" />
</label>
<label for="hammer" class="hammer">
  <img src="https://i.loli.net/2020/10/25/KhVp4EaMoYrjlIC.png" alt class="w-6" />
</label>
.hammer {
  display: none;
}

.globe-trigger:checked {
  & ~ {
    .globe {
      pointer-events: none;
    }

    .hammer {
      display: inline-block;
    }
  }
}

.hammer-trigger:checked {
  & ~ {
    .hammer {
      transform: scale(0);
      opacity: 0;
    }
  }
}

Вы можете видеть, что мы используемlabelЭлемент оборачивает соответствующее изображение и связывает соответствующий переключатель. Когда пользователь нажимает на глобусglobeчас,globe-triggerпереключатель сработает, т.labelактуальность

После срабатывания переключателя изменяется состояние соответствующего элемента рядом с переключателем:globeстановится некликабельным;hammerпоявляется элемент, это то, что делает родственный селектор

Точно так же нажмите молотокhammer, связанныеhammer-triggerПереключатель срабатывает, и в то же время следующийhammerисчезнет, ​​представляя действие «поднятия» пользователем

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

input[type="checkbox"],
input[type="radio"] {
  display: none;
}

переключатель сцены

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

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

<div class="camera">
  <!-- 导航 -->
  <input type="radio" id="nav-1" name="nav" class="nav-trigger-1" />
  <input type="radio" id="nav-2" name="nav" class="nav-trigger-2" />
  <input type="radio" id="nav-3" name="nav" class="nav-trigger-3" />
  <input type="radio" id="nav-4" name="nav" class="nav-trigger-4" />
  <!-- 长图 -->
  <form class="stage">
    <!-- 开关 -->
    <input type="checkbox" id="globe" class="globe-trigger" />...
    <!-- 场景 -->
    <div class="scene scene-1">
      <label for="...">...</label>
      <nav class="navs">
        <label for="nav-4" class="nav-left"></label>
        <label for="nav-2" class="nav-right"></label>
      </nav>
    </div>
  </form>
</div>

Во-первых, установите фиксированную перспективу игры и обрежьте лишние части.

.camera {
  --stage-width: 18rem;
  --scene-id: 0;

  position: relative;
  width: var(--stage-width);
  height: var(--stage-width);
  overflow: hidden;
}

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

@for $i from 1 through 4 {
  .nav-trigger-#{$i}:checked {
    & ~ .stage {
      --scene-id: #{$i - 1};
    }
  }
}

.stage {
  transform: translateY(calc(var(--stage-width) * var(--scene-id) * -1));
}

.scene {
  position: relative;
  width: var(--stage-width);
  height: var(--stage-width);
}

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

На этом эффект переключения сцен заканчивается.

Завершить проект

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

Адрес онлайн-игры:Escape Room Game