DOM gridArea实现25x25伪贪吃蛇:蛇无法移动问题求助
问题:使用gridArea控制的贪吃蛇无法通过方向键移动
我正在尝试用25x25网格创建一款伪贪吃蛇游戏,采用DOM的gridArea属性实现蛇的移动,但按下方向键时蛇的gridArea属性并未更新,蛇完全无法移动,我找不到问题所在,希望能获得帮助!
我的代码如下:
let snakex = 0; // x of snake on grid. let snakey = 0; // y of snake on grid. let temp = 0; // Doesn't have any function, I just prefer to have a temp variable with no use in places that have no function. document.onkeydown = function (event) { const key = event.key; switch(key) { case "ArrowLeft": if (snakex - 1 == 0) { temp -= 1; } // If the fact that moving left will make the snake leave the grid, it will not move and the function won't do anything. else { snakex -= 1; snake.style.gridArea = "'" + snakey + "/" + snakex + "'"; } // Move the snake to the left, while updating the x of the snake on the grid. break; case "ArrowRight": if (snakex + 1 == 26) { temp += 1; } else { snakex += 1; snake.style.gridArea = "'" + snakey + "/" + snakex + "'"; } break; case "ArrowUp": if (snakey - 1 == 0) { temp -= 1; } else { snakey -= 1; snake.style.gridArea = "'" + snakey + "/" + snakex + "'"; } break; case "ArrowDown": if (snakey + 1 == 26) { temp += 1; } else { snakey += 1; snake.style.gridArea = "'" + snakey + "/" + snakex + "'"; } break; } if (onFood()) { moveFood(); } // Different functions, don't have to do with the question. }
问题分析
你的核心问题有两个:
gridArea语法错误:你给gridArea赋值时额外加了单引号("'${snakey}/${snakex}'"),但CSS的grid-area属性值不需要包裹单引号,浏览器会把带单引号的字符串识别为无效值,导致样式完全不生效。- 初始位置与边界判断逻辑错误:
- 25x25网格的行/列索引是从1到25(CSS Grid的网格线计数从1开始),但你把初始位置设为
0,这本身就不在网格范围内; - 边界判断的条件写得太死板,比如向左移动时判断
snakex -1 ==0,但如果初始值是0,这个条件永远不会触发,而且正确的边界应该是判断是否小于等于1(已经在最左列)。
- 25x25网格的行/列索引是从1到25(CSS Grid的网格线计数从1开始),但你把初始位置设为
解决方案
- 移除
gridArea赋值中的多余单引号,用模板字符串让代码更清晰; - 把蛇的初始位置设为合法的网格坐标(比如
1,1); - 修正边界判断逻辑,直接判断当前坐标是否超出1-25的范围;
- 删掉没用的
temp变量(没必要保留占位,反而增加代码噪音)。
修正后的代码
let snakex = 1; // 初始位置设为网格左上角(合法坐标) let snakey = 1; document.onkeydown = function (event) { const key = event.key; switch(key) { case "ArrowLeft": if (snakex <= 1) break; // 已经在最左列,不移动 snakex -= 1; snake.style.gridArea = `${snakey}/${snakex}`; // 正确的gridArea格式 break; case "ArrowRight": if (snakex >= 25) break; // 已经在最右列,不移动 snakex += 1; snake.style.gridArea = `${snakey}/${snakex}`; break; case "ArrowUp": if (snakey <= 1) break; // 已经在最上行,不移动 snakey -= 1; snake.style.gridArea = `${snakey}/${snakex}`; break; case "ArrowDown": if (snakey >= 25) break; // 已经在最下行,不移动 snakey += 1; snake.style.gridArea = `${snakey}/${snakex}`; break; } if (typeof onFood === 'function' && onFood()) { // 加个类型判断避免报错 moveFood(); } }
内容的提问来源于stack exchange,提问作者pierreh
相关产品推荐
相关产品推荐

