-
Notifications
You must be signed in to change notification settings - Fork 653
/
index.html
225 lines (201 loc) · 7.62 KB
/
index.html
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
216
217
218
219
220
221
222
223
224
225
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<!-- <meta name="viewport" content="width=device-width, initial-scale=1"> -->
<!-- 上述3个meta标签必须放在最前面,任何其他内容都必须跟随其后! -->
<meta name="renderer" content="webkit">
<title>贪吃蛇</title>
<style>
#canvas{
box-shadow: 0 5px 40px black;
position: absolute;
top: 50%;
left: 50%;
margin-top: -250px;
margin-left: -400px;
}
</style>
</head>
<body>
<canvas id="canvas" width="800" height="500">
Your browser does not support the Canvas API.
Please upgrade your browser.
</canvas>
<script type="text/javascript">
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
//构造对象方块
function Rect(x, y, w, h, color) {
this.x = x;
this.y = y;
this.w = w;
this.h = h;
this.color = color;
}
//画方块的方法
Rect.prototype.draw = function() {
context.beginPath();
context.fillStyle = this.color;
context.rect(this.x, this.y, this.w, this.h);
context.fill();
context.stroke();
}
//构造对象蛇
function Snake() {
//定义一个空数组存放组成整蛇的方块对象
var snakeArray = [];
//画出4个方块,设置成灰色
for (var i = 0; i < 4; i++) {
var rect = new Rect(i * 20, 0, 20, 20, "gray");
//之所以用splice(往前加)而不是用push(往后加),是为了让蛇头出现在数组第一个位置
snakeArray.splice(0, 0, rect);
}
//把数组第一个作为蛇头,蛇头设成红色
var head = snakeArray[0];
head.color = "red";
//此处将两个后面常用的东西定为属性,方便后面调用
this.head = snakeArray[0]; //蛇头
this.snakeArray = snakeArray; //整蛇数组
//给定初始位置向右(同keyCode右箭头)
this.direction = 39;
}
//画蛇的方法
Snake.prototype.draw = function() {
for (var i = 0; i < this.snakeArray.length; i++) {
this.snakeArray[i].draw();
}
}
//蛇移动的方法
Snake.prototype.move = function() {
//此处是核心部分,蛇的 移动方式
//1、画一个灰色的方块,位置与蛇头重叠
//2、将这个方块插到数组中蛇头后面一个的位置
//3、砍去末尾的方块
//4、将蛇头向设定方向移动一格
var rect = new Rect(this.head.x, this.head.y, this.head.w, this.head.h, "gray");
this.snakeArray.splice(1, 0, rect);
//判断是否吃到食物,isEat判定函数写在最后了
//吃到则食物重新给位置,不砍去最后一节,即蛇变长
//没吃到则末尾砍掉一节,即蛇长度不变
if (isEat()) {
food = new getRandomFood();
} else {
this.snakeArray.pop();
}
//设置蛇头的运动方向,37 左,38 上,39 右,40 下
switch (this.direction) {
case 37:
this.head.x -= this.head.w
break;
case 38:
this.head.y -= this.head.h
break;
case 39:
this.head.x += this.head.w
break;
case 40:
this.head.y += this.head.h
break;
default:
break;
}
// gameover判定
// 撞墙
if (this.head.x >= canvas.width || this.head.x < 0 || this.head.y >= canvas.height || this.head.y < 0) {
clearInterval(timer);
}
// 撞自己,循环从1开始,避开蛇头与蛇头比较的情况
for (var i = 1; i < this.snakeArray.length; i++) {
if (this.snakeArray[i].x == this.head.x && this.snakeArray[i].y == this.head.y) {
clearInterval(timer);
}
}
}
//画出初始的蛇
var snake = new Snake()
snake.draw();
//画出初始的食物
var food = new getRandomFood()
//定时器
var timer = setInterval(function() {
context.clearRect(0, 0, canvas.width, canvas.height);
food.draw();
snake.move();
snake.draw();
}, 100)
//键盘事件,其中的if判定是为了让蛇不能直接掉头
document.onkeydown = function(e) {
var ev = e || window.event;
switch (ev.keyCode) {
case 37:
{
if (snake.direction !== 39) {
snake.direction = 37;
}
break;
}
case 38:
{
if (snake.direction !== 40) {
snake.direction = 38;
}
break;
}
case 39:
{
if (snake.direction !== 37) {
snake.direction = 39;
}
break;
}
case 40:
{
if (snake.direction !== 38) {
snake.direction = 40;
}
break;
}
}
ev.preventDefault();
}
//随机函数,获得[min,max]范围的值
function getNumberInRange(min, max) {
var range = max - min;
var r = Math.random();
return Math.round(r * range + min)
}
//构建食物对象
function getRandomFood() {
//判定食物是否出现在蛇身上,如果是重合,则重新生成一遍
var isOnSnake = true;
//设置食物出现的随机位置
while (isOnSnake) {
//执行后先将判定条件设置为false,如果判定不重合,则不会再执行下列语句
isOnSnake = false;
var indexX = getNumberInRange(0, canvas.width / 20 - 1);
var indexY = getNumberInRange(0, canvas.height / 20 - 1);
var rect = new Rect(indexX * 20, indexY * 20, 20, 20, "green");
for (var i = 0; i < snake.snakeArray.length; i++) {
if (snake.snakeArray[i].x == rect.x && snake.snakeArray[i].y == rect.y) {
//如果判定重合,将其设置为true,使随机数重给
isOnSnake = true;
break;
}
}
}
//返回rect,使得实例化对象food有draw的方法
return rect;
}
//判定吃到食物,即蛇头坐标与食物坐标重合
function isEat() {
if (snake.head.x == food.x && snake.head.y == food.y) {
return true;
} else {
return false;
}
}
</script>
</body>
</html>