奉贤青岛网站建设,wordpress更换链接自动跳转,钓鱼网站后台是怎么做的,小说网站静态页面模板一、游戏页面展示
开始游戏#xff1a; 游戏结束#xff1a; 二、游戏如何操作
通过监听键盘的操作#xff0c;进行移动变化
键盘上下左右键控制页面中所有模块同时向键入的方向移动#xff0c;如果有两块一样的方块#xff0c;就进行合并#xff0c;并且在键盘每操作…一、游戏页面展示
开始游戏 游戏结束 二、游戏如何操作
通过监听键盘的操作进行移动变化
键盘上下左右键控制页面中所有模块同时向键入的方向移动如果有两块一样的方块就进行合并并且在键盘每操作一次的同时会随机位置出现新的方块。
当所有的格子都有方块并且没有可以合并的方块时游戏结束
三、思路
游戏开始启动计时器创建棋盘数组用于存放棋子监听键盘操作合并棋子的同时随机生成新的棋子将棋子的状态事实更新在数组中当棋盘占满并且无棋子可以合并游戏结束将本局得分和游戏时间显示在排行榜中点击按钮可以再来一局。
四、代码部分
我们主要研究js部分所以html和css部分就不展开解释了js代码注释很全希望能方便你理解
代码背景比较浅有些代码颜色也比较浅我不知道怎么调你可以试试用鼠标选中它就能更清楚。代码如下
html
!DOCTYPE html
html langen
headmeta charsetUTF-8meta nameviewport contentwidthdevice-width, initial-scale1.0titleDocument/titlelink relstylesheet href./css/index.css/head
bodydiv classcontainerdiv classdirectionsh12048/h1pstrongHOW TO PLAY:/strong Use your arrow keys to move the tiles. When two tiles slide into each other,they merge into one!/p/divdiv classscoresdiv classscore-container best-scorebest:div classscorediv idbestScore0/div/div/divdiv classscore-containerscore:div classscorediv idscore0/divdiv classadd idadd/div/div/div/divdiv classgamediv idtile-container classtile-container/divdiv classend idendGame Overdiv classmonkey/divbuttonclassbtn not-recommended__item js-restart-btn idtry-againTry Again/button/div/divdiv classnot-recommendedbutton classbtn not-recommended__item js-restart-btn idrestartRestart Game/buttonspan classnot-recommended__annotation/span/div/divscript src./js/index.js/script
/body
/html
css
/* 字体引入 */
import url(https://fonts.googleapis.com/css?familyArvo);/* 伪类表示文档树的根元素 */
/* 定义一些全局的变量 */
:root {/* 网格背景 */--gridBg: #8ca5a0;/* 格子颜色 */--color1: #c2bf1b;--color2: #EF476F;--color3: #0c6148;--color4: #b9543b;/* 背景颜色 *//* --placeholder-tile: #F8FFE5; */--placeholder-tile: #bce4e6;/* 字体颜色 */--font-color: #389989;/* 边框宽度 */--border-width: 7px;
}* {/* c3盒模型 */box-sizing: border-box;
}body,
html {/* 子绝父相 */position: relative;width: 100%;height: 100%;display: flex;/* 纵向排列 */flex-direction: column;font-family: Arvo, Helvetica, sans-serif;font-size: 12px;color: var(--font-color);background: var(--placeholder-tile);/* 不想显示滚动条 */overflow: hidden;
}/* 文字部分 */
.directions {padding: 2rem;border-top: 1px solid var(--gridBg);border-bottom: 1px solid var(--gridBg);
}
/* 整个容器 */
.container {margin: 0 auto;flex: 1;width: 100%;max-width: 550px;text-align: center;
}
/* 2048 */
.directions h1 {margin-top: -20px;
}
/* 游玩方法 */
.directions p {margin-top: -5px;
}
/* 得分部分的大盒子 */
.scores {display: flex;justify-content: center;
}
/* 得分部分的2个小盒子 */
.score-container {display: flex;justify-content: center;align-items: center;margin: 1.8rem;font-size: 1.2rem;line-height: 1;color: var(--font-color);
}
/* 最高得分 */
.score-container.best-score {color: var(--gridBg);
}.score {margin-left: 1rem;position: relative;font-weight: bold;font-size: 1.5rem;vertical-align: middle;text-align: right;
}
/* 游戏部分 */
.game {position: relative;margin: 0 auto;background: var(--gridBg);padding: var(--border-width);display: inline-block;border-radius: 3px;box-sizing: border-box;
}.tile-container {border-radius: 6px;position: relative;width: 400px;height: 400px;
}
/* */
.tile,
.background {display: block;color: var(--placeholder-tile);position: absolute;width: 100px;height: 100px;box-sizing: border-box;text-align: center;
}
/* */
.background {z-index: 1;text-align: center;border: var(--border-width) solid var(--gridBg);background-color: var(--placeholder-tile);
}.tile {opacity: 0;z-index: 2;background: var(--color1);color: #F8FFE5;display: flex;align-items: center;justify-content: center;font-size: 1.8rem;align-items: center;transition: 110ms ease-in-out;border-radius: 3px;border: var(--border-width) solid var(--gridBg);box-sizing: border-box;
}
/* 4分格子 */
.tile.tile--4 {background: var(--color2);color: #F8FFE5;
}
/* 8分格子 */
.tile.tile--8 {background: var(--color3);color: #F8FFE5;}
/* 16分格子 */
.tile.tile--16 {background: var(--color4);color: #F8FFE5;}
/* 32分格子 */
.tile.tile--32 {background: #FF6B81;color: #F8FFE5;}
/* 64分格子 */
.tile.tile--64 {background: #24B0BC;color: #F8FFE5;
}
/* 128分格子 */.tile.tile--128 {background: #11E2AE;color: #F8FFE5;
}
/* 256分格子 */
.tile.tile--256 {background: #FFD047;color: #F8FFE5;}
/* 512分格子 */
.tile.tile--512 {background: #E53B5A;color: #F8FFE5;
}
/* 1024分格子 */.tile.tile--1024 {background: #147B8B;color: #F8FFE5;
}
/* 2048分格子 */
.tile.tile--2048 {background: #05B48A;color: #F8FFE5;
}
/* 增加盒子 */
.tile.tile--pop {animation: pop 0.3s ease-in-out;animation-fill-mode: forwards;
}
/* 减少盒子 */
.tile.tile--shrink {animation: shrink 0.5s ease-in-out;animation-fill-mode: forwards;
}
/* 计算积分 */
.add {position: absolute;opacity: 0;left: 120%;top: 0;font-size: 1rem;color: var(--color3);
}
/* 计算积分的运动 */
.add.active {animation: add 0.8s ease-in-out;
}
/* 算积分动画 */
keyframes add {0% {opacity: 1;top: 0;}100% {opacity: 0;top: -100%;}
}
/* 减少盒子动画 */
keyframes pop {0% {transform: scale(0.5);opacity: 0;}90% {transform: scale(1.1);opacity: 1;}100% {transform: scale(1);opacity: 1;}
}
/* 减少盒子动画 */
keyframes shrink {0% {transform: scale(1);opacity: 1;}100% {transform: scale(0.9);opacity: 0.9;}
}
/* 结束页面 */
.end {opacity: 0;position: absolute;top: 0;left: 0;width: 100%;height: 100%;/* 默认不显示 */z-index: -1;display: flex;flex-direction: column;justify-content: center;align-items: center;background: rgba(85, 85, 85, 0.9);color: white;font-size: 2rem;transition: opacity 0.3s ease-in-out;
}
/* 再来一局按钮 */
.end btn {margin-top: 1rem;
}
/* 结束页面出现 */
.end.active {opacity: 1;z-index: 1000;
}
/* 猴子图标 */
.monkey {font-size: 3rem;margin: 1rem 0;
}
/* 开始按钮 */
.btn {font-family: inherit;font-size: 1rem;border: none;background: var(--color3);letter-spacing: 1px;color: white;font-weight: 300;padding: 0.9em 1.5em;border-radius: 3px;border: 1px solid transparent;cursor: pointer;
}
/* 按钮悬浮时 */
.btn:hover {background-color: #137a8b;}
/* 按钮点击时 */
.btn:active {background-color: #0e5f6e;}
/* 按钮获得焦点时 */
.btn:focus {box-shadow: 0 0 10px #0e5f6e inset;outline: none;
}
/* 底部 */
.not-recommended {display: flex;justify-content: center;align-items: center;margin-top: 3rem;
}
/* 表情位置 */
.not-recommended__annotation {margin-left: 10px;
}
/* 四种状态表情 */
.not-recommended__item.not-recommended__annotation:before {font-size: 30px;content: ;
}.not-recommended__item:hover.not-recommended__annotation:before {content: ;
}.not-recommended__item:focus.not-recommended__annotation:before {content: ;
}.not-recommended__item:active.not-recommended__annotation:before {content: ;
}
js
这部分我们按照功能的不同来划分模块
页面更新和绘制模块
// 页面更新和绘制
// 引出类
export class DOMManager {// 构造函数constructor() {// 显示棋盘的容器this.tileContainer document.getElementById(tile-container);// 游戏结束画面this.endDiv document.getElementById(end);// 棋盘大小为4x4this.size 4;}
// 绘制棋盘背景drawBackground() {// 清空棋盘的内容this.tileContainer.innerHTML ;// 遍历每一个格子for (let i 0; i this.size * this.size; i) {// 创建divconst tileDiv document.createElement(div);// 将一维索引i转换为二维坐标const [x, y] [i % this.size, Math.floor(i / this.size)];// 创建的div的大小tileDiv.style.top ${y * 100}px;tileDiv.style.left ${x * 100}px;// div设置背景添加背景类tileDiv.classList.add(background);// 将格子元素添加到棋盘容器中this.tileContainer.appendChild(tileDiv);}}
// 定位棋子positionTile(tile, elm) {// 将棋子的索引转换为二维坐标const [x, y] [tile.index % this.size, Math.floor(tile.index / this.size)];// 根据坐标设置棋子的位置elm.style.top ${y * 100}px;elm.style.left ${x * 100}px;}
// 画棋子drawGame(tiles, isNew) {// 遍历棋子数组for (const tile of tiles) {// 如果棋子存在if (tile) {// 如果是新棋子if (isNew) {// 创建一个新的div元素const tileDiv document.createElement(div);// 调用positiontile方法设置棋子位置this.positionTile(tile, tileDiv);// 棋子添加类设置样式tileDiv.classList.add(tile, tile--${tile.value});// 设置棋子idtileDiv.id tile.id;// 添加动画实现按钮弹出效果setTimeout(() {tileDiv.classList.add(tile--pop);}, tile.mergedIds ? 1 : 150);// 设置棋子的值tileDiv.innerHTML p${tile.value}/p;// 将棋子元素添加到棋盘容器中this.tileContainer.appendChild(tileDiv);} else {//如果棋子已经存在获取棋子对应dom元素const currentElement document.getElementById(tile.id);// 调用方法更新棋子位置this.positionTile(tile, currentElement);}}}}
// 更新domupdateDOM(before, after) {// 获取新生成的棋子const newElements this.getNewElementsDOM(before, after);// 获取已经存在的棋子const existingElements this.getExistingElementsDOM(before, after);// 获取合并后的棋子const mergedTiles this.getMergedTiles(after);// 移除合并后的旧棋子this.removeElements(mergedTiles);// 绘制新棋子this.drawGame(newElements, true);// 更新已存在的棋子的位置this.drawGame(existingElements);}
// 移除合并的棋子removeElements(mergedTiles) {// 遍历合并后的棋子for (const tile of mergedTiles) {// 遍历合并后的棋子的id列表for (const id of tile.mergedIds) {// 获取对应dom元素const currentElm document.getElementById(id);// 更新棋子的位置this.positionTile(tile, currentElm);// 添加缩小动画类currentElm.classList.add(tile--shrink);// 延时移除棋子元素setTimeout(() {currentElm.remove();}, 100);}}}
// 获取合并后的棋子getMergedTiles(after) {// 过滤出after数组中包含mergedIds的棋子表示这些棋子是通过合并生成的return after.filter(tile tile tile.mergedIds);}
// 获取新生成的棋子getNewElementsDOM(before, after) {// 获取before数组中所有棋子的idconst beforeIds before.filter(tile tile).map(tile tile.id);// 过滤出after数组不再beforeIds中的棋子表示新生成的棋子const newElements after.filter(tile tile !beforeIds.includes(tile.id));// 返回新棋子数组return newElements;}
// 获取已经存在的棋子getExistingElementsDOM(before, after) {// 获取before数组中所有棋子的idconst beforeIds before.filter(tile tile).map(tile tile.id);// 过滤出 after 数组中在 beforeIds 中的棋子表示已存在的棋子const existingElements after.filter(tile tile beforeIds.includes(tile.id));// 返回已存在的棋子数组return existingElements;}
// 游戏结束画面showGameOver() {// 延时800毫秒之后为游戏结束画面的dom元素添加active类显示游戏结束画面setTimeout(() {this.endDiv.classList.add(active);}, 800);}
}
游戏棋盘状态模块
// 游戏棋盘状态
// 导出类
export class GameBoard {// 构造函数constructor(size 4) {this.size size;// 创建一个长度为size*size的一维数组,初始值为null,表示空格this.game Array.from({ length: size * size }, () null);// 初始化一个id计数器,用于为新生成的数字分配唯一标识符this.nextId 1;}
// 初始化游戏棋盘initGame() {// 重新初始化棋盘状态,将所有格子设置为null,表示清空棋盘this.game Array.from({ length: this.size * this.size }, () null);}
// 获取空格的索引getEmptyCells() {return this.game.map((_, index) index).filter(index this.game[index] null);}
// 随机生成数字addRandomNumber() {// 获取所有空格的索引const emptyCells this.getEmptyCells();// 如果没有空格,直接返回if (emptyCells.length 0) return;// 随机选择一个空格的索引const newPos emptyCells[Math.floor(Math.random() * emptyCells.length)];// 创建一个新对象,包含,唯一标识符id,新数字的位置,新数字的值const newObj {id: this.nextId,index: newPos,value: this.generateNewNumber()};// 将新数字放置到棋盘的指定位置this.game[newPos] newObj;}
// 生成新数字的值generateNewNumber() {return Math.random() * 100 90 ? 2 : 4;}
// 根据坐标获取索引getIndexForPoint(x, y) {return y * this.size x;}// 水平翻转棋盘reflectGrid(grid) {let reflectedGame Array.from({ length: this.size * this.size }, () 0);for (let row 0; row this.size; row) {for (let col 0; col this.size; col) {const index1 this.getIndexForPoint(col, row);const index2 this.getIndexForPoint(this.size - col - 1, row);reflectedGame[index1] grid[index2];}}return reflectedGame;}
// 逆时针旋转棋盘90度rotateLeft90Deg(grid) {let rotatedGame Array.from({ length: this.size * this.size }, () 0);for (let row 0; row this.size; row) {for (let col 0; col this.size; col) {const index1 this.getIndexForPoint(col, row);const index2 this.getIndexForPoint(this.size - 1 - row, col);rotatedGame[index1] grid[index2];}}return rotatedGame;}
// 顺时针90rotateRight90Deg(grid) {let rotatedGame Array.from({ length: this.size * this.size }, () 0);for (let row 0; row this.size; row) {for (let col 0; col this.size; col) {const index1 this.getIndexForPoint(col, row);const index2 this.getIndexForPoint(row, this.size - 1 - col);rotatedGame[index1] grid[index2];}}return rotatedGame;}
}
游戏控制模块
// 游戏控制模块
import { GameBoard } from ./GameBoard.js;
import { ScoreManager } from ./ScoreManager.js;
import { DOMManager } from ./DOMManager.js;
import { LeaderboardManager } from ./LeaderboardManager.js;
// 导出游戏控制类
export class GameController {// 构造函数constructor() {// 创建实例// 创建一个gameboard实例管理游戏棋盘this.gameBoard new GameBoard();// 。。。管理游戏分数this.scoreManager new ScoreManager();//。。。操作domthis.domManager new DOMManager();// 。。。管理排行榜this.leaderboardManager new LeaderboardManager();// 获取页面中显示时间的元素this.timerElement document.getElementById(timer);//游戏开始时间this.startTime null;this.timerInterval null;// 初始化一个标志位用来标记游戏结果是否已经提交到排行榜防止一条数据因为键盘多按了几下就重复提交this.resultSubmitted false;// 调用排行榜管理器的renderleaderboard方法渲染排行榜this.leaderboardManager.renderLeaderboard();// 初始化游戏方法this.initGame();// 事件监听器this.addEventListeners();}
// 初始化游戏方法initGame() {// 初始化棋盘状态this.gameBoard.initGame();// 重置当前分数this.scoreManager.resetScore();// 初始化最高分this.scoreManager.initBestScore();// 绘制游戏背景this.domManager.drawBackground();// 复制当前状态到previousgame用于后续比较------?const previousGame [...this.gameBoard.game];// 随机生成两个数字this.gameBoard.addRandomNumber();this.gameBoard.addRandomNumber();// 更新棋盘显示this.domManager.updateDOM(previousGame, this.gameBoard.game);// 启动计时器this.startTimer();// 提交标志位重置为falsethis.resultSubmitted false;}
// 启动计时器startTimer() {// 记录当前时间毫秒this.startTime Date.now();// 定时器每秒计算一下现在的时间距离开始时间过了多久this.timerInterval setInterval(() {const elapsedTime Date.now() - this.startTime;const seconds Math.floor(elapsedTime / 1000);this.timerElement.textContent 时长: ${seconds} 秒;}, 1000);}// 停止计时stopTimer() {// 如果正在计时if (this.timerInterval) {// 清除计时器clearInterval(this.timerInterval);// 计时器设值为null计时器已经停止this.timerInterval null;}}
// 添加事件监听器addEventListeners() {// 两个按钮const buttons document.querySelectorAll(.js-restart-btn);// 两个按钮都执行下面的方法// 添加点击监听buttons.forEach(button {// 点击按钮开启新游戏button.addEventListener(click, () this.newGameStart());});// bind绑定this传入的第一个数就是this的值其他的是函数参数document.addEventListener(keydown, this.handleKeypress.bind(this));}// 处理键盘事件handleKeypress(evt) {// 特殊键const modifiers evt.altKey || evt.ctrlKey || evt.metaKey || evt.shiftKey;// 如果不是特殊键就执行这个方法if (!modifiers) {// 仅处理上下左右键const validKeys [37, 38, 39, 40];// 如果数组中不包含事件的键码就退出当前的执行if (!validKeys.includes(evt.which)) {return;}// 阻止事件的默认行为evt.preventDefault();// 复制当前棋盘状态用于后续比较const prevGame [...this.gameBoard.game];// 判断按下的是哪个键switch (evt.which) {// 左case 37:// 调用滑动方法// ----this.gameBoard.game this.shiftGameLeft(this.gameBoard.game);break;// 上case 38:this.gameBoard.game this.shiftGameUp(this.gameBoard.game);break;// 右case 39:this.gameBoard.game this.shiftGameRight(this.gameBoard.game);break;// 下case 40:this.gameBoard.game this.shiftGameDown(this.gameBoard.game);break;}// 更新棋盘状态为每个数字添加索引this.gameBoard.game this.gameBoard.game.map((tile, index) tile ? { ...tile, index } : null);// 如果棋盘状态未改变则直接返回if (this.arrayEqual(prevGame, this.gameBoard.game)) return;// 在棋盘上随机生成一个新的数字this.gameBoard.addRandomNumber();// 更新dom显式this.domManager.updateDOM(prevGame, this.gameBoard.game);// 检查游戏是否结束if (this.gameOver()) {// 显示结束画面this.domManager.showGameOver();// 计时停止this.stopTimer();// 结果提交到排行榜this.submitGameResult();return;}}}
// 查看棋盘状态有没有变化通过比较数组是否相等来判断arrayEqual(arr1, arr2) {// 如果两个数组是同一个引用就返回trueif (arr1 arr2) return true;// 如果两个数组的长度不同就返回falseif (arr1.length ! arr2.length) return false;// 遍历数组的每个元素// ---for (let i 0; i arr1.length; i) {if (Array.isArray(arr1[i]) Array.isArray(arr2[i])) {if (!this.arrayEqual(arr1[i], arr2[i])) return false;} else if (arr1[i] ! arr2[i]) {return false;}}return true;}
// 重新开始游戏newGameStart() {// 清空棋盘的内容this.domManager.tileContainer.innerHTML ;// 去掉游戏结束的画面this.domManager.endDiv.classList.remove(active);// 停止计时器---this.stopTimer();// 重新初始化游戏状态this.initGame();}
// 检查游戏是否结束gameOver() {// 如果棋盘上还有空格if (this.gameBoard.getEmptyCells().length 0) {// 检查是否存在相邻的格子可以合并const sameNeighbors this.gameBoard.game.find((tile, i) {// 检查右侧是否有相同数字// -----const isRightSame this.gameBoard.game[i 1] (i 1) % 4 ! 0 ? tile.value this.gameBoard.game[i 1].value : false;// 检测下方是否有相同数字const isDownSame this.gameBoard.game[i 4] ? tile.value this.gameBoard.game[i 4].value : false;// 如果有可以合并的格子就返回truereturn isRightSame || isDownSame;});// 没有可以合并的数字,返回true游戏结束return !sameNeighbors;}return false;}
// 格子右移shiftGameRight(gameGrid) {// 将棋盘水平翻转let reflectedGame this.gameBoard.reflectGrid(gameGrid);reflectedGame this.shiftGameLeft(reflectedGame);// 再次翻转,恢复到原来return this.gameBoard.reflectGrid(reflectedGame);}
// 格子左移shiftGameLeft(gameGrid) {let newGameState [];let totalAdd 0;for (let i 0; i this.gameBoard.size; i) {const firstPos 4 * i;const lastPos (this.gameBoard.size) 4 * i;const currentRow gameGrid.slice(firstPos, lastPos);const filteredRow currentRow.filter(row row);for (const row of filteredRow) {delete row.mergedIds;}for (let j 0; j filteredRow.length - 1; j) {if (filteredRow[j].value filteredRow[j 1].value) {const sum filteredRow[j].value * 2;filteredRow[j] {id: this.gameBoard.nextId,mergedIds: [filteredRow[j].id, filteredRow[j 1].id],value: sum};filteredRow.splice(j 1, 1);totalAdd sum;}}while (filteredRow.length this.gameBoard.size) {filteredRow.push(null);}newGameState [...newGameState, ...filteredRow];}if (totalAdd 0) {this.scoreManager.updateScore(totalAdd);}return newGameState;}
// 格子上移shiftGameUp(gameGrid) {let rotatedGame this.gameBoard.rotateLeft90Deg(gameGrid);rotatedGame this.shiftGameLeft(rotatedGame);return this.gameBoard.rotateRight90Deg(rotatedGame);}
// 格子下移shiftGameDown(gameGrid) {let rotatedGame this.gameBoard.rotateRight90Deg(gameGrid);rotatedGame this.shiftGameLeft(rotatedGame);return this.gameBoard.rotateLeft90Deg(rotatedGame);}
// 提交结果submitGameResult() {// 检查结果是否已提交// 如果没有提交if (!this.resultSubmitted) {// 获取页面显示的时间文本const timeText this.timerElement.textContent;
// 从时间文本中提取秒数const elapsedTime parseInt(timeText.match(/\d/)[0], 10);// 获取当前分数const score this.scoreManager.score;// 将分数和时间提交到排行榜this.leaderboardManager.addScore(score, elapsedTime);// 重新渲染排行榜this.leaderboardManager.renderLeaderboard();// 标记结果已提交this.resultSubmitted true;}}
}
排行榜模块
//排行榜
// 导出类
export class LeaderboardManager {// 构造函数constructor() {// 定义一个键名,用于在localStorage中存储排行榜数据this.leaderboardKey game2048Leaderboard;// 调用getLeaderboard方法,从localStorage中读取排行榜数据并将其存储在实例的leaderboard中this.leaderboard this.getLeaderboard();}
// 从localstorage中读取数据getLeaderboard() {// 从 localStorage 中获取存储的排行榜数据const leaderboardData localStorage.getItem(this.leaderboardKey);// 如果数据存在则将其从 JSON 格式解析为 JavaScript 对象如果数据不存在则返回一个空数组表示排行榜为空return leaderboardData ? JSON.parse(leaderboardData) : [];}
// 保存排行榜数据到saveLeaderboard() {// 将当前的排行榜数据this.leaderboard转换为 JSON 格式并存储到 localStorage 中localStorage.setItem(this.leaderboardKey, JSON.stringify(this.leaderboard));}
// 添加新的分数到排行榜addScore(score, time) {// 检查新分数是否已经存在于排行榜const isScoreExists this.leaderboard.some(entry entry.score score entry.time time);// 如果记录不存在if (!isScoreExists) {// 将新的分数和时间记录添加到排行榜数组中this.leaderboard.push({ score, time });// 根据分数从高到低对排行榜进行排序this.leaderboard.sort((a, b) b.score - a.score);// 将更新后的排行榜保存到Localstorage中this.saveLeaderboard();}}
// 渲染排行榜到页面renderLeaderboard() {// 获取排行榜元素const leaderboardElement document.getElementById(leaderboard);// 清空排行榜容器的内容leaderboardElement.innerHTML ;// 创建一个表格行用于显示排行榜的表头const headerRow document.createElement(tr);// 创建一个表头单元格显示排名const rankHeader document.createElement(th);rankHeader.textContent 排名;// 创建一个表头单元格显示分数const scoreHeader document.createElement(th);scoreHeader.textContent 分数;// 创建一个表头单元格显示时长const timeHeader document.createElement(th);timeHeader.textContent 时长;// 将表头单元格添加到表头行中headerRow.appendChild(rankHeader);headerRow.appendChild(scoreHeader);headerRow.appendChild(timeHeader);// 将表头行添加到排行榜容器中leaderboardElement.appendChild(headerRow);
// 遍历排行榜数组为每一项都创建一个表格行this.leaderboard.forEach((entry, index) {const row document.createElement(tr);const rankCell document.createElement(td);rankCell.textContent index 1;const scoreCell document.createElement(td);scoreCell.textContent entry.score;const timeCell document.createElement(td);timeCell.textContent ${entry.time} 秒;
// 将单元格添加到表格中row.appendChild(rankCell);row.appendChild(scoreCell);row.appendChild(timeCell);// 将表格行添加到排行榜容器中leaderboardElement.appendChild(row);});}
}
得分模块
// 本局得分和最高分
export class ScoreManager {// 构造函数constructor() {// 初始化当前得分this.score 0;// 从localstorage中读取最高分如果不存在就默认为0// this.bestScore localStorage.getItem(bestScore) || 0;// 获取页面中用于显示当前得分的元素this.scoreDiv document.getElementById(score);// 获取页面中用于显示最高得分的元素this.bestScoreDiv document.getElementById(bestScore);// 获取页面中用于显示加分动画的元素this.addDiv document.getElementById(add);}
// 初始化最高分initBestScore() {// 从localstorage中读取最高分如果不存在就默认为0this.bestScore localStorage.getItem(bestScore) || 0;// 将最高分显示在页面上this.bestScoreDiv.textContent this.bestScore;}
// 更新得分updateScore(totalAdd) {// 将新增分数加到当前得分上this.score totalAdd;// 更新页面上显示的当前得分this.scoreDiv.textContent this.score;// 在加分动画中显示新增分数this.addDiv.textContent ${totalAdd};// 为加分动画添加active类触发css动画this.addDiv.classList.add(active);// 延时800毫秒后移除active动画结束setTimeout(() {this.addDiv.classList.remove(active);}, 800);// 如果当前得分超过最高得分将当前得分保存为最高得分if (this.score this.bestScore) {localStorage.setItem(bestScore, this.score);// 更新页面上显示的最高得分this.initBestScore();}}
// 重置得分resetScore() {// 当前得分为0this.score 0;// 更新页面显示的当前得分this.scoreDiv.textContent this.score;}
}
主函数模块
// 创建实例启动游戏
// 引入游戏控制类
import { GameController } from ./GameController.js;
// 创建游戏实例
const gameInstance new GameController();
如果你有更简单的方法可以和我交流一下因为是初学者所以可能有写的不对的地方请指正。