基于js的贪吃蛇小游戏

我一直很想用js写一个简易的网页小游戏,但是作为一个只写过几份js代码,连入门都算不上的蒟蒻,要我自己写的话简直天方夜谭。而网上的代码很难找到适合像我这样的小白。所幸在github上找到了一位前辈做过的前端小demo,这些完整且简单的代码着实令我受益匪浅。
点击此处进入

在这些的demo中,我选择了贪吃蛇游戏,一来比较简单,二来不用其他图片素材,比较方便。

游戏点此
和我之前html、css、javascript炖在一起作大杂烩不同,这份代码html、css、javascript分别放在三个文档中,清晰明了。

HTML

我们先从其骨架——html文档着手。html文档中的代码并不是很多,主要做了两件事:

  1. <head>中调用js和css的文档
  2. <div>标签将网页分割成几个独立区域
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<title>贪吃蛇</title>
<script src="snake.js"></script>
<link rel="stylesheet" href="snake.css"/>
</head>
<body>
<div id="map"></div>
<div id="Button">
<button type="button" onclick="start()">开始游戏</button>
<button type="button" onclick="stop()">结束游戏</button>
</div>
</body>
</html>

CSS

分好了区域,那么就开始用css修饰网页中需要的元素。css代码没什么需要解释的,详情看代码及注释,毕竟我也是新手。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
@charset "utf-8";/*允许中文字符*/
*{ margin:0; padding:0;}/* 删除浏览器中这些元素的默认值*/
html,body{ width:100%; height:100%;}/*宽度和高度为自适应*/
body{ position:relative;}/*相对定位*/
/*地图区域的各种样式*/
#map{ /*#为id选择器*/
position:absolute;
left:0;right:0; top:0; bottom:50px;
margin:auto;
border:2px solid #000;
font-size: 0;
}
/*按钮区域的各种样式*/
#Button{
position:absolute;
left:450px;right:0; bottom:10px;
margin:auto;
/*border:2px solid #000;*/
font-size: 25px;
}
/*span元素的样式*/
span{
display: inline-block;
/*border: 1px solid black; 是否显示边界*/
box-sizing: border-box;
}
/*className为snake和food的样式*/
span.snake{background: blue;}/*蛇的颜色*/
span.food{background: red;}/*食物的颜色*/

JAVASCRIPT

js的代码应该算是该游戏的重中之重了。
代码本身并不是很难,只是新的语言还不知道怎么用。
代码流程如下:

  1. 先定义所需要的变量。
  2. 游戏开始前初始化地图、蛇和食物。
  3. 开始游戏后按周期移动蛇,并判断下一步是否为自己的身体或者食物。
  4. 吃到食物,随机显示下一个食物。
  5. 吃到自己的身体则GameOver。
  6. 当遇到按键事件,根据所按键改变方向。

具体还是看代码吧……

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
//地图大小
var map={
width:900,
height:500
};
var box={
width:25,
height:25
};
//格子个数
var boxNums={
wNums:map.width/box.width,
hNums:map.height/box.height,
nums:0
};
boxNums.nums=boxNums.wNums*boxNums.hNums;
//格子大小
//蛇的身体
var snake=[];
//其他部分
var other=[];
//周期
var period=200;
//蛇头朝向,默认向右
//0 L;1 U;2 R;3 D
var dir=2;
//页面加载完成后立即执行,即最先执行的程序
window.onload=function(){
mapInit();
createFood();
}

function start(){
//周期调用函数:每隔400ms调用一次snakeMove
setInterval(snakeMove,period);
//按键松开时触发事件,按照所按键改变朝向,不能向后
document.onkeyup=function(e){
for(var i=0;i<4;i++){
if(e.keyCode==i+37&&dir!=(i+2)%4){
dir=i;break;
}
}
}
}
function stop(){
window.location.href=window.location.href;
}
//地图初始化
function mapInit(){
//获取id名为“map”的块元素,并赋予样式长宽
var map_target=document.getElementById("map");
map_target.style.width=map.width+"px";
map_target.style.height=map.height+"px";
var newSpan=null;
for(var i=1;i<=boxNums.nums;i++){
//创造方块,并赋予样式
newSpan=document.createElement("span");
newSpan.style.width=box.width+"px";
newSpan.style.height=box.height+"px";
newSpan.id=i;
//appendChild():往元素中添加新元素
map_target.appendChild(newSpan);
//蛇的位置初始化
if(i<=5){
newSpan.className="snake";
snake.push(newSpan);
}
else {
other.push(newSpan);
}
//push():往数组的最后添加元素
}
}
//随机产生一个食物
function createFood(){
//Math.floor()向下取整,Math.random()取0~1之间的随机数,other.length:other数组的长度
var x=Math.floor(Math.random()*other.length);
other[x].className="food";
}
//蛇移动
function snakeMove(){
//蛇头的id
var headId=parseInt(snake[snake.length-1].id);
//按照当前朝向向前移动一步
switch(dir){
case 0:
headId--;
if(headId%boxNums.wNums==0)headId+=boxNums.wNums;
break;

case 1:
headId-=boxNums.wNums;
if(headId<=0)headId+=boxNums.nums;
break;
case 2:
headId++;
if(headId%boxNums.wNums==1)headId-=boxNums.wNums;
break;
case 3:
headId+=boxNums.wNums;
if(headId>=boxNums.nums)headId-=boxNums.nums;
break;
default:break;
}
//找到下一步元素的Id
var newHead=document.getElementById(headId);
//如果吃到了蛇身
for(var i=1;i<snake.length;i++)
if(headId==snake[i].id){
alert("Game Over!");
//重新跳到当前页面,即刷新
window.location.href=window.location.href;
}
//找到新蛇头在other中的位置
var index;
for(var i=1;i<other.length;i++)
if(other[i].id==headId){
index=i;
break;
}
//删除other中的新蛇头
other.splice(index,1);
snake.push(newHead);
if(newHead.className=="food"){
//如果吃到了食物,蛇长度加一,并随机显示新食物
createFood();
}
else {
//否则删除原先蛇尾的元素
snake[0].className="";
other.push(snake.shift());
}
newHead.className="snake";
}