话不多说,直接上代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script type="text/javascript">
var body; // 全局变量们,因为后面还需要获取
var _map;
var _food;
var _snake;
window.onload=function(){
body=document.querySelector('body');
_map= new Map(); // 实例化以及方法的调用
_food=new Food();
_food.display();
_snake= new Snake();
_snake.display();
_snake.move();
body.onkeydown=function(event){
// console.log(event.keyCode);
_snake.setdirect(event.keyCode);
}
}
function Map(){ // 地图
this.div_map=document.createElement('div');
this.div_map.style.width=800+'px';
this.div_map.style.height=600+'px';
this.div_map.style.background='seagreen';
this.div_map.style.margin='40px auto';
this.div_map.style.position='relative';
body.appendChild(this.div_map);
}
function Food(){ // 食物
this.width=20;
this.height=20;
this.color='red';
this.div_food=document.createElement('div'); //创建食物提到display外面
this.display=function(){
this.div_food.style.width=this.width+'px';
this.div_food.style.height=this.height+'px';
this.div_food.style.background=this.color;
this.div_food.style.position='absolute'; // 父相对定位子绝对定位
this.div_food.style.top=(Math.round(Math.random()*29))*(this.height)+'px'; // 食物随机位置
this.div_food.style.left=(Math.round(Math.random()*39))*(this.width)+'px';
this.y=parseInt(this.div_food.style.top); // 留后判断吃食用
this.x=parseInt(this.div_food.style.left);
_map.div_map.appendChild(this.div_food);
}
}
function Snake(){ // 蛇
this.width=20;
this.height=20;
this.snakearr=[
[7,1,null,"red"], // 蛇的横纵坐标,蛇身div,蛇的颜色
[6,1,null,"white"],
[5,1,null,"white"]
];
this.side=null;
this.sideboolean=true; // 属性(方向bool值)用来锁死方向:向左移动时右键失效,否则蛇会穿过自身运动
this.display=function(){
for(var i=0;i<this.snakearr.length;i++){
if (this.snakearr[i][2]==null) { // 为null才创建,否则移动过程中会重复创建
this.snakearr[i][2]=document.createElement('div');
this.snakearr[i][2].style.width=this.width+'px';
this.snakearr[i][2].style.height=this.height+'px';
this.snakearr[i][2].style.background=this.snakearr[i][3];
this.snakearr[i][2].style.position='absolute';
this.snakearr[i][2].style.borderRadius='50%';
_map.div_map.appendChild(this.snakearr[i][2]);
}
this.snakearr[i][2].style.top=this.snakearr[i][1]*this.height+'px'; // 坐标*相应的单位距离=实际距离
this.snakearr[i][2].style.left=this.snakearr[i][0]*this.width+'px';
}
}
this.setdirect=function(code){ //保存蛇运动方向的方法(按下键盘后需要让蛇保持运动状态,需要保存其方向,否则按一下走一下)
switch (code){
case 37: // 键码
this.side='left'; // 通过键码,即按下的键给方向属性赋值
break;
case 38:
this.side='up';
break;
case 39:
this.side='right';
break;
case 40:
this.side='down';
break;
default:
break;
}
}
this.move=function(){ // 蛇移动的方法
if (this.side!=null) {
for (var i=this.snakearr.length-1;i>0;i--) {
this.snakearr[i][0]=this.snakearr[i-1][0]; // 将上一节蛇的位置赋给下一节
this.snakearr[i][1]=this.snakearr[i-1][1];
}
switch (this.side){
case 'left': // 根据方向属性的值判断蛇的具体移动实现
this.snakearr[0][0]-=1;
this.display(); // 每次改变坐标值都需调用一次蛇的显示方法,才真正实现了移动,每一个case里都写,因为可以通过函数传参来实现蛇头的转向,不过在这个基础功能版本里没加蛇头的旋转
break;
case 'right':
this.snakearr[0][0]+=1;
this.display();
break;
case 'up':
this.snakearr[0][1]-=1;
this.display();
break;
case 'down':
this.snakearr[0][1]+=1;
this.display();
break;
default:
break;
}
}
if (_food.x==(this.snakearr[0][0])*20 && _food.y==(this.snakearr[0][1])*20) { // 吃到食物
_food.display();
var x=this.snakearr[this.snakearr.length-1][0];
var y=this.snakearr[this.snakearr.length-1][1];
this.snakearr.push([x,y,null,"white"]);
_snake.display();
}
if (this.snakearr[0][0] < 0 || this.snakearr[0][0] > 39 || this.snakearr[0][1] < 0 || this.snakearr[0][1] > 29) { // 碰壁
clearTimeout(timer);
alert('game over');
location.reload();
}
var timer= setTimeout('_snake.move()',200);
}
}
</script>
</head>
<body>
</body>
</html>