如何在JavaScript中将文本游戏的两个二维数组合并为三维数组
把二维数组合并为三维数组的解决方案
嘿,我来帮你搞定这个问题!你想把碰撞信息整合到mainArray里做成三维数组的思路完全没问题,只是之前没调整好各个地方对数组元素的访问方式而已。咱们一步步来修改代码:
核心思路
原来的mainArray每个位置存的是单个显示字符(比如.或#),colArray存碰撞标记;现在咱们让mainArray的每个位置变成一个长度为2的数组,第一个元素存显示字符,第二个元素存碰撞属性(比如"Solid"或空字符串),这样整个mainArray就成了三维数组啦。
修改后的完整代码
function gameloop() { var mainArray = []; // 移除单独的colArray var mapSizeX = 32; var mapSizeY = 128; var idPos = { x: 0, y: 0 }; function initMap(mainArray, mapSizeX, mapSizeY) { for (var i = 0; i < mapSizeX; i++) { mainArray.push([]) for (var j = 0; j < mapSizeY; j++) { // 初始化每个位置为[显示字符, 碰撞属性] mainArray[i][j] = [".", ""]; if (j == 0 || j == mapSizeY - 1 || i == 0 || i == mapSizeX - 1) { // 边框位置设置为#和Solid mainArray[i][j][0] = "#"; mainArray[i][j][1] = "Solid"; } } } } function nl() { GameScreen.innerText += "\n"; } function render() { // 渲染时只取每个位置的第一个元素(显示字符) GameScreen.innerText = mainArray.map(row => row.map(cell => cell[0]).join("")).join("\n"); nl(); nl(); } function reposition(xChange, yChange, strA) { // 碰撞判断时取目标位置的第二个元素 if (mainArray[idPos.x + xChange][idPos.y + yChange][1] === "Solid") { GameLog.innerText = "You can not travel in that direction" } else { // 更新玩家原位置的显示字符 mainArray[idPos.x][idPos.y][0] = "."; idPos.x = idPos.x + xChange; idPos.y = idPos.y + yChange; // 设置新位置的显示字符为@ mainArray[idPos.x][idPos.y][0] = "@"; GameLog.innerText = "You take a step to the " + strA } render(); } //Startup initMap(mainArray, mapSizeX, mapSizeY); idPos.x = Math.floor(mapSizeX / 2); // 确保索引为整数,避免浮点数问题 idPos.y = Math.floor(mapSizeY / 2); mainArray[idPos.x][idPos.y][0] = "@"; //First Render render(); document.addEventListener('keydown', function(event) { if (event.keyCode === 38) { reposition(-1, 0, "North"); } if (event.keyCode === 40) { reposition(1, 0, "South"); } if (event.keyCode === 37) { reposition(0, -1, "West"); } if (event.keyCode === 39) { reposition(0, 1, "East"); } }); } gameloop();
关键修改点说明
- 移除
colArray:不再需要单独的碰撞数组,所有信息都统一存在mainArray里 - 初始化三维数组:
mainArray[i][j] = [".", ""],每个位置同时存储显示字符和碰撞属性 - 边框设置优化:合并了原来的多个if判断,直接给边框位置的两个元素赋值
- 渲染逻辑调整:
render函数里通过row.map(cell => cell[0])提取显示字符,再拼接成可显示的字符串 - 碰撞判断调整:访问
mainArray[目标x][目标y][1]来检查该位置是否为不可通行的Solid - 玩家位置更新:修改玩家位置时,只更新数组的第一个元素(显示字符),碰撞属性保持不变
另外我还加了个小优化:用Math.floor(mapSizeX / 2)确保玩家初始位置是整数索引,避免因为除法得到浮点数导致的潜在问题。
对应的HTML部分可以保持不变:
<p style="color:#7d7d7d;font-family:Lucida Console;">Dungeon Valley.<br> <font style="color:#ABABAB;font-family:Lucida Console;font-size:0.5em"> Taming the Borderlands.<br> v0.005 By heromedel. </font> </p> <p> <section id="GameScreen" style="color:#000000;font-family:Lucida Console;"></section> </p> <p> <section id="GameLog" style="color:#000000;font-family:Lucida Console;">Arrow Keys to move.<br></section> <script src="main.js"></script>
内容的提问来源于stack exchange,提问作者heromedel
相关产品推荐
相关产品推荐

