初步学习了javascript,我就按耐不住想写个项目看看,现在分享到这里和大家分享探讨。
大致思路:
- 用canvas画布制作网状格背景
- 绘制食物,20*20的网状格中随机分布(用Math.random()实现)
- 绘制蛇,让蛇动起来(蛇看做二维具有x,y属性的数组,pop出最后一个元素,unshift()新添一个元素(蛇头))
- 蛇吃食物(通过判断蛇头与食物的坐标,判定蛇是否能吃掉食物)
- 边界以及蛇自咬的判断
本人疑惑:
第64行以及第73行中,snake[0]和newhead有什么实质性的区别吗?我找这个错误找了很久,但是不太明白它们有什么区别。
本代码还没解决的地方:
蛇触碰到边界后,不是立即游戏终止,蛇身还是减少一节,什么改善代码解决这个问题?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Snake</title>
<style>
#drow{
background-color:#ccc;
display:block;
margin:0 auto;
}
</style>
</head>
<body>
<canvas id="drow" width="600px" height="600px" ></canvas>
<script>
var drow=document.getElementById("drow");
var tools=drow.getContext('2d');
var isAted=false;//设置标记:食物是否被蛇吃掉,默认没有被吃掉
var isgameover=false;//设置游戏状态值,默认没有结束
var snake=[{x:3,y:0},{x:2, y:0},{x:1 ,y:0}];//默认蛇的坐标和节数
var xdirection=1,ydirection=0;//默认蛇向正右方行进
var xfood=Math.floor(Math.random()*20)*30;//生成随机的食物的x坐标
var yfood=Math.floor(Math.random()*20)*30;//生成随机的食物的y坐标
/*------------------用setInterval实现动画,先擦除,再绘制---------------------*/
window.setInterval(clock,200);
function clock()
{
if(isgameover==false)
{
tools.clearRect(0,0,600,600);
/*-------------------------------键控蛇的动作------------------------------*/
document.addEventListener('keydown',function(event)//监听键盘按下的行为, 上:38 下:40 左:37 右:39
{
switch(event.keyCode)
{
case 38:xdirection=0; ydirection=-1; break;
case 40:xdirection=0; ydirection=1; break;
case 37:xdirection=-1; ydirection=0; break;
default:xdirection=1; ydirection=0;
}
})
/*-------------------------------绘制食物----------------------------------*/
if(isAted==true)
{
xfood=Math.floor(Math.random()*20)*30;//生成随机的食物的x坐标
yfood=Math.floor(Math.random()*20)*30;//生成随机的食物的y坐标
}
tools.fillStyle="orange";
tools.fillRect(xfood,yfood,30,30);
/*------------------ 绘制蛇,通过pop(),unshift()让蛇动起来---------------------*/
var oldhead=snake[0];//旧蛇头
var newhead={x:oldhead.x+xdirection, y:oldhead.y+ydirection}//新蛇头
//if(newhead.x==xfood && newhead.y==yfood) 错误教训:一定要注明是哪个数组元素的属性!!!
if(snake[0].x*30==xfood && snake[0].y*30==yfood) {isAted=true;}//判断蛇是否吃到食物
else
{
isAted=false;
snake.pop();
}
}
for(var i=2;i<snake.length;i++)
{
if(newhead.x==snake[i].x && newhead.y==snake[i].y)//判断蛇是否自咬
{
alert("Game Over, you killed by yourself.");
isgameover=true;
}
}
if(newhead.x<0||newhead.x*30>=600||newhead.y<0||newhead.y*30>=600) isgameover=true;//判断蛇是否出界
else snake.unshift(newhead);
for(var i=0;i<snake.length;i++)
{
if(i==0) tools.fillStyle="red";//设置蛇头颜色为红色
else tools.fillStyle="blue"; //设置蛇身颜色为蓝色
tools.fillRect(snake[i].x*30,snake[i].y*30,30,30);
}
/*-------------------------------绘制画布线--------------------------------*/
for(var i=1;i<20;i++)//绘制19条等间距水平线
{
tools.moveTo(0,i*30+0.5);
tools.lineTo(600,i*30+0.5);
}
for(var i=1;i<20;i++)//绘制19条等间距垂直线
{
tools.moveTo(i*30+0.5,0);
tools.lineTo(i*30+0.5,600);
}
tools.strokeStyle="white";//设置线的颜色
tools.stroke();//真正执行画线的动作
if(isgameover==true) alert("Game Over!");
}
</script>
</body>
</html>