Логическая игра с использованием элемента HTML5 canvas

Один из новых интересных элементов в HTML5 - <canvas>. Он позволяет разработчику рисовать все, что угодно с помощью JavaScript. В данном уроке мы создадим логическую игру на его основе.

Игра называется "Выключатель" и навеяна оригинальной версией для iPhone. Цель игры - выключить все лампочки, нажимая на них. При этом соседние лампочки переключают свое состояние. Довольно занимательная логическая головоломка.

demosourse

 

HTML/CSS

Разметка для нашей игры будет весьма незатейлива. Элемент <canvas> в контейнере и простые стили.

<div id="lightcontainer">
	<canvas id="lightpanel" width="500" height="500"></canvas>
</div>
#lightcontainer { margin:20px auto; width:500px; }
#lightpanel { background-color:#002B33;
	-moz-box-shadow:0 0 5px #999; -moz-border-radius:10px;
	-webkit-box-shadow:0 0 5px #999; -webkit-border-radius:10px;
	box-shadow:0 0 5px #999; border-radius:10px;
}

 

Идея

Ниже представлено несколько рисунков, которые описывают идею игры.

Сначала нам нужно создать игровое поле.

Игравое поле

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

Логика игры

В завершении создаем стартовую позицию.

Стартовая позиция

 

JavаScript

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

	// Двумерный массив, который представляет игровое поле
	// "x" означает "включено"
	// "o" означает "выключено"
	var lightField =
	[
		[ "x", "o", "o", "x", "x" ],
		[ "o", "o", "x", "o", "x" ],
		[ "o", "x", "o", "x", "o" ],
		[ "x", "o", "x", "o", "o" ],
		[ "x", "x", "o", "o", "x" ]
	];

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

	// Привязываем обработчик события click
	$("#lightpanel").click(function(e) {
		
		if(!userCanClick) {
			return false;	
		}
		
		// e дает нам абсолютные значения x и y, 
		// поэтому нам надо провести вычисления относительно положения элемента canvas
		var pos = $("#lightpanel").position();
		var ox = e.pageX - pos.left;
		var oy = e.pageY - pos.top;
		
		// Проверяем, какие поля надо перевернуть
		var yField = Math.floor(oy / 100);
		var xField = Math.floor(ox / 100);
		
		// Поле, на котором произошло событие click 
		lightField[yField][xField] = lightField[yField][xField] == "x" ? "o" : "x";
		
		// Поле выше
		if(yField-1 >= 0) {
			lightField[yField-1][xField] = lightField[yField-1][xField] == "x" ? "o" : "x";
		}
		
		// Поле ниже
		if(yField+1 < 5) {
			lightField[yField+1][xField] = lightField[yField+1][xField] == "x" ? "o" : "x";
		}
		
		// Поле справа
		if(xField-1 >= 0) {
			lightField[yField][xField-1] = lightField[yField][xField-1] == "x" ? "o" : "x";	
		}
		
		// Поле слева
		if(xField+1 < 5) {
			lightField[yField][xField+1] = lightField[yField][xField+1] == "x" ? "o" : "x";	
		}
		
		repaintPanel();
	});

Очень важная функция -  вывод панели.

	/*
	* Выводим панель
	*/
	function repaintPanel() {
		
		// Получаем элемент canvas
		var canvas = document.getElementById("lightpanel");
		
		// Проверяем поддержку браузером элемента <canvas>
		if (!canvas.getContext){
			alert("Для данной игры ваш браузер должен поддерживать элемент <canvas>.");
			return;
		} else {
			clear();
			
			// Получаем контекст для рисования
			var ctx = canvas.getContext("2d");
			
			// Создаем поля
			var allLightsAreOff = true;
			for(var i = 0; i < lightField.length; i++) { // Строки
				for (var j = 0; j < lightField[i].length; j++) { // Столбцы
					
					// Устанавливаем кисти
					ctx.lineWidth = 3;
					ctx.strokeStyle = "#83BD08";
					
					// Начинаем вывод
	        		ctx.beginPath();
	        		
	        		// arc( x, y, радиус, стартовый_угол, конечный_угол, против_часовой_стрелки)
			        ctx.arc(j * 100 + 50, i * 100 + 50, 40, 0, Math.PI*2, true);
			        
			        // Выводим рамку
	         		ctx.stroke();
	         		
	         		// Проверяем, нужно ли заполнять рамку
	         		if(lightField[i][j] == "x") {
	         			ctx.fillStyle = "#FFBD38";
	         			ctx.beginPath();
	         			ctx.arc(j * 100 + 50, i * 100 + 50, 38, 0, Math.PI*2, true);
	         			ctx.fill();
	         			
	         			// Так как нам нужно заполниить данное поле, то значит не все лампочки выключены
	         			allLightsAreOff = false;
	         		}
					
				}
			}
			
			// Проверка выключения всех лампочек
			if(allLightsAreOff) {
				// Пользователь больше не может нажимать на элементы
				userCanClick = false;
				
				// Выводим сообщение
				alert("Все лампочки выключены! Поздравляю с победой!");
			}
		}
	}

Так как элемент <canvas> не обновляется после перерисовки, нам придется вручную очищать его специальным методом clear:

	/*
	* Очищаем элемент canvas
	*/
	function clear() {
		var canvas = document.getElementById("lightpanel");
		var ctx = canvas.getContext("2d");
		ctx.clearRect(0, 0, 500, 500);
	}

 

Готово!

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

Данный урок подготовлен для вас командой сайта ruseller.com
Источник урока: www.marcofolio.net/webdesign/lights_off_a_puzzle_game_using_html5_canvas.html
Перевел: Сергей Фастунов
Урок создан: 1 Августа 2011
Просмотров: 32040
Правила перепечатки


5 последних уроков рубрики "HTML и DHTML"

^ Наверх ^