原生贪吃蛇升级版

贪吃蛇升级版

重点:
1.添加了开始,停止,结束按钮,改变了启动和结束的方式,修复了游戏结束后不可以再次玩游戏
2.改变了蛇的身体颜色,变成随机颜色
3.修改了蛇头方向都变化不可以返回
4.添加了蛇头碰到身体结束游戏
5.初始化游戏
6.添加了wasd键盘控制事件,添加了鼠标拖拽改变方向

效果


案例代码

Css 外部引入style.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
30
* {
padding: 0;
margin: 0;
}
/* 蛇身体的长度和分数 */
.df,
.ssc {
position: absolute;
top: 0px;
left: 400px;
}
.ssc {
left: 250px;
}
/* 蛇地图的样式 */
.wrap {
width: 800px;
height: 600px;
position: relative;
top: 20px;
left: 20px;
background-color: #ccc;
}
/* 游戏说明 */
.yx {
position: absolute;
margin: 40px;
font-size: 20px;
color: pink;
}

Html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<input type="button" value="开始游戏">
<input type="button" value="停止游戏">
<input type="button" value="结束游戏">
<div class="ssc">
蛇身的长度: 0
</div>
<div class="df">
得分: 0
</div>
<!-- 蛇地图 -->
<div class="wrap">

</div>
<div class="yx">
<h3>游戏说明:</h3>
玩法:上下左右键控制,w上s下a左d右控制,鼠标上下左右拖拽<br>
点击开始游戏,开启游戏<br>
点击停止游戏,暂停游戏,点击开始游戏恢复继续玩<br>
点击结束游戏,停止游戏要点击开启游戏重新开始<br>
</div>

Js

外部引入食物 Food.js

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
/*
* @Author: yhf
* @Date: 2018-09-10 12:36:12
* @Last Modified by: yhf
* @Last Modified time: 2018-09-11 09:08:11
*/
(function () {
// 存放食物的数组
var elements = [];

// 食物方法
function Food(x, y, height, width, color) {
// 食物的横纵坐标
this.x = x;
this.y = y;
// 食物的宽高
this.height = height || 20;
this.width = width || 20;
// 食物的颜色
this.color = color || "yellow";
};

// 删除食物函数
function remove() {
var i = elements.length - 1;
for (; i >= 0; i--) {
var ele = elements[i];
// 从wrap删除
ele.parentNode.removeChild(ele);
elements.splice(i, 1);
}
};


// 添加原型方法--初始化食物
Food.prototype.init = function (wrap) {
// 删除食物
remove();
// 创建食物
var div = document.createElement("div");
// 添加食物到地图
wrap.appendChild(div);
// 设置食物div的样式
// div脱离文档流
div.style.position = "absolute";
// div宽高
div.style.width = this.width + "px";
div.style.height = this.height + "px";
// div颜色
div.style.backgroundColor = this.color;

// 随机食物横纵坐标
this.x = parseInt(Math.random() * (wrap.offsetWidth / this.width)) * this.width;
this.y = parseInt(Math.random() * (wrap.offsetHeight / this.height)) * this.height;
// 设置食物横纵坐标
div.style.left = this.x + "px";
div.style.top = this.y + "px";
// 把新建的数组添加到食物数组中
elements.push(div);
};

// 添加原型方法清空食物
Food.prototype.empty = function () {
remove();
elements.splice(0, elements.length);
}

// 把食物暴露给window,外界可以调用
window.Food = Food;
}());

外部引入蛇 Snake.js

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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
/*
* @Author: yhf
* @Date: 2018-09-10 14:28:55
* @Last Modified by: yhf
* @Last Modified time: 2018-09-11 08:28:31
*/
(function () {
// 存放蛇数组·
var elements = [];

// 蛇的函数
function Snake(width, height, direction) {
// 计算得分
this.df = 0;
// 判断是否碰到身体
this.stfh = true;
// 蛇的宽高
this.width = width || 20;
this.height = height || 20;
// 蛇身体
this.body = [{
x: 3,
y: 2,
color: "red"
}, {
x: 2,
y: 2,
color: "#00FFFF"
}, {
x: 1,
y: 2,
color: "pink"
}];
// 颜色
this.col = ["#F0F8FF", "#FAEBD7", "#F0F8FF", "#FAEBD7", "#00FFFF", "#7FFFD4", "#F0FFFF", "#F5F5DC", "#FFE4C4", "#000000", "#FFEBCD", "#0000FF", "#8A2BE2", "#A52A2A", "#DEB887", "#5F9EA0", "#7FFF00", "#D2691E", "#FF7F50", "#6495ED", "#FFF8DC", "#DC143C", "#00FFFF", "#00008B", "#008B8B", "#B8860B", "#A9A9A9", "#006400", "#BDB76B", "#8B008B", "#556B2F", "#FF8C00", "#9932CC", "#8B0000", "#E9967A", "#8FBC8F", "#483D8B", "#2F4F4F", "#00CED1", "#9400D3", "#FF1493", "#00BFFF", "#696969", "#1E90FF", "#D19275", "#B22222", "#FFFAF0", "#228B22", "#FF00FF", "#DCDCDC", "#F8F8FF", "#FFD700", "#DAA520", "#808080", "#008000", "#ADFF2F", "#F0FFF0", "#FF69B4", "#CD5C5C", "#4B0082", "#FFFFF0", "#F0E68C", "#E6E6FA", "#FFF0F5", "#7CFC00", "#FFFACD", "#ADD8E6", "#F08080", "#E0FFFF", "#FAFAD2", "#D3D3D3", "#90EE90", "#FFB6C1", "#FFA07A", "#20B2AA", "#87CEFA", "#8470FF", "#778899", "#B0C4DE", "#FFFFE0", "#00FF00", "#32CD32", "#FAF0E6", "#FF00FF", "#800000", "#66CDAA", "#0000CD", "#BA55D3", "#9370D8", "#3CB371", "#7B68EE", "#00FA9A", "#48D1CC", "#C71585", "#191970", "#F5FFFA", "#FFE4E1", "#FFE4B5", "#FFDEAD", "#000080", "#FDF5E6", "#808000", "#6B8E23", "#FFA500", "#FF4500", "#DA70D6", "#EEE8AA", "#98FB98", "#AFEEEE", "#D87093", "#FFEFD5", "#FFDAB9", "#CD853F", "#FFC0CB", "#DDA0DD", "#B0E0E6", "#800080", "#FF0000", "#BC8F8F", "#4169E1", "#8B4513", "#FA8072", "#F4A460", "#2E8B57", "#FFF5EE", "#A0522D", "#C0C0C0", "#87CEEB", "#6A5ACD", "#708090", "#FFFAFA", "#00FF7F", "#4682B4", "#D2B48C", "#008080", "#D8BFD8", "#FF6347", "#40E0D0", "#EE82EE", "#D02090", "#F5DEB3", "#FFFFFF", "#F5F5F5", "#FFFF00", "#9ACD32"];
// 蛇的行走方向
this.direction = direction || "right";
};


// 添加原型初始化蛇
Snake.prototype.init = function (wrap) {

// 初始化删除蛇
remove();

// 循环创建蛇的身体
for (let i = 0; i < this.body.length; i++) {
// 初始化this.body[i]
const ele = this.body[i];
// 创建蛇
var div = document.createElement("div");
// 添加蛇到地图
wrap.appendChild(div);
// div脱离文档流
div.style.position = "absolute";
// div宽高
div.style.width = this.width + "px";
div.style.height = this.height + "px";
// div颜色
div.style.backgroundColor = ele.color;
// div横纵坐标
var x = this.width * ele.x;
var y = this.height * ele.y;
// 设置横纵坐标
div.style.left = x + "px";
div.style.top = y + "px";
// 添加到数组
elements.push(div);
}
};

// 添加原型方法--蛇动起来
Snake.prototype.move = function (food, wrap) {

// 获取到蛇身体数据
var i = this.body.length - 1;
// 循环设置身体的变动位置,把蛇头以外,从蛇尾开始把前一位的数据获取到
for (; i > 0; i--) {
this.body[i].x = this.body[i - 1].x;
this.body[i].y = this.body[i - 1].y;
}
// 判断键盘到移动改变蛇头到移动方向
switch (this.direction) {
case "right":
this.body[0].x += 1;
break;
case "left":
this.body[0].x -= 1;
break;
case "top":
this.body[0].y -= 1;
break;
case "bottom":
this.body[0].y += 1;
break;
}

// 获取蛇头到横纵坐标
var sx = this.body[0].x * this.width;
var sy = this.body[0].y * this.height;
// 判断蛇头是否吃到了食物
if (sx == food.x && sy == food.y) {
var sjys = parseInt(Math.random() * this.col.length);
for (let i = 0; i < this.col.length; i++) {
const ele = this.col[i];
if (i == sjys) {
this.df++;
// 获取到蛇的尾巴
var list = this.body[this.body.length - 1];
// 再蛇身体添加多一个身体值
this.body.push({
x: list.x,
y: list.y,
color: ele
});
// 删除食物
food.init(wrap);
}
}
// this.df++;
// // 获取到蛇的尾巴
// var list = this.body[this.body.length - 1];
// // 再蛇身体添加多一个身体值
// this.body.push({
// x: list.x,
// y: list.y,
// color: list.color
// });
// // 删除食物
// food.init(wrap);
}

// 循环获取身体位置,把蛇头以外,从蛇尾开始把前一位的数据获取到,判断蛇头是否碰到身体,判断生死
for (var i = this.body.length - 1; i > 0; i--) {
if (this.body[i].x * this.width == sx && sy == this.body[i].y * this.height) {
this.stfh = false;
}
}

};

// 添加原型方法清空蛇
Snake.prototype.empty = function () {
remove();
elements.splice(0, elements.length);
this.body = [{
x: 3,
y: 2,
color: "red"
}, {
x: 2,
y: 2,
color: "pink"
}, {
x: 1,
y: 2,
color: "pink"
}];
this.direction = "right";
};

// 删除蛇函数
function remove() {
var i = elements.length - 1;
for (; i >= 0; i--) {
var ele = elements[i];
// 从wrap删除
ele.parentNode.removeChild(ele);
// 删除数组中到蛇身
elements.splice(i, 1);
}
};


// 把Snake暴露给window
window.Snake = Snake;
}());

外部引入初始化 Game.js

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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
/*
* @Author: yhf
* @Date: 2018-09-10 15:37:16
* @Last Modified by: yhf
* @Last Modified time: 2018-09-11 08:30:40
*/
(function () {
// 定义this
var _this = null;
// 键盘方向
var key = 39;
// 定时器
var time = null;

// 启动游戏构造函数
function Game() {
// 初始化食物
this.food = new Food();
// 初始化蛇
this.snake = new Snake();
// 定义画布
this.wrap = wrap;
// 定义this
_this = this;
// 判断是否点击开始
this.bol = false;
};

// 添加原型启动游戏函数
Game.prototype.init = function () {
// 初始化食物
this.food.init(this.wrap);
// 初始化蛇
this.snake.init(this.wrap);
// 蛇动
this.runSnake();
// 键盘事件
this.keyDown();
};

// 添加原型蛇动起来
Game.prototype.runSnake = function () {
// 添加名为time的定时器
time = setInterval(function () {
// 蛇动函数
this.snake.move(this.food, this.wrap);
// 初始化蛇
this.snake.init(this.wrap);

// 最大横纵坐标 --蛇最大可以移动的距离
var maxX = wrap.offsetWidth / this.snake.width;
var maxY = wrap.offsetHeight / this.snake.height;

// 获取蛇头部横纵坐标
var hearX = this.snake.body[0].x;
var hearY = this.snake.body[0].y;

// 判断是否碰到墙壁结束游戏
if (hearX < 0 || hearX >= maxX) {
// 清空函数
this.empty();
};
if (hearY < 0 || hearY >= maxY) {
// 清空函数
this.empty();
};
if (!this.snake.stfh) {
this.snake.stfh = true;
this.empty();
}
df.innerHTML = "得分:" + this.snake.df;
ssc.innerHTML = "蛇身长度:" + (this.snake.df + 2);

}.bind(_this), 150);
};

// 添加原型方法--键盘和鼠标事件
Game.prototype.keyDown = function () {
// document.addEventListener("keydown", function (e) {
// // 此时this应该是keydown的事件对象
// // 所以this就是document
// // 获取按键值
// keyfn(this, e.keyCode);
// }.bind(_this), false);

// 鼠标拖动控制方向
var dx = 0; //鼠标点击时的位置
var dy = 0; //鼠标点击时的位置
var sx = 0; //鼠标当前位置
var sy = 0; //鼠标当前位置
// 给页面添加监听事件
// 监听鼠标按下
document.onmousedown = function (e) {
bol = true;
dx = e.clientX;
dy = e.clientY;
e.preventDefault();
}
// 鼠标移动
document.onmousemove = function (e) {
sx = e.clientX;
sy = e.clientY;
}
// 鼠标抬起
document.onmouseup = function () {
console.log(sx - dx)
if (Math.abs(sx - dx) > Math.abs(sy - dy)) {
if (sx - dx > 0) {
keyfn(this, 39);
} else {
keyfn(this, 37);
}
} else if (sy - dy == 0) {
keyfn(this, 39);
} else {
if (sy - dy > 0) {
keyfn(this, 40);
} else {
keyfn(this, 38);
}
}
}.bind(_this);

// 给页面添加监听事件
// 监听键盘按下
document.onkeydown = function (e) {
keyfn(this, e.keyCode);
}.bind(_this);
};
// 添加原型-停止游戏
Game.prototype.stop = function () {
clearInterval(time);
this.bol = false;
}

// 添加原型-结束游戏
Game.prototype.empty = function () {
alert("游戏结束");
// 结束定时器
clearInterval(time);
// 删除清空蛇
this.snake.empty();
// 删除清空食物
this.food.empty();
// 结束游戏
this.bol = false;
// 清空得分
this.snake.df = 0;
}

// 键盘事件
function keyfn(_this, keys) {
switch (keys) {
case 37: //左
if (key != 39 && key != 68) {
_this.snake.direction = "left";
key = keys;
}
break;

case 38: //上
if (key != 40 && key != 83) {
_this.snake.direction = "top";
key = keys;
}
break;

case 39: //右
if (key != 37 && key != 65) {
_this.snake.direction = "right";
key = keys;
}
break;

case 40: //下
if (key != 38 && key != 87) {
_this.snake.direction = "bottom";
key = keys;
}
break;


case 65: //左
if (key != 39 && key != 68) {
_this.snake.direction = "left";
key = keys;
}
break;

case 87: //上
if (key != 40 && key != 83) {
_this.snake.direction = "top";
key = keys;
}
break;

case 68: //右
if (key != 37 && key != 65) {
_this.snake.direction = "right";
key = keys;
}
break;

case 83: //下
if (key != 38 && key != 87) {
_this.snake.direction = "bottom";
key = keys;
}
break;
}
}

// 把Game暴露给window
window.Game = Game;
}());

外部引入开启 index.js

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
/*
* @Author: yhf
* @Date: 2018-09-10 23:45:57
* @Last Modified by: yhf
* @Last Modified time: 2018-09-11 08:38:58
*/
// 获取定义的蛇地图
const wrap = document.querySelector(".wrap");
const btn = document.querySelectorAll("input");
const df = document.querySelector(".df");
const ssc = document.querySelector(".ssc");

// 定义运动函数
var gm = new Game(wrap);
btn[0].onclick = function () {
// 判断点击了不可以再点击
if (gm.bol) {
return;
}
// 开关
gm.bol = "true";
// 开启游戏
gm.init();
}
btn[1].onclick = function () {
// 停止游戏
gm.stop();
}
btn[2].onclick = function () {
// 未点击开始不可以点击
if (!gm.bol) {
return;
}
// 结束游戏
gm.empty();
}



/*
* 后期添加项目:
* 食物颜色改变不同的颜色,加的身体值不同
* 改关卡闯关
* 添加其他功能
* 未完待续。。。
* 手机事件
*
*/
-------------本文结束感谢您的阅读-------------
0%