在某些特殊的场合之下,比如没有网络的大兴安岭,克拉玛利,比如不允许上网的某些研究所,比如在飞机上。那么我们如何连接热点,上网连线一款游戏解闷呢?前些天本人收到了dfrobot寄来的Firebbetle Esp32-C5试用板,心想刚好可以利用其自带的wifi以及http功能,将其作为微型服务器,利用Ap模式发出局域网热点信号,连接热点访问其中的小游戏。

废话不说,先上效果

目前只需要连接ESP32的wifi热点,以及输入密码12345678就可以啦。下面有四个方向箭,点击就可以实现对于2048小游戏的控制。得益于esp32c5的优越性能,目前游玩过程很流畅,也很顺利。如果有多人接入,只需要避免同时一次性大量访问就好。
视频演示

当然由于是试用版的缘故,以及科学上网变得更加困难,折腾了一段时间,开发板具体的使用方法是,下载Arduino2.3.6,将
附件当中的json文件保存到下面的文件夹下,注意将原来的package_index.json删除,将这个json重命名为package_index.json。注意arduino当中文件-首选项-其余开发板链接当中的链接全部删除,然后再打开arduino,选择esp32 espress的下面的3.3.0-alpha-cn进行开发

arduino源代码展示如下
- #include <WiFi.h>
- #include <WebServer.h>
-
- /* Put your SSID & Password */
- const char* ssid = "ESP32"; // Enter SSID here
- const char* password = "12345678"; // Enter Password here
-
- /* Put IP Address details */
- IPAddress local_ip(192,168,1,1);
- IPAddress gateway(192,168,1,1);
- IPAddress subnet(255,255,255,0);
-
- WebServer server(80);
-
- void setup()
- {
- Serial.begin(115200);
-
- WiFi.softAP(ssid, password);
- WiFi.softAPConfig(local_ip, gateway, subnet);
- delay(100);
-
- server.on("/", handle_on_connect);
- server.onNotFound(handle_not_found);
-
- server.begin();
- Serial.println("HTTP server started");
- }
-
- void loop()
- {
- server.handleClient();
- }
-
- void handle_on_connect()
- {
- Serial.println("Client connected");
- server.send(200, "text/html", send_2048_html());
- }
-
- void handle_not_found()
- {
- server.send(404, "text/plain", "Not found");
- }
-
- String send_2048_html()
- {
- String ptr = "<!DOCTYPE html>\n";
- ptr += "<html lang='zh'>\n";
- ptr += "<head>\n";
- ptr += " <meta charset='UTF-8'>\n";
- ptr += " <meta name='viewport' content='width=device-width, initial-scale=1.0, user-scalable=no'>\n";
- ptr += " <title>ESP32 2048游戏</title>\n";
- ptr += " <style>\n";
- ptr += " body {\n";
- ptr += " font-family: Arial, sans-serif;\n";
- ptr += " text-align: center;\n";
- ptr += " background-color: #faf8ef;\n";
- ptr += " margin: 0;\n";
- ptr += " padding: 20px;\n";
- ptr += " }\n";
- ptr += " h1 {\n";
- ptr += " color: #776e65;\n";
- ptr += " font-size: 28px;\n";
- ptr += " margin-bottom: 10px;\n";
- ptr += " }\n";
- ptr += " .game-container {\n";
- ptr += " display: flex;\n";
- ptr += " flex-direction: column;\n";
- ptr += " align-items: center;\n";
- ptr += " margin-top: 20px;\n";
- ptr += " }\n";
- ptr += " .game-header {\n";
- ptr += " display: flex;\n";
- ptr += " justify-content: space-between;\n";
- ptr += " width: 300px;\n";
- ptr += " margin-bottom: 20px;\n";
- ptr += " }\n";
- ptr += " .score-container {\n";
- ptr += " background: #bbada0;\n";
- ptr += " padding: 10px 15px;\n";
- ptr += " border-radius: 5px;\n";
- ptr += " color: white;\n";
- ptr += " font-weight: bold;\n";
- ptr += " text-align: center;\n";
- ptr += " min-width: 80px;\n";
- ptr += " }\n";
- ptr += " .score-title {\n";
- ptr += " font-size: 14px;\n";
- ptr += " color: #eee4da;\n";
- ptr += " }\n";
- ptr += " .score-value {\n";
- ptr += " font-size: 20px;\n";
- ptr += " }\n";
- ptr += " .grid-container {\n";
- ptr += " background-color: #bbada0;\n";
- ptr += " border-radius: 6px;\n";
- ptr += " width: 300px;\n";
- ptr += " height: 300px;\n";
- ptr += " padding: 10px;\n";
- ptr += " position: relative;\n";
- ptr += " box-sizing: border-box;\n";
- ptr += " }\n";
- ptr += " .grid-row {\n";
- ptr += " display: flex;\n";
- ptr += " margin-bottom: 10px;\n";
- ptr += " height: 65px;\n";
- ptr += " }\n";
- ptr += " .grid-row:last-child {\n";
- ptr += " margin-bottom: 0;\n";
- ptr += " }\n";
- ptr += " .grid-cell {\n";
- ptr += " width: 65px;\n";
- ptr += " height: 65px;\n";
- ptr += " margin-right: 10px;\n";
- ptr += " background-color: #cdc1b4;\n";
- ptr += " border-radius: 3px;\n";
- ptr += " display: flex;\n";
- ptr += " justify-content: center;\n";
- ptr += " align-items: center;\n";
- ptr += " font-size: 24px;\n";
- ptr += " font-weight: bold;\n";
- ptr += " color: #776e65;\n";
- ptr += " }\n";
- ptr += " .grid-cell:last-child {\n";
- ptr += " margin-right: 0;\n";
- ptr += " }\n";
- ptr += " .tile-2 { background-color: #eee4da; }\n";
- ptr += " .tile-4 { background-color: #ede0c8; }\n";
- ptr += " .tile-8 { background-color: #f2b179; color: #f9f6f2; }\n";
- ptr += " .tile-16 { background-color: #f59563; color: #f9f6f2; }\n";
- ptr += " .tile-32 { background-color: #f67c5f; color: #f9f6f2; }\n";
- ptr += " .tile-64 { background-color: #f65e3b; color: #f9f6f2; }\n";
- ptr += " .tile-128 { background-color: #edcf72; color: #f9f6f2; font-size: 20px; }\n";
- ptr += " .tile-256 { background-color: #edcc61; color: #f9f6f2; font-size: 20px; }\n";
- ptr += " .tile-512 { background-color: #edc850; color: #f9f6f2; font-size: 20px; }\n";
- ptr += " .tile-1024 { background-color: #edc53f; color: #f9f6f2; font-size: 16px; }\n";
- ptr += " .tile-2048 { background-color: #edc22e; color: #f9f6f2; font-size: 16px; }\n";
- ptr += " .controls {\n";
- ptr += " margin-top: 20px;\n";
- ptr += " }\n";
- ptr += " .btn {\n";
- ptr += " background-color: #8f7a66;\n";
- ptr += " color: white;\n";
- ptr += " border: none;\n";
- ptr += " border-radius: 5px;\n";
- ptr += " padding: 10px 20px;\n";
- ptr += " font-weight: bold;\n";
- ptr += " cursor: pointer;\n";
- ptr += " margin: 5px;\n";
- ptr += " }\n";
- ptr += " .btn:hover {\n";
- ptr += " background-color: #7c6957;\n";
- ptr += " }\n";
- ptr += " .game-message {\n";
- ptr += " display: none;\n";
- ptr += " position: absolute;\n";
- ptr += " top: 0;\n";
- ptr += " left: 0;\n";
- ptr += " right: 0;\n";
- ptr += " bottom: 0;\n";
- ptr += " background: rgba(238, 228, 218, 0.73);\n";
- ptr += " z-index: 100;\n";
- ptr += " flex-direction: column;\n";
- ptr += " align-items: center;\n";
- ptr += " justify-content: center;\n";
- ptr += " border-radius: 6px;\n";
- ptr += " color: #776e65;\n";
- ptr += " font-weight: bold;\n";
- ptr += " font-size: 30px;\n";
- ptr += " }\n";
- ptr += " .game-message.game-won {\n";
- ptr += " background: rgba(237, 194, 46, 0.5);\n";
- ptr += " color: #f9f6f2;\n";
- ptr += " }\n";
- ptr += " .game-message p {\n";
- ptr += " margin: 0;\n";
- ptr += " margin-bottom: 20px;\n";
- ptr += " }\n";
- ptr += " .swipe-controls {\n";
- ptr += " display: flex;\n";
- ptr += " flex-wrap: wrap;\n";
- ptr += " justify-content: center;\n";
- ptr += " margin-top: 20px;\n";
- ptr += " }\n";
- ptr += " .swipe-btn {\n";
- ptr += " width: 80px;\n";
- ptr += " height: 80px;\n";
- ptr += " margin: 5px;\n";
- ptr += " font-size: 30px;\n";
- ptr += " background-color: #bbada0;\n";
- ptr += " color: white;\n";
- ptr += " border: none;\n";
- ptr += " border-radius: 5px;\n";
- ptr += " display: flex;\n";
- ptr += " justify-content: center;\n";
- ptr += " align-items: center;\n";
- ptr += " cursor: pointer;\n";
- ptr += " }\n";
- ptr += " .swipe-btn:active {\n";
- ptr += " background-color: #8f7a66;\n";
- ptr += " }\n";
- ptr += " .footer {\n";
- ptr += " margin-top: 30px;\n";
- ptr += " font-size: 14px;\n";
- ptr += " color: #776e65;\n";
- ptr += " }\n";
- ptr += " </style>\n";
- ptr += "</head>\n";
- ptr += "<body>\n";
- ptr += " <h1>ESP32 2048游戏</h1>\n";
- ptr += " <div class='game-container'>\n";
- ptr += " <div class='game-header'>\n";
- ptr += " <div class='score-container'>\n";
- ptr += " <div class='score-title'>分数</div>\n";
- ptr += " <div id='score' class='score-value'>0</div>\n";
- ptr += " </div>\n";
- ptr += " <div class='score-container'>\n";
- ptr += " <div class='score-title'>最高分</div>\n";
- ptr += " <div id='best-score' class='score-value'>0</div>\n";
- ptr += " </div>\n";
- ptr += " </div>\n";
- ptr += " <div class='grid-container'>\n";
- ptr += " <div id='game-message' class='game-message'>\n";
- ptr += " <p></p>\n";
- ptr += " <button id='retry-btn' class='btn'>再试一次</button>\n";
- ptr += " </div>\n";
- ptr += " <div class='grid-row'>\n";
- ptr += " <div id='cell-0-0' class='grid-cell'></div>\n";
- ptr += " <div id='cell-0-1' class='grid-cell'></div>\n";
- ptr += " <div id='cell-0-2' class='grid-cell'></div>\n";
- ptr += " <div id='cell-0-3' class='grid-cell'></div>\n";
- ptr += " </div>\n";
- ptr += " <div class='grid-row'>\n";
- ptr += " <div id='cell-1-0' class='grid-cell'></div>\n";
- ptr += " <div id='cell-1-1' class='grid-cell'></div>\n";
- ptr += " <div id='cell-1-2' class='grid-cell'></div>\n";
- ptr += " <div id='cell-1-3' class='grid-cell'></div>\n";
- ptr += " </div>\n";
- ptr += " <div class='grid-row'>\n";
- ptr += " <div id='cell-2-0' class='grid-cell'></div>\n";
- ptr += " <div id='cell-2-1' class='grid-cell'></div>\n";
- ptr += " <div id='cell-2-2' class='grid-cell'></div>\n";
- ptr += " <div id='cell-2-3' class='grid-cell'></div>\n";
- ptr += " </div>\n";
- ptr += " <div class='grid-row'>\n";
- ptr += " <div id='cell-3-0' class='grid-cell'></div>\n";
- ptr += " <div id='cell-3-1' class='grid-cell'></div>\n";
- ptr += " <div id='cell-3-2' class='grid-cell'></div>\n";
- ptr += " <div id='cell-3-3' class='grid-cell'></div>\n";
- ptr += " </div>\n";
- ptr += " </div>\n";
- ptr += " <div class='controls'>\n";
- ptr += " <button id='new-game-btn' class='btn'>新游戏</button>\n";
- ptr += " </div>\n";
- ptr += " <div class='swipe-controls'>\n";
- ptr += " <div style='width: 90px; height: 90px;'></div>\n";
- ptr += " <button id='up-btn' class='swipe-btn'>↑</button>\n";
- ptr += " <div style='width: 90px; height: 90px;'></div>\n";
- ptr += " <button id='left-btn' class='swipe-btn'>←</button>\n";
- ptr += " <div style='width: 90px; height: 90px;'></div>\n";
- ptr += " <button id='right-btn' class='swipe-btn'>→</button>\n";
- ptr += " <div style='width: 90px; height: 90px;'></div>\n";
- ptr += " <button id='down-btn' class='swipe-btn'>↓</button>\n";
- ptr += " <div style='width: 90px; height: 90px;'></div>\n";
- ptr += " </div>\n";
- ptr += " </div>\n";
- ptr += " <div class='footer'>\n";
- ptr += " <p>ESP32网页2048游戏 - 基于ESP32 Web Server</p>\n";
- ptr += " </div>\n";
-
- // 添加JavaScript代码
- ptr += " <script>\n";
- ptr += " // 游戏状态变量\n";
- ptr += " let grid = [\n";
- ptr += " [0, 0, 0, 0],\n";
- ptr += " [0, 0, 0, 0],\n";
- ptr += " [0, 0, 0, 0],\n";
- ptr += " [0, 0, 0, 0]\n";
- ptr += " ];\n";
- ptr += " let score = 0;\n";
- ptr += " let bestScore = 0;\n";
- ptr += " let gameOver = false;\n";
- ptr += " let gameWon = false;\n";
-
- ptr += " // DOM元素\n";
- ptr += " const scoreElement = document.getElementById('score');\n";
- ptr += " const bestScoreElement = document.getElementById('best-score');\n";
- ptr += " const gameMessageElement = document.getElementById('game-message');\n";
- ptr += " const newGameBtn = document.getElementById('new-game-btn');\n";
- ptr += " const retryBtn = document.getElementById('retry-btn');\n";
- ptr += " const upBtn = document.getElementById('up-btn');\n";
- ptr += " const leftBtn = document.getElementById('left-btn');\n";
- ptr += " const rightBtn = document.getElementById('right-btn');\n";
- ptr += " const downBtn = document.getElementById('down-btn');\n";
-
- ptr += " // 初始化游戏\n";
- ptr += " function initGame() {\n";
- ptr += " grid = [\n";
- ptr += " [0, 0, 0, 0],\n";
- ptr += " [0, 0, 0, 0],\n";
- ptr += " [0, 0, 0, 0],\n";
- ptr += " [0, 0, 0, 0]\n";
- ptr += " ];\n";
- ptr += " score = 0;\n";
- ptr += " gameOver = false;\n";
- ptr += " gameWon = false;\n";
- ptr += " scoreElement.textContent = '0';\n";
- ptr += " gameMessageElement.style.display = 'none';\n";
- ptr += " \n";
- ptr += " // 添加两个初始方块\n";
- ptr += " addRandomTile();\n";
- ptr += " addRandomTile();\n";
- ptr += " \n";
- ptr += " updateGrid();\n";
- ptr += " }\n";
-
- ptr += " // 更新网格显示\n";
- ptr += " function updateGrid() {\n";
- ptr += " for (let row = 0; row < 4; row++) {\n";
- ptr += " for (let col = 0; col < 4; col++) {\n";
- ptr += " const cell = document.getElementById(`cell-${row}-${col}`);\n";
- ptr += " const value = grid[row][col];\n";
- ptr += " \n";
- ptr += " // 清除所有类\n";
- ptr += " cell.className = 'grid-cell';\n";
- ptr += " cell.textContent = '';\n";
- ptr += " \n";
- ptr += " if (value !== 0) {\n";
- ptr += " cell.textContent = value;\n";
- ptr += " cell.classList.add(`tile-${value}`);\n";
- ptr += " }\n";
- ptr += " }\n";
- ptr += " }\n";
- ptr += " }\n";
-
- ptr += " // 添加随机方块\n";
- ptr += " function addRandomTile() {\n";
- ptr += " const emptyCells = [];\n";
- ptr += " \n";
- ptr += " // 找出所有空单元格\n";
- ptr += " for (let row = 0; row < 4; row++) {\n";
- ptr += " for (let col = 0; col < 4; col++) {\n";
- ptr += " if (grid[row][col] === 0) {\n";
- ptr += " emptyCells.push({ row, col });\n";
- ptr += " }\n";
- ptr += " }\n";
- ptr += " }\n";
- ptr += " \n";
- ptr += " // 如果有空单元格,随机选择一个并添加2或4\n";
- ptr += " if (emptyCells.length > 0) {\n";
- ptr += " const randomCell = emptyCells[Math.floor(Math.random() * emptyCells.length)];\n";
- ptr += " grid[randomCell.row][randomCell.col] = Math.random() < 0.9 ? 2 : 4;\n";
- ptr += " }\n";
- ptr += " }\n";
-
- ptr += " // 检查游戏是否结束\n";
- ptr += " function checkGameOver() {\n";
- ptr += " // 检查是否有空单元格\n";
- ptr += " for (let row = 0; row < 4; row++) {\n";
- ptr += " for (let col = 0; col < 4; col++) {\n";
- ptr += " if (grid[row][col] === 0) {\n";
- ptr += " return false;\n";
- ptr += " }\n";
- ptr += " }\n";
- ptr += " }\n";
- ptr += " \n";
- ptr += " // 检查是否有可合并的相邻单元格\n";
- ptr += " for (let row = 0; row < 4; row++) {\n";
- ptr += " for (let col = 0; col < 4; col++) {\n";
- ptr += " const value = grid[row][col];\n";
- ptr += " \n";
- ptr += " // 检查右侧\n";
- ptr += " if (col < 3 && grid[row][col + 1] === value) {\n";
- ptr += " return false;\n";
- ptr += " }\n";
- ptr += " \n";
- ptr += " // 检查下方\n";
- ptr += " if (row < 3 && grid[row + 1][col] === value) {\n";
- ptr += " return false;\n";
- ptr += " }\n";
- ptr += " }\n";
- ptr += " }\n";
- ptr += " \n";
- ptr += " return true;\n";
- ptr += " }\n";
-
- ptr += " // 检查是否获胜(达到2048)\n";
- ptr += " function checkWin() {\n";
- ptr += " for (let row = 0; row < 4; row++) {\n";
- ptr += " for (let col = 0; col < 4; col++) {\n";
- ptr += " if (grid[row][col] === 2048) {\n";
- ptr += " return true;\n";
- ptr += " }\n";
- ptr += " }\n";
- ptr += " }\n";
- ptr += " return false;\n";
- ptr += " }\n";
-
- ptr += " // 更新分数\n";
- ptr += " function updateScore(points) {\n";
- ptr += " score += points;\n";
- ptr += " scoreElement.textContent = score;\n";
- ptr += " \n";
- ptr += " if (score > bestScore) {\n";
- ptr += " bestScore = score;\n";
- ptr += " bestScoreElement.textContent = bestScore;\n";
- ptr += " localStorage.setItem('bestScore', bestScore);\n";
- ptr += " }\n";
- ptr += " }\n";
-
- ptr += " // 显示游戏结束或胜利消息\n";
- ptr += " function showGameMessage(won) {\n";
- ptr += " gameMessageElement.style.display = 'flex';\n";
- ptr += " gameMessageElement.querySelector('p').textContent = won ? '你赢了!' : '游戏结束!';\n";
- ptr += " if (won) {\n";
- ptr += " gameMessageElement.classList.add('game-won');\n";
- ptr += " } else {\n";
- ptr += " gameMessageElement.classList.remove('game-won');\n";
- ptr += " }\n";
- ptr += " }\n";
-
- ptr += " // 移动方向处理函数\n";
- ptr += " function move(direction) {\n";
- ptr += " if (gameOver || gameWon) return;\n";
- ptr += " \n";
- ptr += " let moved = false;\n";
- ptr += " \n";
- ptr += " // 创建网格副本用于比较\n";
- ptr += " const previousGrid = JSON.parse(JSON.stringify(grid));\n";
- ptr += " \n";
- ptr += " // 根据方向执行移动\n";
- ptr += " switch (direction) {\n";
- ptr += " case 'up':\n";
- ptr += " moved = moveUp();\n";
- ptr += " break;\n";
- ptr += " case 'right':\n";
- ptr += " moved = moveRight();\n";
- ptr += " break;\n";
- ptr += " case 'down':\n";
- ptr += " moved = moveDown();\n";
- ptr += " break;\n";
- ptr += " case 'left':\n";
- ptr += " moved = moveLeft();\n";
- ptr += " break;\n";
- ptr += " }\n";
- ptr += " \n";
- ptr += " // 如果有移动,添加新方块并更新网格\n";
- ptr += " if (moved) {\n";
- ptr += " addRandomTile();\n";
- ptr += " updateGrid();\n";
- ptr += " \n";
- ptr += " // 检查是否获胜\n";
- ptr += " if (checkWin()) {\n";
- ptr += " gameWon = true;\n";
- ptr += " showGameMessage(true);\n";
- ptr += " }\n";
- ptr += " // 检查是否游戏结束\n";
- ptr += " else if (checkGameOver()) {\n";
- ptr += " gameOver = true;\n";
- ptr += " showGameMessage(false);\n";
- ptr += " }\n";
- ptr += " }\n";
- ptr += " }\n";
-
- ptr += " // 向上移动\n";
- ptr += " function moveUp() {\n";
- ptr += " let moved = false;\n";
- ptr += " \n";
- ptr += " for (let col = 0; col < 4; col++) {\n";
- ptr += " // 合并相同的数字\n";
- ptr += " for (let row = 0; row < 3; row++) {\n";
- ptr += " if (grid[row][col] !== 0) {\n";
- ptr += " for (let nextRow = row + 1; nextRow < 4; nextRow++) {\n";
- ptr += " if (grid[nextRow][col] !== 0) {\n";
- ptr += " if (grid[row][col] === grid[nextRow][col]) {\n";
- ptr += " grid[row][col] *= 2;\n";
- ptr += " grid[nextRow][col] = 0;\n";
- ptr += " updateScore(grid[row][col]);\n";
- ptr += " moved = true;\n";
- ptr += " }\n";
- ptr += " break;\n";
- ptr += " }\n";
- ptr += " }\n";
- ptr += " }\n";
- ptr += " }\n";
- ptr += " \n";
- ptr += " // 移动所有方块\n";
- ptr += " for (let row = 0; row < 3; row++) {\n";
- ptr += " if (grid[row][col] === 0) {\n";
- ptr += " for (let nextRow = row + 1; nextRow < 4; nextRow++) {\n";
- ptr += " if (grid[nextRow][col] !== 0) {\n";
- ptr += " grid[row][col] = grid[nextRow][col];\n";
- ptr += " grid[nextRow][col] = 0;\n";
- ptr += " moved = true;\n";
- ptr += " row--; // 重新检查当前行\n";
- ptr += " break;\n";
- ptr += " }\n";
- ptr += " }\n";
- ptr += " }\n";
- ptr += " }\n";
- ptr += " }\n";
- ptr += " \n";
- ptr += " return moved;\n";
- ptr += " }\n";
-
- ptr += " // 向右移动\n";
- ptr += " function moveRight() {\n";
- ptr += " let moved = false;\n";
- ptr += " \n";
- ptr += " for (let row = 0; row < 4; row++) {\n";
- ptr += " // 合并相同的数字\n";
- ptr += " for (let col = 3; col > 0; col--) {\n";
- ptr += " if (grid[row][col] !== 0) {\n";
- ptr += " for (let prevCol = col - 1; prevCol >= 0; prevCol--) {\n";
- ptr += " if (grid[row][prevCol] !== 0) {\n";
- ptr += " if (grid[row][col] === grid[row][prevCol]) {\n";
- ptr += " grid[row][col] *= 2;\n";
- ptr += " grid[row][prevCol] = 0;\n";
- ptr += " updateScore(grid[row][col]);\n";
- ptr += " moved = true;\n";
- ptr += " }\n";
- ptr += " break;\n";
- ptr += " }\n";
- ptr += " }\n";
- ptr += " }\n";
- ptr += " }\n";
- ptr += " \n";
- ptr += " // 移动所有方块\n";
- ptr += " for (let col = 3; col > 0; col--) {\n";
- ptr += " if (grid[row][col] === 0) {\n";
- ptr += " for (let prevCol = col - 1; prevCol >= 0; prevCol--) {\n";
- ptr += " if (grid[row][prevCol] !== 0) {\n";
- ptr += " grid[row][col] = grid[row][prevCol];\n";
- ptr += " grid[row][prevCol] = 0;\n";
- ptr += " moved = true;\n";
- ptr += " col++; // 重新检查当前列\n";
- ptr += " break;\n";
- ptr += " }\n";
- ptr += " }\n";
- ptr += " }\n";
- ptr += " }\n";
- ptr += " }\n";
- ptr += " \n";
- ptr += " return moved;\n";
- ptr += " }\n";
-
- ptr += " // 向下移动\n";
- ptr += " function moveDown() {\n";
- ptr += " let moved = false;\n";
- ptr += " \n";
- ptr += " for (let col = 0; col < 4; col++) {\n";
- ptr += " // 合并相同的数字\n";
- ptr += " for (let row = 3; row > 0; row--) {\n";
- ptr += " if (grid[row][col] !== 0) {\n";
- ptr += " for (let prevRow = row - 1; prevRow >= 0; prevRow--) {\n";
- ptr += " if (grid[prevRow][col] !== 0) {\n";
- ptr += " if (grid[row][col] === grid[prevRow][col]) {\n";
- ptr += " grid[row][col] *= 2;\n";
- ptr += " grid[prevRow][col] = 0;\n";
- ptr += " updateScore(grid[row][col]);\n";
- ptr += " moved = true;\n";
- ptr += " }\n";
- ptr += " break;\n";
- ptr += " }\n";
- ptr += " }\n";
- ptr += " }\n";
- ptr += " }\n";
- ptr += " \n";
- ptr += " // 移动所有方块\n";
- ptr += " for (let row = 3; row > 0; row--) {\n";
- ptr += " if (grid[row][col] === 0) {\n";
- ptr += " for (let prevRow = row - 1; prevRow >= 0; prevRow--) {\n";
- ptr += " if (grid[prevRow][col] !== 0) {\n";
- ptr += " grid[row][col] = grid[prevRow][col];\n";
- ptr += " grid[prevRow][col] = 0;\n";
- ptr += " moved = true;\n";
- ptr += " row++; // 重新检查当前行\n";
- ptr += " break;\n";
- ptr += " }\n";
- ptr += " }\n";
- ptr += " }\n";
- ptr += " }\n";
- ptr += " }\n";
- ptr += " \n";
- ptr += " return moved;\n";
- ptr += " }\n";
-
- ptr += " // 向左移动\n";
- ptr += " function moveLeft() {\n";
- ptr += " let moved = false;\n";
- ptr += " \n";
- ptr += " for (let row = 0; row < 4; row++) {\n";
- ptr += " // 合并相同的数字\n";
- ptr += " for (let col = 0; col < 3; col++) {\n";
- ptr += " if (grid[row][col] !== 0) {\n";
- ptr += " for (let nextCol = col + 1; nextCol < 4; nextCol++) {\n";
- ptr += " if (grid[row][nextCol] !== 0) {\n";
- ptr += " if (grid[row][col] === grid[row][nextCol]) {\n";
- ptr += " grid[row][col] *= 2;\n";
- ptr += " grid[row][nextCol] = 0;\n";
- ptr += " updateScore(grid[row][col]);\n";
- ptr += " moved = true;\n";
- ptr += " }\n";
- ptr += " break;\n";
- ptr += " }\n";
- ptr += " }\n";
- ptr += " }\n";
- ptr += " }\n";
- ptr += " \n";
- ptr += " // 移动所有方块\n";
- ptr += " for (let col = 0; col < 3; col++) {\n";
- ptr += " if (grid[row][col] === 0) {\n";
- ptr += " for (let nextCol = col + 1; nextCol < 4; nextCol++) {\n";
- ptr += " if (grid[row][nextCol] !== 0) {\n";
- ptr += " grid[row][col] = grid[row][nextCol];\n";
- ptr += " grid[row][nextCol] = 0;\n";
- ptr += " moved = true;\n";
- ptr += " col--; // 重新检查当前列\n";
- ptr += " break;\n";
- ptr += " }\n";
- ptr += " }\n";
- ptr += " }\n";
- ptr += " }\n";
- ptr += " }\n";
- ptr += " \n";
- ptr += " return moved;\n";
- ptr += " }\n";
-
- // 修复事件***和初始化代码
- ptr += " // 加载最高分\n";
- ptr += " function loadBestScore() {\n";
- ptr += " const savedBestScore = localStorage.getItem('bestScore');\n";
- ptr += " if (savedBestScore) {\n";
- ptr += " bestScore = parseInt(savedBestScore);\n";
- ptr += " bestScoreElement.textContent = bestScore;\n";
- ptr += " }\n";
- ptr += " }\n";
-
- ptr += " // 事件***\n";
- ptr += " newGameBtn.addEventListener('click', initGame);\n";
- ptr += " retryBtn.addEventListener('click', initGame);\n";
- ptr += " upBtn.addEventListener('click', () => move('up'));\n";
- ptr += " rightBtn.addEventListener('click', () => move('right'));\n";
- ptr += " downBtn.addEventListener('click', () => move('down'));\n";
- ptr += " leftBtn.addEventListener('click', () => move('left'));\n";
-
- ptr += " // 键盘控制\n";
- ptr += " document.addEventListener('keydown', (e) => {\n";
- ptr += " if (gameOver || gameWon) return;\n";
- ptr += " \n";
- ptr += " switch (e.key) {\n";
- ptr += " case 'ArrowUp':\n";
- ptr += " move('up');\n";
- ptr += " break;\n";
- ptr += " case 'ArrowRight':\n";
- ptr += " move('right');\n";
- ptr += " break;\n";
- ptr += " case 'ArrowDown':\n";
- ptr += " move('down');\n";
- ptr += " break;\n";
- ptr += " case 'ArrowLeft':\n";
- ptr += " move('left');\n";
- ptr += " break;\n";
- ptr += " }\n";
- ptr += " });\n";
-
- ptr += " // 触摸控制\n";
- ptr += " let touchStartX = 0;\n";
- ptr += " let touchStartY = 0;\n";
- ptr += " let touchEndX = 0;\n";
- ptr += " let touchEndY = 0;\n";
-
- ptr += " document.addEventListener('touchstart', (e) => {\n";
- ptr += " touchStartX = e.touches[0].clientX;\n";
- ptr += " touchStartY = e.touches[0].clientY;\n";
- ptr += " }, false);\n";
-
- ptr += " document.addEventListener('touchend', (e) => {\n";
- ptr += " if (gameOver || gameWon) return;\n";
- ptr += " \n";
- ptr += " touchEndX = e.changedTouches[0].clientX;\n";
- ptr += " touchEndY = e.changedTouches[0].clientY;\n";
- ptr += " \n";
- ptr += " const deltaX = touchEndX - touchStartX;\n";
- ptr += " const deltaY = touchEndY - touchStartY;\n";
- ptr += " \n";
- ptr += " // 确定滑动方向\n";
- ptr += " if (Math.abs(deltaX) > Math.abs(deltaY)) {\n";
- ptr += " // 水平滑动\n";
- ptr += " if (deltaX > 20) {\n";
- ptr += " move('right');\n";
- ptr += " } else if (deltaX < -20) {\n";
- ptr += " move('left');\n";
- ptr += " }\n";
- ptr += " } else {\n";
- ptr += " // 垂直滑动\n";
- ptr += " if (deltaY > 20) {\n";
- ptr += " move('down');\n";
- ptr += " } else if (deltaY < -20) {\n";
- ptr += " move('up');\n";
- ptr += " }\n";
- ptr += " }\n";
- ptr += " }, false);\n";
-
- ptr += " // 阻止页面滚动\n";
- ptr += " document.addEventListener('touchmove', (e) => {\n";
- ptr += " if (e.target.closest('.grid-container')) {\n";
- ptr += " e.preventDefault();\n";
- ptr += " }\n";
- ptr += " }, { passive: false });\n";
-
- ptr += " // 初始化\n";
- ptr += " loadBestScore();\n";
- ptr += " initGame();\n";
- ptr += " </script>\n";
- ptr += "</body>\n";
- ptr += "</html>\n";
-
- return ptr;
- }
复制代码
|