js+canvas 手柄迷宫小游戏
最编程
2024-06-29 21:07:55
...
更多精彩文章请访问我的个人博客(zhuoerhuobi.cn)
纯H5的小游戏,放在了404页面,增添了网站的有趣性。点此试玩
一、项目分析
游戏构成要素
- 三级迷宫(重点)
- 移动者
- 终点
- 计时器
游戏流程
- 生成小尺寸迷宫
- 在迷宫中生成移动者和终点
- 用户开始游戏,移动者开始移动,计时器开始计时
- 移动者抵达终点,重新生成中尺寸迷宫,以及新的移动者和终点
- 移动者抵达终点,重新生成大尺寸迷宫,以及新的移动者和终点
- 移动者抵达终点,计时器停止计时,页面提示通关信息和通关时间,点击确定后跳转回首页
核心要素(迷宫)
要保证迷宫的可抵达性、随机性、一定的趣味性(复杂度)。
实现方案:连通图。随机的对任意两个相邻的不连通的节点,进行连通操作,直到起点与终点在同一连通图中。
该方案保证了随机性、可抵达性,根据测试,趣味性尚可,在大尺寸迷宫难度下具有一定难度。
替代方案:从起点随机遍历所有未抵达的节点,直到所有节点可抵达。
该方案保证了随机性、可抵达性(并且唯一),根据测试,复杂度较高,容易出现很长的死胡同(因为遍历产生的特性),但是道路唯一,不存在环路。
二、代码实现
生成迷宫
先用线条画出指定大小的格子棋盘。
var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
canvas.width = 800;
canvas.height = 800;
$("#canvasDiv").append(canvas);
var boardSize = 14; //将迷宫大小设置为变量,便于关卡变化
var piecePos;
var tree;
var reachable;
var startTime;
var costTime;
var mission;
//将画线抽象成一个动作
function drawLine(ctx, startX, startY, endX, endY) {
ctx.beginPath();
ctx.moveTo(startX, startY);
ctx.lineTo(endX, endY);
ctx.stroke();
ctx.closePath();
}
function drawChessBoard() {
ctx.strokeStyle="#202935";
ctx.lineWidth = 3;
drawLine(ctx,15,15,15,15+30*boardSize);
drawLine(ctx,15,15,15+30*boardSize,15);
for (var i = 1; i < boardSize; i++) {
ctx.strokeStyle="grey";
ctx.lineWidth = 2;
drawLine(ctx,15+i*30,15,15+i*30,15+30*boardSize);
drawLine(ctx,15,15+i*30,15+30*boardSize,15+i*30);
}
ctx.strokeStyle="#202935";
ctx.lineWidth = 3;
drawLine(ctx,15+boardSize*30,15,15+30*boardSize,15+30*boardSize);
drawLine(ctx,15,15+30*boardSize,15+30*boardSize,15+30*boardSize);
}
接下来逻辑上用二维数组代表迷宫,对其使用并查集操作生成迷宫。界面上擦掉连通的节点之间的“墙”。
//tree是表示同一子连通图的树,根节点相同则表示相互连通
function root(i