«Если рабочий хочет хорошо выполнять свою работу, он должен сначала заточить свои инструменты» — Конфуций, «Аналитики Конфуция. Лу Лингун»
титульная страница > программирование > Слайдер-игра «Пазл» на HTML и CSS

Слайдер-игра «Пазл» на HTML и CSS

Опубликовано 15 августа 2024 г.
Просматривать:240

\

Перейти к загадке

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

Очевидно, это называется «Пазл 15» и существует с 1870-х годов. Поиск в Интернете выдает множество воссозданий, написанных на разных языках программирования, и действительно, на dev.to есть несколько статей, включая https://dev.to/artydev/let-us-code-a-sliding-puzzle-9n. , https://dev.to/xzanderzone/making-a-slider-puzzle-in-java-script-83m и https://dev.to/claurcia/slide-puzzle-5c55 — все на JavaScript и https:/ /dev.to/mfbmina/building-a-sliding-puzzle-with-go-3bnj в Go. Он также представлен как хорошее начальное задание для тех, кто изучает JavaScript.

Что меня заинтересовало, так это идея о том, что его можно воссоздать в Интернете, вообще не используя язык программирования! То есть реализация, использующая только чистый HTML и CSS. Поэтому я представляю это ниже. Единственный компромисс, на который мне пришлось пойти, заключался в том, что в 10 предоставленных играх были фиксированные, предварительно перетасованные стартовые позиции.

Для этого задан заранее порядок показа законченного изображения.

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

Таким образом, каждая плитка имеет пару групп переключателей, каждая из которых содержит четыре переключателя. Одна из этих групп сохраняет положение плитки по оси X, а другая — по оси Y. (Или горизонтальное и вертикальное положение соответственно, если хотите.) Каждому из пятнадцати плиток изначально присваивается разная комбинация координат X и Y с помощью переключателей, так что каждая из них занимает отдельную ячейку в кадре.
 
Плитки изначально размещаются в верхней левой ячейке фрейма, а затем перемещаются внутри фрейма с помощью CSS, измеряя состояние переключателей, применяя к ним преобразование перевода:

/* "X" refers to the X-axis cell positions, "Y" to the Y-axis cell positions. 
 * 0, 1, 2, 3 refers to the position on that axis, 
 * 0 = left and top, 3 = right and bottom respectively.
 */

.tile:has(.X0:checked~.Y0:checked) {
     transform: translate(0%, 0%);
}
.tile:has(.X0:checked~.Y1:checked) {
     transform: translate(0%, 100%);
}
.tile:has(.X0:checked~.Y2:checked) {
     transform: translate(0%, 200%);
}
.tile:has(.X0:checked~.Y3:checked) {
     transform: translate(0%, 300%);
}
.tile:has(.X1:checked~.Y0:checked) {
     transform: translate(100%, 0%);
}
/* and so on for the remainder of the sixteen combinations */

Плитка также содержит восемь элементов метки, соответствующих восьми переключателям. Каждая метка абсолютно позиционируется, накладываясь друг на друга, и каждая полностью заполняет плитку. Метки прозрачны и изначально настроены так, чтобы не реагировать на щелчки и касания, путем установки для всех из них pointer-events:none.

Следующий шаг — селекторы CSS должны определить, где находится пустая ячейка. Это делается методом исключения: это ячейка, координаты X,Y которой не представлены парой групп переключателей ни на одной из пятнадцати плиток.

Например, если это соответствует:

.frame:not(:has(.tile .X0:checked~.Y0:checked)) { .... }

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

Как только это будет сделано, можно будет идентифицировать ячейки, соседние с пустой ячейкой. Если пустая ячейка находится в углу, то есть ровно две плитки, которые могут переместиться в эту ячейку, в противном случае, если пустая ячейка находится напротив одной из сторон кадра, есть три плитки, которые могут переместиться в ячейку, в противном случае пустая ячейка ячейка должна быть одной из четырех средних ячеек, и есть четыре плитки, которые могут переместиться в нее. Для каждой из этих плиток ровно одна из восьми меток плитки активирует правильный переключатель, необходимый для перемещения плитки в пустую ячейку. Эта метка включается путем установки значения ее указателя-событий обратно в значение auto. Итак, примеры:

/* Top, left corner */
.frame:not(:has(.tile .X0:checked ~ .Y0:checked)) {
  :is(
      .tile:has(.X0:checked ~ .Y1:checked) label.Y0,
      .tile:has(.X1:checked ~ .Y0:checked) label.X0
    ) {
    pointer-events: auto;
  }
}

/* right most cell of row two */
.frame:not(:has(.tile .X1:checked ~ .Y3:checked)) {
  :is(
      .tile:has(.X1:checked ~ .Y2:checked) label.Y3,
      .tile:has(.X0:checked ~ .Y3:checked) label.X1,
      .tile:has(.X2:checked ~ .Y3:checked) label.X1
    ) {
    pointer-events: auto;
  }
}

/* second cell from left on row three */
.frame:not(:has(.tile .X2:checked ~ .Y1:checked)) {
  :is(
      .tile:has(.X2:checked ~ .Y0:checked) label.Y1,
      .tile:has(.X2:checked ~ .Y2:checked) label.Y1,
      .tile:has(.X1:checked ~ .Y1:checked) label.X2,
      .tile:has(.X3:checked ~ .Y1:checked) label.X2
    ) {
    pointer-events: auto;
  }
}

Последний шаг игры — определить, когда головоломка решена. Это просто случай проверки того, что для всех 15 плиток ожидаемые переключатели осей X и Y установлены в «решенное» положение.

/* Each tile is assigned a letter "a" to "o". 
 * The puzzle is solved when the tiles are in alphabetical order
 * reading left to right and top to bottom
*/
.frame:has(.a .X0:checked ~ .Y0:checked):has(.b .X1:checked ~ .Y0:checked):has(
    .c .X2:checked ~ .Y0:checked
  ):has(.d .X3:checked ~ .Y0:checked):has(.e .X0:checked ~ .Y1:checked):has(
    .f .X1:checked ~ .Y1:checked
  ):has(.g .X2:checked ~ .Y1:checked):has(.h .X3:checked ~ .Y1:checked):has(
    .i .X0:checked ~ .Y2:checked
  ):has(.j .X1:checked ~ .Y2:checked):has(.k .X2:checked ~ .Y2:checked):has(
    .l .X3:checked ~ .Y2:checked
  ):has(.m .X0:checked ~ .Y3:checked):has(.n .X1:checked ~ .Y3:checked):has(
    .o .X2:checked ~ .Y3:checked
  )
  ~ .options
  .success {
  display: block;
}

Остальное — косметика. Скольжение осуществляется с помощью простого перехода описанного выше преобразования

.tile {
  transition: 0.5s transform;
  @media (prefers-reduced-motion) {
    transition: none;
  }
}

и каждая плитка показывает часть изображения игры с использованием размера фона и положения фона

.tile {
  background-size: 400%;
}
#board1 .tile {
  background-image: url("https://alohci.net/image/dev.to/slidergame/mullermarc-k7bQqdUf954-unsplash.webp");
}
.a {
  background-position: 0% 0%;
}
.b {
  background-position: 33.333% 0%;
}
.c {
  background-position: 66.667% 0%;
}
.d {
  background-position: 100% 0%;
}
.e {
  background-position: 0% 33.333%;
}
/* and so on for the remaining tiles */

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

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

Я также предоставил «базовый» режим для отображения букв плитки и переключателей, который может помочь понять, как работают HTML и CSS.

Итак, вот законченная игра-головоломка. Пожалуйста, дайте мне знать, если у вас есть отзывы.


Заявление о выпуске Эта статья воспроизведена по адресу: https://dev.to/alohci/15-puzzle-slider-game-in-html-and-css-5g2i?1. Если есть какие-либо нарушения, свяжитесь с [email protected], чтобы удалить это
Последний учебник Более>

Изучайте китайский

Отказ от ответственности: Все предоставленные ресурсы частично взяты из Интернета. В случае нарушения ваших авторских прав или других прав и интересов, пожалуйста, объясните подробные причины и предоставьте доказательства авторских прав или прав и интересов, а затем отправьте их по электронной почте: [email protected]. Мы сделаем это за вас как можно скорее.

Copyright© 2022 湘ICP备2022001581号-3