一、实验项目
?8.1 基于HTML5的贪吃蛇游戏的设计与实现
功能要求:贪吃蛇游戏是一款经典的单机休闲游戏,玩家通过上下左右按键控制蛇头的移动方向使其向指定方向前进,并吃掉随机位置上产生食物来获得分数。每吃掉一次食物,贪吃蛇的蛇身都会变长,并且会继续在随机位置上产生下一个食物。如果蛇头撞到墙壁或蛇身,则判定游戏失败。根据游戏的难度可以设置不同的游戏速度,蛇的爬行速度越快,游戏难度越大。
8.1.2 界面布局设计
1. 整体界面设计
使用<div>划分区域
CSS外部样式表snake.css
2. 信息展示区设计
使用<div>划分区域
3.主游戏界面设计
使用<canvas>元素制作游戏画面
使用<button>元素制作按钮
二、实验源代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>贪吃蛇游戏的设计与实现</title>
<link rel="stylesheet" href="css/snake.css">
</head>
<body>
<div id="container">
<h3>基于HTML5的贪吃蛇小游戏</h3>
<hr>
<!--状态信息栏-->
<div id="status">
<!--历史最高分-->
<div class="box">
历史最高分:<span id="bestScore">0</span>
</div>
<!--当前分数-->
<div class="box">
当前分数:<span id="currentScore">0</span>
</div>
</div>
<!--设置游戏画布-->
<canvas id="myCanvas" width="400" height="400" style="border:1px solid"></canvas>
<div>
<button onclick="window.location.reload()">
重新开始
</button>
</div>
</div>
<script>
//=====================
// 游戏参数设置
//=====================
//游戏界面刷新的间隔时间(数字越大,蛇的速度越慢)
var time = 200;
//蛇身长
var t = 3;
//记录蛇运行轨迹,用数组记录每一个坐标点uuuj
var snakeMap = [];
//蛇身单元大小
var w = 10;
// 方向代码:左37,上38,右39,下40
var direction = 37;
//蛇的初始坐标
var x = 0;
var y = 0;
//食物的初始化坐标
var foodX = 0;
var foodY = 0;
//当前得分
var score = 0;
//历史最高分纪录
var bestScore = 0;
//画布的宽和高
var width = 400;
var height = 400;
//根据id找到指定的画布
var c = document.getElementById("myCanvas");
//创建2D的context对象
var ctx = c.getContext("2d");
// 获得历史最高分记录
showBestScore();
//开始游戏
GameStart();
//=====================
// 启动游戏
//=====================
function GameStart() {
// 调用drawFood()函数,在随机位置绘制第一个食物
drawFood();
//随机生成贪吃蛇的蛇头坐标
x = Math.floor(Math.random() * width / w) * w;
y = Math.floor(Math.random() * height / w) * w;
//随机生成蛇的前进方向
direction = 37 + Math.floor(Math.random() * 4);
// 每隔time毫秒,则刷新一次游戏内容
setInterval("gameRefresh()", time);
}
//=====================
// 游戏画面刷新函数
//=====================
function gameRefresh() {
//将当前坐标数据添加到贪吃蛇的运动轨迹坐标数组中
snakeMap.push({
'x' : x,
'y' : y
});
//绘制贪吃蛇
drawSnake();
// 根据方向移动蛇头的下一个位置
switch(direction) {
//左37
case 37:
x -= w;
break;
//上38
case 38:
y -= w;
break;
//右39
case 39:
x += w;
break;
//下40
case 40:
y += w;
break;
}
//碰撞检测,返回值0表示没有撞到障碍物
var code = detectCollision();
//如果返回值不为0,表示游戏失败
if (code != 0) {
//如果当前得分高于历史最高分,则更新历史最高分记录
if (score > bestScore)
localStorage.setItem("bestScore", score);
//返回值1表示撞到墙壁
if (code == 1) {
alert("撞到了墙壁,游戏失败!当前得分:" + score);
}
//返回值2表示撞到蛇身
else if (code == 2) {
alert("撞到蛇身,游戏失败!当前得分:" + score);
}
//重新加载页面
window.location.reload();
}
//吃到食物判定
if (foodX == x && foodY == y) {
//吃到一次食物加10分
score += 10;
//更新状态栏中的当前分数
var currentScore = document.getElementById("currentScore");
currentScore.innerHTML = score;
//在随机位置绘制下一个食物
drawFood();
//蛇身长度加1
t++;
}
}
//==================
// 绘制贪吃蛇函数
//==================
function drawSnake() {
//设置蛇身内部填充颜色
ctx.fillStyle = "lightblue";
//绘制最新位置的蛇身矩形
ctx.fillRect(x, y, w, w);
//数组只保留蛇身长度的数据,如果蛇前进了则删除最旧的坐标数据
if (snakeMap.length > t) {
//删除数组第一项,即蛇的尾部最后一个位置的坐标记录,并且返回
var lastBox = snakeMap.shift();
//画布清除蛇的尾部最后一个位置,从而实现移动效果
ctx.clearRect(lastBox['x'], lastBox['y'], w, w);
}
}
//================
// 绘制食物函数
//================
function drawFood() {
//随机生成食物坐标
foodX = Math.floor(Math.random() * width / w) * w;
foodY = Math.floor(Math.random() * height / w) * w;
//内部填充颜色
ctx.fillStyle = "#FF0000";
//绘制矩形
ctx.fillRect(foodX, foodY, w, w);
}
//==================
// 改变蛇方向的按键监听
//==================
document.onkeydown = function(e) {
// 根据按键更新前进方向code:左37,上38,右39,下40
if (e.keyCode == 37 || e.keyCode == 38 || e.keycode == 39 || e.keyCode == 40)
direction = e.keyCode;
}
//================
// 碰撞检测函数
//================
function detectCollision() {
//蛇头碰撞到了四周的墙壁,则游戏失败
if (x > width || y > height || x < 0 || y < 0) {
return 1;
}
//蛇头碰撞到了蛇身,则游戏失败
for (var i = 0; i < snakeMap.length; i++) {
if (snakeMap[i].x == x && snakeMap[i].y == y) {
return 2;
}
}
return 0;
}
//=====================
// 显示历史最高分记录
//=====================
function showBestScore() {
//从本地存储数据中读取历史最高分
bestScore = localStorage.getItem("bestScore");
//如果尚未记录最高分,则重置为0
if (bestScore == null)
bestScore = 0;
//将历史最高分更新到状态栏中
var best = document.getElementById("bestScore");
best.innerHTML = bestScore;
}
</script>
</body>
</html>
三、实验结果
四、主要知识点