var sw=20, //一个方块的宽 sh=20, //一个方块的高 tr=30, //行数 td=30; //列数
var snake=null, //蛇的实例 food=null, //食物的实例 game=null; //游戏的实例
function Square(x,y,classname){ //0,0 //20,0 1,0 //40,0 2,0 this.x=x*sw; this.y=y*sh; this.class=classname;
this.viewContent=document.createElement('div'); //Dom元素 this.viewContent.className=this.class; this.parent=document.getElementById('snakeWrap'); //方块的父级
} Square.prototype.create=function(){ this.viewContent.style.position='absolute'; this.viewContent.style.width=sw+'px'; this.viewContent.style.height=sh+'px'; this.viewContent.style.left=this.x+'px'; this.viewContent.style.top=this.y+'px';
this.parent.appendChild(this.viewContent); }; Square.prototype.remove=function(){ this.parent.removeChild(this.viewContent); };
//蛇 function Snake(){ this.head=null; //蛇头 this.tail=null; //蛇尾 this.pos=[]; //存储在蛇身上的每一个方块的位置
this.directionNum={ //蛇走的方向
left:{ x:-1, y:0, rotate:180 //蛇头在不同的方向中进行旋转, }, right:{ x:1, y:0, rotate:0 }, up:{ x:0, y:-1, rotate:-90 }, down:{ x:0, y:1, rotate:90 } } } Snake.prototype.init=function(){ //创建蛇头 var snakeHead=new Square(2,0,'snakeHead'); snakeHead.create(); this.head=snakeHead; //存储蛇头信息 this.pos.push([2,0]); //蛇头位置存储
//创建蛇身体 var snakeBody1=new Square(1,0,'snakeBody'); snakeBody1.create(); this.pos.push([1,0]); //蛇身1的坐标存储
var snakeBody2=new Square(0,0,'snakeBody'); snakeBody2.create();
this.tail=snakeBody2; //把蛇尾存起来 this.pos.push([0,0]); //蛇身2的坐标存储
//形成链表关系 snakeHead.last=null; snakeHead.next=snakeBody1;
snakeBody1.last=snakeHead; snakeBody1.next=snakeBody2;
snakeBody2.last=snakeBody1; snakeBody2.next=null;
//给蛇添加一个属性,用来表示蛇的方向。 this.direction=this.directionNum.right; }; //这个方法用来获取 蛇头的下一个位置对应的元素,要个根据元素做不同的事情 Snake.prototype.getNextPos=function(){ var nextPos=[ //蛇头要走的下一个点的坐标 this.head.x/sw + this.direction.x, this.head.y/sh + this.direction.y ]
//游戏结束条件
//撞自己 var selfCollied=false; this.pos.forEach(function(value){ if(value[0]==nextPos[0] && value[1]==nextPos[1]){ //如果数组中的两个数据都相等,就说明下一个点在蛇身上里面能找到,代表撞到自己。 selfCollied=true; } }); if(selfCollied){ console.log('撞到自己');
this.strategies.die.call(this);
return; } //撞墙 if(nextPos[0]<0 || nextPos[1]<0 || nextPos[0]>td-1 || nextPos[1]>tr-1){ console.log('撞墙了');
this.strategies.die.call(this);
return; } //吃食物 // this.strategies.eat(); if(food && food.pos[0]==nextPos[0] && food.pos[1]==nextPos[1]){ //这个条件成立说明现在蛇头要走的下一个点是食物的位置。 console.log('吃食物') this.strategies.eat.call(this) return; }
//移动 this.strategies.move.call(this);
};
//碰撞处理 Snake.prototype.strategies={
move:function(format){ //决定是否删除蛇尾 //创建新身体(在旧蛇头的位置) var newBody=new Square(this.head.x/sw,this.head.y/sh,'snakeBody'); //更新链表关系 newBody.next=this.head.next; newBody.next.last=newBody; newBody.last=null;
this.head.remove(); newBody.create();
//创建一个新蛇头(蛇头下一个要走的点) var newHead=new Square(this.head.x/sw + this.direction.x,this.head.y/sh + this.direction.y,'snakeHead') //更新链表关系 newHead.next=newBody; newHead.last=null; newBody.last=newHead; newHead.viewContent.style.transform='rotate('+this.direction.rotate+'deg)'; newHead.create();
//蛇身上的每一个方块的坐标更新 //this.pos this.pos.splice(0,0,[this.head.x/sw + this.direction.x,this.head.y/sh + this.direction.y]); this.head=newHead; //更新头部信息
if(!format){ this.tail.remove(); this.tail=this.tail.last;
this.pos.pop(); }
}, eat:function(){ this.strategies.move.call(this,true);
createFood(); game.score++; }, die:function(){ console.log('死'); game.over(); } } snake=new Snake(); // snake.init(); // snake.getNextPos();
//创建食物 function createFood(){ //食物随机坐标 var x=null; var y=null;
var include=true; //随机生成的坐标 true在蛇身上!(需要继续循环) false不在蛇身上(不循环)
while(include){ x=Math.round(Math.random()*(td-1)); y=Math.round(Math.random()*(tr-1)); snake.pos.forEach(function(value){ if(x!=value[0] && y!=value[1]){ //随即坐标不在蛇身上 include=false } });
}
//生成食物 food=new Square(x,y,'food'); food.pos=[x,y]; //存储以下生成食物的坐标,用于跟蛇头要走的下一个点做对比 var foodDom=document.querySelector('.food'); if(foodDom){ foodDom.style.left=x*sw +'px'; foodDom.style.top=y*sh +'px'; }else{ food.create(); } }
//创建游戏逻辑 function Game(){ this.timer=null; this.score=0; } Game.prototype.init=function(){ snake.init(); createFood();
document.onkeydown=function(ev){ if(ev.which==37 && snake.direction!=snake.directionNum.right){ snake.direction=snake.directionNum.left; }else if(ev.which==38 && snake.direction!=snake.directionNum.down){ snake.direction=snake.directionNum.up; }else if(ev.which==39 && snake.direction!=snake.directionNum.left){ snake.direction=snake.directionNum.right; }else if(ev.which==40 && snake.direction!=snake.directionNum.up){ snake.direction=snake.directionNum.down; } } this.start(); } Game.prototype.start=function(){ this.timer=setInterval(function(){ snake.getNextPos(); },200); } Game.prototype.pause=function(){ clearInterval(this.timer); } Game.prototype.over=function(){ clearInterval(this.timer); alert('你的得分为:'+ this.score); //游戏回归初始状态 var snakeWrap=document.getElementById('snakeWrap'); snakeWrap.innerHTML = '';
snake=new Snake(); game=new Game();
var startBtnWrap=document.querySelector('.startBtn'); startBtnWrap.style.display='block';
}
//开始游戏 game=new Game();
var startBtn=document.querySelector('.startBtn button');
startBtn.onclick=function(){ startBtn.parentNode.style.display='none'; game.init(); };
//暂停游戏 var snakeWrap=document.getElementById('snakeWrap');
var pauseBtn=document.querySelector('.pauseBtn button');
snakeWrap.onclick=function(){
game.pause();
pauseBtn.parentNode.style.display='block'; } pauseBtn.onclick=function(){ game.start(); pauseBtn.parentNode.style.display='none'; }
|