Игры на CSS. Часть 2: StarCraft

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

Смотрите видео и под кат.


Разумеется, речь (пока) не идет о полноценной игре, но концепцию покажу.

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

Во-первых, в CSS у нас вся игра завязана на чекбоксах и radio кнопках и слеекторе "~". А потому изменяемые элементы должны находиться сверху страницы.

Назовем их «состояния»

<!-- Состояние --> 	<!-- Дефолтные состояния --> 	<input type="radio" name="button-level-2" id="default-state-level-2"> 	<input type="radio" name="button-level-1" id="default-state-level-1"> 	<input type="radio" name="unit" id="default-state-unit">  	<!-- Кнопки --> 		<!-- Нажата кнопка выбора построек --> 		<input class="state build-button probe" type="radio" name="button-level-1" id="build-button"> 		<!-- Для постройки выбран нексус --> 		<input class="state build-nexus start-build" type="radio" name="button-level-2" id="build-nexus"> 		<!-- Постройка пробок --> 		<input class="state build-probe-1" type="checkbox" id="build-probe-1"> 		<input class="state build-probe-2" type="checkbox" id="build-probe-2"> 		<input class="state build-probe-3" type="checkbox" id="build-probe-3"> 		<input class="state build-probe-4" type="checkbox" id="build-probe-4"> 		<input class="state build-probe-5" type="checkbox" id="build-probe-5"> 	<!-- /Кнопки -->   	<!-- Юниты --> 		<input class="state unit probe" type="radio" name="unit" id="start-probe"> 		<input class="state unit nexus" type="radio" name="unit" id="nexus-select"> 	<!-- /Юниты -->  <!-- /Состояние --> 

Кроме того, что они должны быть вверху, они еще не должны находиться внутри блоков, тк селектор "~" выбирает элементы того же уровня.
То есть, имея разметку

<input type="radio" name="unit" id="default-state-unit"> <div id="map"> 	<div class="some">Hiho</div> </div> 

Этот селектор не выберет ничего

#default-state-unit:checked ~ .some 

Это происходит потому, что .some вложен в #map, то есть находится на другом уровне вложенности.
В этом случае селектор необходимо начинать с ближайшего элемента того же уровня

#default-state-unit:checked ~ #map .some 

Сетка

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

<!-- Ячейка --> <div class="cell-label"> 	<!-- Нексус --> 	<label for="cell_6_nexus" class="nexus status unit"> 		<span class="inner"></span> 	</label> 	<input type="checkbox" id="cell_6_nexus" class="cell-state"> 	<label class="view nexus unit" for="nexus-select"> 		<div class="probes"> 			<div class="probe"></div> 			<div class="probe"></div> 			<div class="probe"></div> 			<div class="probe"></div> 			<div class="probe"></div> 		</div> 	</label> </div> <!-- /Ячейка --> 

За конечное отображение у нас отвечает блок .view (их может быть множество для разных состояний).
Включается состояние при нажатии на соответствующий label: включаем чекбокс — .view виден:

#map .cell-label .cell-state:checked + .view{ 	display: block; } 

Сам же лейбл виден тоже при определенных условиях. Например, когда мы собираемся строить нексус, у нас «виден» (display:block) label, отвечающий за это состояние:

.state.build-nexus:checked ~ #map .cell-label:hover label.status.nexus{ 	display: block; } 

При наведении курсора на ячейку мы хотим видеть предварительно, как будет стоять наше здание. Для этого просто стилизуем вложенный в label span (span больше label’а, лейбл размером с ячейку).
Итак, мы видим предварительное расположение постройки, но блок и изображением закрывает соседние ячейки, так что на них трудно обыграть состояние :hover (которое как раз и инициирует показ предварительной постройки).
Слава богам, мы уже можем использовать CSS4 свойство

pointer-events: none; 

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

Юниты

Юнитов и зданий у нас несколько, и выделяя каждый из этих элементов, мы хотим видеть разные кнопки на панели заданий.
Достигается это переключением радио-кнопок, ведь каждый раз мы можем выделить только одно здание/юнита (в оригинале не так).

Заключение

Хотел сделать некоторый сброс к дефолтным состояниям некоторых радио-кнопок, отвечающих за состояния панели при выделении юнита/здания.
Вложил лейбл в лейбл в лейбл рассчитывая, что клик по содержимому лейбла вызовет клик по контейнеру. Но на мое удивление это не сработало, кликается только внутренний лейбл.

<!-- Дефолтные состояния --> <input type="radio" name="button-level-2" id="default-state-level-2"> <input type="radio" name="button-level-1" id="default-state-level-1"> <input type="radio" name="unit" id="default-state-unit">  <!-- Сброс --> <label for="default-state-level-2" class="reset"> 	<label for="default-state-level-1" class="reset"> 		<label for="default-state-unit" class="reset"></label> 	</label> </label> <!-- /Сброс --> 

Разумеется, это всего лишь Proof-of-Concept и доделать-переделать тут можно много чего, я лишь указал направление для размышлений.

Ресурсы

ссылка на оригинал статьи http://habrahabr.ru/post/267801/

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *