HTML5 迷宫游戏(碰撞检测)实例一
在HTML5中,使用Canvas API可以开发出各种有趣的游戏,本例将介绍如何利用Canvas开发一个简单的迷宫游戏,并通过键盘控制小人的移动以及实现碰撞检测功能。
实现原理
1、迷宫的生成:使用一幅迷宫图片并将其绘制到画布上。
2、响应键盘事件:通过设置window.onkeydown
的响应函数processKey()
,当用户按下方向键时,根据键码调整小人的移动速度。
3、绘制帧:drawFrame()
函数每10毫秒刷新画布,如果小人有速度则移动并绘制轨迹,同时进行碰撞检测,如果小人到达终点,则弹出成功消息框。
4、碰撞检测:基于像素颜色的碰撞检测方法,取小人所在区域的像素块(在小人四周稍微扩展一点),判断其中是否有黑色像素,如果有则说明撞墙了。
下面是详细的代码实现:
<!DOCTYPE html> <html> <head> <meta charset="UTF8" /> <style> canvas { border: 6px double black; background: white; } img { display: none; } button { padding: 3px; } </style> <script> var canvas; var context; var x = 0; // 记录小人图标的当前位置 var y = 0; var dx = 0; // 记录小人在x轴和y轴方向上每一帧要移动多少像素 var dy = 0; var timer; window.onload = function() { canvas = document.getElementById("canvas"); context = canvas.getContext("2d"); drawMaze('maze.png', 5, 5); // 加载迷宫图片 window.onkeydown = processKey; // 当用户按下键盘上的键时,运行processKey()函数 }; function drawMaze(mazeFile, startingX, startingY) { clearTimeout(timer); // 先停止绘制 dx = 0; // 停止小人 dy = 0; var imgMaze = new Image(); imgMaze.onload = function() { canvas.width = imgMaze.width; // 调整画布大小以适应迷宫图片 canvas.height = imgMaze.height; context.drawImage(imgMaze, 0, 0); // 绘制迷宫 x = startingX; // 初始化小人位置 y = startingY; var imgFace = document.getElementById("face"); context.drawImage(imgFace, x, y); // 绘制小人 context.stroke(); timer = setTimeout(drawFrame, 10); // 10毫秒后绘制下一帧 }; imgMaze.src = mazeFile; // 加载迷宫图片 } function processKey(e) { dx = 0; // 如果小人在移动,停止 dy = 0; if (e.keyCode == 38) { // 向上键 dy = 1; } else if (e.keyCode == 40) { // 向下键 dy = 1; } else if (e.keyCode == 37) { // 向左键 dx = 1; } else if (e.keyCode == 39) { // 向右键 dx = 1; } } function checkForCollision() { var imgData = context.getImageData(x 1, y 1, 15 + 2, 15 + 2); // 取得小人所在的像素块,再稍微扩展一点 var pixels = imgData.data; for (var i = 0, n = pixels.length; i < n; i += 4) { // 检测其中的像素 var red = pixels[i]; var green = pixels[i + 1]; var blue = pixels[i + 2]; if (red == 0 && green == 0 && blue == 0) { // 检测黑色的墙(如果检测到,说明撞墙了) return true; } else if (red == 169 && green == 169 && blue == 169) { // 检测灰色的边(如果检测到,说明撞墙了) return true; } } return false; // 没有撞墙 } function drawFrame() { if (dx != 0 || dy != 0) { // 检测小人是否正在哪个方向上移动,如果是,则移动并绘制轨迹 context.beginPath(); context.fillStyle = "rgba(255,255,0,0.5)"; // 黄色背景表示移动痕迹 context.rect(x, y, 15, 15); context.fill(); x += dx; // 更新小人的位置 y += dy; var imgFace = document.getElementById("face"); // 绘制小人应该移动到的新位置 context.drawImage(imgFace, x, y); } if (checkForCollision()) { // 如果撞墙了,则停止移动 dx = 0; dy = 0; } else if (canvas.height y < 17) { // 如果到达终点,弹出成功消息框 alert('恭喜你通关!'); } else { timer = setTimeout(drawFrame, 10); // 继续绘制下一帧 } } </script> </head> <body> <canvas id="canvas" width="400" height="400"></canvas> <img id="face" src="face.png"> </body> </html>
相关问答FAQs
Q1: 如何更换迷宫地图?
A1: 你可以通过修改drawMaze
函数中的mazeFile
参数来更换迷宫地图,将'maze.png'
替换为新的迷宫图片路径即可,确保新图片的尺寸与Canvas的尺寸匹配,以便正确显示。
Q2: 如何增加游戏的复杂度或功能?
A2: 你可以考虑添加更多的游戏元素,如障碍物、道具或者多个角色等,还可以引入更复杂的碰撞检测算法,如基于二维几何的碰撞检测,以提高游戏的性能和体验,可以加入音效和动画效果,使游戏更加生动有趣。
HTML5 迷宫游戏(碰撞检测)实例一
1. 引言
在这个实例中,我们将创建一个简单的HTML5迷宫游戏,并实现基本的碰撞检测功能,游戏将包含一个迷宫地图和一个小球,当小球触碰到迷宫的墙壁时,游戏将停止。
2. 技术栈
HTML5
CSS3
JavaScript
Canvas API
3. 游戏设计
迷宫地图:使用二维数组表示迷宫的墙壁和通道。
小球:表示玩家控制的角色。
碰撞检测:当小球触碰到墙壁时,游戏结束。
4. 代码实现
HTML
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF8"> <title>迷宫游戏</title> <style> canvas { border: 1px solid black; } </style> </head> <body> <canvas id="mazeCanvas" width="400" height="400"></canvas> <script src="maze.js"></script> </body> </html>
CSS
(无需额外CSS,已在HTML中内联)
JavaScript (maze.js)
const canvas = document.getElementById('mazeCanvas'); const ctx = canvas.getContext('2d'); const mazeSize = 20; const blockSize = canvas.width / mazeSize; const ballSize = blockSize / 2; let ballX = blockSize / 2; let ballY = blockSize / 2; let ballSpeedX = 0; let ballSpeedY = 0; // 迷宫地图 const maze = [ [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1], [1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1], [1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1], [1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] ]; function drawMaze() { for (let y = 0; y < mazeSize; y++) { for (let x = 0; x < mazeSize; x++) { if (maze[y][x] === 1) { ctx.fillRect(x * blockSize, y * blockSize, blockSize, blockSize); } } } } function drawBall() { ctx.beginPath(); ctx.arc(ballX, ballY, ballSize, 0, Math.PI * 2); ctx.fill(); } function checkCollision() { const ballXBlock = Math.floor(ballX / blockSize); const ballYBlock = Math.floor(ballY / blockSize); if (maze[ballYBlock][ballXBlock] === 1) { alert('碰撞!游戏结束。'); ballSpeedX = 0; ballSpeedY = 0; } } function moveBall() { ballX += ballSpeedX; ballY += ballSpeedY; checkCollision(); } function loop() { ctx.clearRect(0, 0, canvas.width, canvas.height); drawMaze(); drawBall(); moveBall(); requestAnimationFrame(loop); } loop();
5. 归纳
在这个实例中,我们创建了一个简单的迷宫游戏,并实现了基本的碰撞检测功能,当小球触碰到迷宫的墙壁时,游戏将停止,这个例子可以作为更复杂游戏的基础,进一步扩展和优化。