源代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<style type="text/css">
body{
background-color: silver;
}
#container{
width: 600px;
margin: 10px auto;
text-align: center;
padding: 10px;
background-color: white;
box-shadow: 10px 10px 10px gray;
}
.box{
width: 200px;
float: left;
height: 20px;
margin: 10px 50px;
}
button{
width: 200px;
height: 50px;
border: 0;
font-size: 25px;
font-weight: bold;
background-color: lightcoral;
color: white;
cursor: pointer;
}
button:hover{
background-color: chocolate;
}
</style>
</head>
<body>
<div id="container">
<h3>基于HTML5的贪吃蛇游戏</h3>
<hr />
<div class="box">
历史最高分:<span id="bestScore">0</span>
</div>
<div class="box">
当前分数:<span id="currentScore">0</span>
</div>
<canvas id="myCanvas"width="400"height="400"style="border: 1px solid;"></canvas>
<button>重新开始</button>
</div>
<script type="text/javascript">
//游戏界面刷新的间隔时间(数字越大,蛇的速度越慢)
var time=300;
//蛇身长
var t=3;
//记录蛇运行轨迹,用数组记录每一个坐标点
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 showBestScore(){
//从本地存储数据中读取历史最高分
bestScore=localStorage.getItem("bestScore");
//如果尚未记录最高分,则重置为0
if(bestScore==null)
bestScore=0;
//将历史最高分更新到状态栏中
var best=document.getElementById("bestScore");
best.innerHTML=bestScore;
}
//启动游戏
//=========================
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 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);
}
//游戏画面刷新函数
//============================
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);
}
}
//改变蛇方向的按键监听
//==============
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;
}
</script>
</body>
</html>
效果图: