HTML5 хранилище в действии

Подготовили: Евгений Рыжков и Татьяна Головко Дата публикации: 28.03.2011

Рассмотрим использование HTML5 хранилища на реальном примере. Помнишь, в одной из глав мы реализовывали игру «Уголки»? В той реализации была небольшая проблема: если в процессе игры закрыть окно браузера, игра будет потеряна. HTML5 хранилище, дает возможность сохранить текущую игру локально. Посмотреть такую реализацию можно по этой ссылке. Сделай несколько ходов и закрой браузер. Когда зайдешь в игру снова, все фигуры должны находится на тех же местах, на которых были оставлены. Также сохранится число ходов. Конечно, все сохранится при условии поддержки браузером HTML5 хранилища.

Как это работает? При каждом изменении в игре, мы вызываем функцию:

function saveGameState() {
	if (!supportsLocalStorage()) { return false; }
	localStorage["halma.game.in.progress"] = gGameInProgress;
	for (var i = 0; i < kNumPieces; i++) {
		localStorage["halma.piece." + i + ".row"] = gPieces[i].row;
		localStorage["halma.piece." + i + ".column"] = gPieces[i].column;
	}
	localStorage["halma.selectedpiece"] = gSelectedPieceIndex;
	localStorage["halma.selectedpiecehasmoved"] gSelectedPieceHasMoved;
	localStorage["halma.movecount"] = gMoveCount;
	return true;
}

Как видишь, мы используем объект localStorage для отслеживания изменений в игре (gGameInProgress — булевый тип): если произошли изменения, gGameInProgress получит значение true. Если произошло изменение, запускаем цикл для перебора всех фигур (gPieces — Javascript массив) и сохранения номеров их строк и колонок. Затем сохраняем некоторые дополнительные сведения по игре: выбранную фигуру (gSelectedPieceIndex — целое число), может ли потенциально совершить самый длинный прыжок (сделать самый удачный ход) выделенная фигура (gSelectedPieceHasMoved — булевый тип) и число уже совершенных ходов (gMoveCount — целое число).

Во время загрузки страницы мы не вызываем функцию newGame(), которая сбрасывает все сохранения в игре, мы вызываем resumeGame(). resumeGame() проверяет, есть ли какие-то сейвы для игры. Если таковые имеются — они извлекаются из хранилища, используя объект localStorage:

function resumeGame() {
	if (!supportsLocalStorage()) { return false; }
	gGameInProgress = (localStorage["halma.game.in.progress"] == "true");
	if (!gGameInProgress) { return false; }
	gPieces = new Array(kNumPieces);
	for (var i = 0; i < kNumPieces; i++) {
		var row = parseInt(localStorage["halma.piece." + i + ".row"]);
		var column = parseInt(localStorage["halma.piece." + i + ".column"]);
		gPieces[i] = new Cell(row, column);
	}
	gNumPieces = kNumPieces;
	gSelectedPieceIndex = parseInt(localStorage["halma.selectedpiece"]);
	gSelectedPieceHasMoved = localStorage["halma.selectedpiecehasmoved"] == "true";
	gMoveCount = parseInt(localStorage["halma.movecount"]);
	drawBoard();
	return true;
}

Важный момент, о котором я уже упоминал — данные хранятся в виде строк. Если данные должны содержать другие типы — придется немного напрячься, чтобы их получить в нужном виде. Например, у нас есть флаг gGameInProgress в булевом типе. В функции saveGameState() мы его просто сохраняли ни о чем не беспокоясь:

localStorage["halma.game.in.progress"] = gGameInProgress;

А вот в resumeGame() нам нужно анализировать полученные данные из хранилища и вручную «делать» себе булевый тип:

gGameInProgress = (localStorage["halma.game.in.progress"] == "true");

Аналогично и с целыми числами, как, например, у нас хранится число сделанных ходов gMoveCount. Сохраняем просто:

localStorage["halma.movecount"] = gMoveCount;

извлекаем c шаманством:

gMoveCount = parseInt(localStorage["halma.movecount"]);

Куда дальше

Показать комментарии