Canvas系列之贪吃蛇

准备

canvas画布 食物 蛇 键盘事件

1.canvas画布

绘制就很简单啦 你可以给点你喜欢的样式

1
2
3
<canvas width="600" height="400">
你的浏览器不支持canvas,请使用chrome或更高版本的浏览器!
</canvas>

当然,你要先获取画布哦

1
2
var canvas=document.querySelector('canvas');
var ctx=canvas.getContext('2d');

2.随机放置食物

x表示食物的大小 map是存放蛇身单元位置

var foodx=foody=?;定义食物的起点坐标
1
2
3
4
5
6
7
8
9
10
11
12
function food(x){
foodx=Math.ceil(Math.random()*canvas.width/x)*x-x;
foody=Math.ceil(Math.random()*canvas.height/x)*x-x;
//判断不让食物随机到蛇身上
map.forEach(function(e){
if (e.x==foodx&&e.y==foody) {
food(10);
}
})
ctx.fillStyle='#000';//食物颜色
ctx.fillRect(foodx,foody,x,x);//绘制矩形
}

3.蛇的移动及绘制

1.先做一个移动方向的判断

2.在做一个是否撞墙和撞自身的判断,这里用了forEach,你也可以用for循环代替

3.一个保证起始蛇身的判断

4.接下就就是绘制每一个蛇身单元,多个蛇身单元组成蛇身

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
function moveSnake(){
switch(direction){
case 37:x-=size;break;//左
case 38:y-=size;break;//上
case 39:x+=size;break;//右
case 40:y+=size;break;//下
}
//判断是否撞墙,撞墙则结束
if (x<0||y<0||x+size>canvas.width||y+size>canvas.height) {
end();
}
map.forEach(function(e){
if (e.x==x&&e.y==y) {
end();
}
})
if (map.length>snakeLength) {//保持蛇长
var last=map.shift();//删除数组第一项,并返回该元素
ctx.clearRect(last.x,last.y,size,size)
}
//把单元蛇身保存并绘制
map.push({"x":x,"y":y});
ctx.fillStyle='cyan';
ctx.fillRect(x,y,size,size);
if (x==foodx&&y==foody) {
food(10);
snakeLength++;
i++;
score.value=i*10;
}
}

这里写了当游戏结束时,显示的函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function end(){
clearInterval(timer);
if (score.value<100) {
alert('继续努力哦!\nGAME OVER')
}else if (score.value>=100) {
alert('哎呦,不错!\nGAME OVER')
}else if (score.value>=400) {
alert('非常棒!\nGAME OVER')
}else if (score.value>=800) {
alert('你已无人能挡!\nGAME OVER')
}else if (score.value>=1600) {
alert('无敌战神!\nGAME OVER')
}
window.location=window.location;//刷新页面
return;
}

增加游戏难度

你可以发挥你的想象来则加游戏难度,比如增加蛇的运动速度,canvas的画布变小等等

接下来就要讲讲键盘事件了

下面是键盘对应值:
keycode

按下键盘改变方向,这里我做了个space控制游戏的开始和暂停设置

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
var code=null;
var space=true;
document.onkeydown=function(event){
if (event.keyCode==32) {
if (space) {
timer=setInterval(moveSnake,60);
space=!space;
}else{
clearInterval(timer);
space=!space;
}
return;
}
//判断如果是相反键则失效
if (Math.abs(code-event.keyCode)==2) {
code=code;
}else{
code=event.keyCode;
}
switch(code){
case 37:direction=37;break;//左
case 38:direction=38;break;//下
case 39:direction=39;break;//右
case 40:direction=40;break;//上
}
}

如果需要源码,请前往:我的 github,转载请注明出处,谢谢!

很惭愧<br><br>只做了一点微小的工作<br>谢谢大家