游戏里的小人如何走路?百行HTML5+JS能搜索出路径吗?
用了HTML5里的canvas. 这个"游戏"的”玩法“是:
- 改迷宫折腾电脑
- 改程序折腾自己:-)。我自以为程序挺简明,注释挺多,比如:
-
- // 全局变量坑死人,这里曾经少个var
- // 虽然直接drawImage有时能出来,但这么做绝对必要。坑了我好长时间。
单.HTML文件146行,包括数张嵌入式.gif图片和JS。下面是全部JS(112行):
ctx = gmaze.getContext('2d') function reset_maze(){ X = Xin.value; if(X > 32 || X < 6) X = 20 Y = Yin.value; if(Y > 20 || Y < 6) Y = 13 Xin.value = X; Yin.value = Y maze = new Array(); for(y = 0; y < Y; y++){ var row = new Array() // new Array(3)不是创建长度为3的数组 for(x = 0; x < X; x++) row.push(Math.random() < 0.7 ? ' ' : 'w') maze.push(row) } maze[cx = 0][cy = 0] = 'r' // cx,cy记录当前机器人位置 gmaze.width = X * 32; gmaze.height = Y * 32; draw_maze() }; reset_maze() function clear_path() { for(y = 0; y < Y; y++) for(x = 0; x < X; x++){ var c = maze[y][x] if(c == 'x' || c == 'p' || c == 'r') maze[y][x] = ' ' } stepcnt = 0 } function draw_maze(){ for(y = 0; y < Y; y++) for(x = 0; x < X; x++){ var c = maze[y][x] if(c == 'r') draw_img(img_robot, x, y) else if(c == 'w') draw_img(img_wall, x, y) else if(c == 'p') draw_img(img_flag, x, y) else if(c == ' ') draw_blk('#fff', x, y) else draw_blk('#f00', x, y) } } // 虽然直接drawImage有时能出来,但这么做绝对必要。坑了我好长时间。 function draw_img(img, x, y){ var i = new Image(); i.src = img.src i.onload = function(){ ctx.drawImage(i, x * 32, y * 32) } } function draw_blk(color, x, y){ ctx.fillStyle = color; ctx.fillRect(x * 32, y * 32, 32, 32) } // mx, my记录鼠标指针位置 d = document; d.addEventListener('mousemove', function(e){ mx = e.x; my = e.y }) // 像素坐标到块坐标转换。border+wall=8+32. round() is bad, round() is wrong. function get_x() { // var x = Math.floor((mx - 40) / 32) if(x < 0 || x >= X) throw 'X超出范围。' return x } function get_y() { var y = Math.floor((my - 40) / 32) if(y < 0 || y >= Y) throw 'Y超出范围。' return y } d.addEventListener('mousedown', function(e){ // 可以忽略exception if(e.which != 1) return; // Not left button var x = get_x(), y = get_y() var c = maze[y][x] if(c == 'w') maze[y][x] = ' ', draw_blk('#fff', x, y) else if (c == ' ') maze[y][x] = 'w', draw_img(img_wall, x, y) }) d.addEventListener('keydown', function(e){ if (e.keyCode != 71) return // Not 'g' try{ tx = get_x(), ty = get_y() // target x, y, 全局变量 clear_path() //alert('Searching for ' + cx + ',' + cy + ' to ' + tx + ',' + ty) ok = search(cx, cy) if(ok) maze[cy = ty][cx = tx] = 'r' else { maze[cy][cx] = 'r' alert('Please try a nearer target.') } draw_maze() } catch(e){} }) function search(x, y){ if(x == tx && y == ty) return true if(++stepcnt > 1000000) return false if(x<0 || x>=X || y<0 || y>=Y) { console.log(x, y) return false } if(maze[y][x] != ' ') { console.log(x, y, maze[y][x]) return false } maze[y][x] = 'p' var dxdy = [[0,-1],[0,1],[-1,0],[1,0]] var e_i = [1,2,3,4] // evaluation_index var i, j for(i = 0; i < 4; i++) { var a = x + dxdy[i][1], b = y + dxdy[i][0] var c = tx - a, d = ty - b var t = c * c + d * d // 距离的平方 e_i[i] = (t << 2) | i } // 默认情况下,sort方法按字母顺序对元素排序。https://www.codenong.com/1063007/ e_i.sort((a, b) => a - b) for(j = 0; j < 4; j++) { i = e_i[j] & 0x3 // 全局变量坑死人,这里曾经少个var if(search(x + dxdy[i][1], y + dxdy[i][0])) return true } maze[y][x] = 'x'; return false }
// 写完了才知道let和const是JavaScript里相对较新的变量声明方式。let在很多方面与var相似。
点这里下载HTML+JS。下面是HTML的不包含嵌入图片的部分:
<html><meta charset="gbk"><title>走迷宫</title><style> /* https://www.w3school.com.cn/cssref/css_selectors.asp */ * { font:12pt 'Segoe UI' } #wall { position:absolute; left:8px; top:8px; padding:32px; background-image:url(data:image/gif;base64,...); } #gmaze { cursor:hand } #panel { float:right; top:32px } h6 { font:bold 14pt 'Segoe UI'; color:green; margin:1em } input { width:2em } pre { display:none } </style> <body> <div id="wall"><canvas id="gmaze"/></div> <div id="panel"> <h6>你设计一个迷宫,机器人来走</h6> <p style="text-align:center"> <button onclick="reset_maze()">重新生成</button> <input type="text" id="Xin" value="20"/> X <input type="text" id="Yin" value="17"/>的迷宫 </p> <ul> <li>编辑: 在迷宫里按鼠标左键切换路或墙。<br>最外面的墙不能改变。</li> <li>按 g 键后,机器人会试图走到鼠标指针所在处。</li> <li style='font-size:10pt'>打开开发人员工具后,键盘焦点可能不在页面内。<br>此时可点击页面内任意文本框把焦点切回来。<br>鼠标双击容易误操作。</li> </ul> </div>
想起扫地机器人的笑话: 把droppings摊了薄薄一层; 展屎官的迷思……
分类:
HTML/JS
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?