保存游戏(使用localStorage)并在重新加载页面后继续游戏的能力
Posted
技术标签:
【中文标题】保存游戏(使用localStorage)并在重新加载页面后继续游戏的能力【英文标题】:the ability to save the game (using localStorage) and after reload the page continue the game 【发布时间】:2021-02-20 04:04:14 【问题描述】:我正在制作一个宝石拼图。我有一个保存按钮。当你点击它时,游戏的当前状态被保存,这样当页面重新加载时,用户可以从他保存的地方继续玩。据我了解,我必须将表保存在 localStorage 中。并且在重新加载页面时,检查 localeStorage 是否为空。但是如何在页面重新加载时重新渲染游戏?当使用 json.stringify 和 json.parse 时,我有一个错误 Uncaught SyntaxError: Unexpected token o in JSON at position 1. 当我删除 json.stringify 和 json.parse 这是一个错误 Uncaught TypeError: Failed to execute 'appendChild' on '节点”:参数 1 不是“节点”类型。在 LocalStorage 是 [object htmlTableSectionElement]
let saveSession = false;
document.querySelector('.save-btn').addEventListener('click', () =>
saveSession = true;
)
function start()
let button = document.getElementById('newGame');
button.addEventListener('click', startNewGame, false );
textMoves = document.getElementById('moves');
table = document.getElementById('table');
rows = 4;
columns = 4;
startNewGame();
function startNewGame()
let arrayOfNumbers = new Array();
let arrayHasNumberBeenUsed;
let randomNumber = 0;
let count = 0;
moves = 0;
rows = document.getElementById('rows').value;
columns = document.getElementById('columns').value;
textMoves.innerHTML = moves;
arrayForBoard = new Array(rows);
for (let i = 0; i < rows; i++)
arrayForBoard[i] = new Array(columns);
arrayHasNumberBeenUsed = new Array( rows * columns );
for (let i = 0; i < rows * columns; i++)
arrayHasNumberBeenUsed[i] = 0;
for (let i = 0; i < rows * columns; i++)
randomNumber = Math.floor(Math.random()*rows * columns);
if (arrayHasNumberBeenUsed[randomNumber] == 0)
arrayHasNumberBeenUsed[randomNumber] = 1;
arrayOfNumbers.push(randomNumber);
else
i--;
count = 0;
for (let i = 0; i < rows; i++)
for (let j = 0; j < columns; j++)
arrayForBoard[i][j] = arrayOfNumbers[count];
count++;
showTable();
function showTable()
for (let tr of document.querySelectorAll("#table tr"))
tr.remove();
let tbody = document.createElement('tbody');
document.querySelector('#table').appendChild(tbody);
for (let i = 0; i < rows; i++)
let tr = document.createElement('tr');
for (let j = 0; j < columns; j++)
let cell = document.createElement('td');
if (arrayForBoard[i][j] == 0)
cell.className = 'blank';
else
cell.className = 'tile';
cell.draggable = true;
cell.addEventListener('click', () =>
moveThisTile(i, j);
)
cell.innerHTML =arrayForBoard[i][j];
tr.appendChild(cell);
tbody.appendChild(tr);
if(saveSession)
localStorage.setItem('currentGame', JSON.stringify(tbody));
;
window.addEventListener('load', () =>
if(localStorage.getItem('currentGame') !== null)
const tbody = JSON.parse(localStorage.getItem('currentGame'));
document.querySelector('#table').appendChild(tbody);
else
start();
, false );
【问题讨论】:
问题在于localStorage.setItem('currentGame', JSON.stringify(tbody));
JSON 库并不是一个神奇的解决方案,可以修复整个销售商店的完整文档元素,然后轻松检索它们..
【参考方案1】:
当您将某些内容保存到 localStorage 并使用 setItem() 时,您可以使用 getItem() 检索它。然而,这里重要的一件事是您的本地存储实际上并不将对象存储为本身。它存储的是 JSON 字符串。
所以你需要在使用 localStorage.setItem() 函数时执行以下操作:
if(saveSession)
localStorage.setItem('currentGame', JSON.stringify(tbody));
现在,当您需要从 localStorage 中检索此项目时,您必须解析之前存储到 localStorage 中的 JSON 字符串,您可以通过以下方式使用 localStorage.getItem() 函数:
window.addEventListener('load', () =>
const tbody = JSON.parse(localStorage.getItem('currentGame'));
如果您需要检查 localStorage.setItem() 是否正常工作,您可以转到 chrome 开发工具中的“应用程序”选项卡并从那里查看 localStorage。
【讨论】:
我有一个 [object HTMLTableSectionElement] 并且我有一个错误 Uncaught SyntaxError: Unexpected token o in JSON at position 1. 所以我删除了 JSON.stringify 和 JSON.parse: if(saveSession) localStorage. setItem('currentGame', tbody); window.addEventListener('load', () => const tbody = localStorage.getItem('currentGame');document.querySelector('#table').appendChild(tbody);并且还有一个错误无法在'Node'上执行'appendChild':参数1不是'Node'类型。 试图从评论中读取非常不清楚。您能否更新您的问题,添加您尝试过的内容以及收到的错误? 您可以尝试添加 JSON.stringify() 而不是 JSON.parse() 以查看确切的错误发生在哪里。如果只是 stringify 没有给出错误,那么我们可以查看 JSON.parse()。 重点是localStorage只能存储字符串,不能存储JS对象。因此,如果要使用 localStorage,则必须使用 JSON.stringify()。请检查您是否使用了正确的 JSON.stringify() 语法 - developer.mozilla.org/en-US/docs/Web/javascript/Reference/… 当我只使用 JSON.stringify() 而不是 JSON.parse() 时,我有错误 - 无法在 'Node' 上执行 'appendChild':参数 1 不是类型 'Node' 【参考方案2】:好的,我在看到另一个 localStorage 问题时遇到了这个问题,我现在要尝试回答:D
问题在于
localStorage.setItem('currentGame', JSON.stringify(tbody));
JSON 库并不是一个神奇的解决方案,可以解决整个销售商店的完整文档元素,然后轻松检索它们。..
我将只存储元素的一些数据以重新创建它(attributes
、inneHTML
、localName
)
遗漏了什么? elem 的父级,附加到 elem 的任何事件侦听器(函数有很多上下文,elem 的父级也是如此)
//saves an element
function saveElem(name,elem)
const item=attributes:[],localName:'',innerHTML:''
item.localName=elem.localName
item.innerHTML=elem.innerHTML
let attributes=item
for(let i=0;i<elem.attributes.length;i++)
attributes[i]=[elem.attributes[i].name, elem.attributes[i].value];
localStorage.setItem(name,JSON.stringify(item))
//loads an element
function loadElem(name)
const item=JSON.parse(localStorage.getItem(name))
const elem=document.createElement(item.localName)
item.attributes.forEach(([type,value])=>
elem.setAttribute(type,value)
)
elem.innerHTML=item.innerHTML
return elem
let saveSession = false;
document.querySelector('.save-btn').addEventListener('click', () =>
saveSession = true;
)
function start()
let button = document.getElementById('newGame');
button.addEventListener('click', startNewGame, false );
textMoves = document.getElementById('moves');
table = document.getElementById('table');
rows = 4;
columns = 4;
startNewGame();
function startNewGame()
let arrayOfNumbers = new Array();
let arrayHasNumberBeenUsed;
let randomNumber = 0;
let count = 0;
moves = 0;
rows = document.getElementById('rows').value;
columns = document.getElementById('columns').value;
textMoves.innerHTML = moves;
arrayForBoard = new Array(rows);
for (let i = 0; i < rows; i++)
arrayForBoard[i] = new Array(columns);
arrayHasNumberBeenUsed = new Array( rows * columns );
for (let i = 0; i < rows * columns; i++)
arrayHasNumberBeenUsed[i] = 0;
for (let i = 0; i < rows * columns; i++)
randomNumber = Math.floor(Math.random()*rows * columns);
if (arrayHasNumberBeenUsed[randomNumber] == 0)
arrayHasNumberBeenUsed[randomNumber] = 1;
arrayOfNumbers.push(randomNumber);
else
i--;
count = 0;
for (let i = 0; i < rows; i++)
for (let j = 0; j < columns; j++)
arrayForBoard[i][j] = arrayOfNumbers[count];
count++;
showTable();
function showTable()
for (let tr of document.querySelectorAll("#table tr"))
tr.remove();
let tbody = document.createElement('tbody');
document.querySelector('#table').appendChild(tbody);
for (let i = 0; i < rows; i++)
let tr = document.createElement('tr');
for (let j = 0; j < columns; j++)
let cell = document.createElement('td');
if (arrayForBoard[i][j] == 0)
cell.className = 'blank';
else
cell.className = 'tile';
cell.draggable = true;
cell.addEventListener('click', () =>
moveThisTile(i, j);
)
cell.innerHTML =arrayForBoard[i][j];
tr.appendChild(cell);
tbody.appendChild(tr);
if(saveSession)
saveElem('currentGame',tbody);
;
window.addEventListener('load', () =>
if(localStorage.getItem('currentGame') !== null)
const tbody = loadElem('currentGame');
document.querySelector('#table').appendChild(tbody);
else
start();
, false );
【讨论】:
以上是关于保存游戏(使用localStorage)并在重新加载页面后继续游戏的能力的主要内容,如果未能解决你的问题,请参考以下文章
HTML5 & Javascript Canvas 游戏 - 如何让玩家能够保存他们的游戏
vue 中使用vuex和localStorage保存登录状态
是否可以将 File 对象保存在 LocalStorage 中,然后当用户返回页面时通过 FileReader 重新加载文件?