javascript 贪吃蛇 源码 2

原型:https://blog.csdn.net/lsswear/article/details/109989622

修改内容: 加关卡 修改bug 障碍物、食物显示根据 map宽高获取随机数据

bug描述 :在地图清除时有食物残留,因为蛇迟到食物后马上新建食物在清除地图之后。

源码:

<!DOCTYPE html>
<!--https://www.jb51.net/article/154869.htm-->
<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, user-scalable=no,initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0">
	<mate http-equiv="X-UA-Compatible" content="ie=edge">
	<title>cluttonous snake</title>
	<style type="text/css" media="screen">
		body{
			margin:0;
			padding:0;
		}
		.main{
			width:800px;
			height:400px;
			margin:50px auto;
		}
		.btn{
			width:100px;
			height:40px;
		}
		.map{
			position:relative;
			width:100%;
			height: 100%;
			background: #ccc;
			overflow: hidden;
		}
	</style>
</head>
<body>
	<div class="main">
		<p>
			<button class="btn" id="begin">begin</button> &nbsp;
			level:<i id="level">0</i>&nbsp;
			line:<i id="line">0</i>&nbsp;
			score:<i id="score">0</i>&nbsp;
			speed:<i id="speed">0</i>&nbsp;
			<button class="btn" id="stop">stop</button> &nbsp;
		</p>
		<div class="map" id="map"></div>
		<script type="text/javascript">
			var map = document.getElementById('map');
			var speed = 500;
			var gameLevel = 1;
			var barrierNum = 10;
			function Snake(){
				this.width = 10;
				this.height = 10;
				this.step = 1;
				this.score = 0;
				this.times = 0;
				this.range = 1;
				this.endGame = false;
				this.maxWidth = Math.floor(map.clientWidth/this.width);
				this.maxHeight = Math.floor(map.clientHeight/this.height);
				//方向
				this.direction = 'right';

				this.body = [
					{x:2,y:0},
					{x:1,y:0},
					{x:0,y:0}
				];
				this.display = function(){
					for (var i =0 ; i <this.body.length; i++) {
						if(this.body[i].x !=null){
							var s = document.createElement('div');
							this.body[i].flag =s ;	
							s.style.width = this.width+'px';
							s.style.height = this.height+'px';
							s.style.borderRadius = '0%';
							//s.style.background = "rgb("+Math.floor(Math.random()*256)+","+Math.floor(Math.random()*256)+","+Math.floor(Math.random()*256)+")";
							s.style.background = "#fffccc";
							s.style.position = 'absolute';
							/*if(this.times>0){
								switch(this.direction){
									case "left":
										this.body[i].x -=this.step;
										break;
									case "right":
										this.body[i].x +=this.step;
										break;
									case "up":
										this.body[i].y -=this.step;
										break;
									case "down":
										this.body[i].y +=this.step;
										break;
								}	
							}*/
							var left = this.body[i].x*this.width;	
							var top = this.body[i].y*this.height;
							s.style.left = left+'px';
							s.style.top = top+'px';
							map.appendChild(s);
						}		
					}
					this.times++;
				}
				this.clear= function(){
					for(var i=0;i<this.body.length;i++){
						if(this.body[i].flag!=null){
							map.removeChild(this.body[i].flag);
						}
					}
					this.init();
				}
				this.init = function(){
					this.body = [
						{x:2,y:0},
						{x:1,y:0},
						{x:0,y:0},
					];
					this.score = 0;
					this.times = 0;
					this.direction="right";
					this.speed = 500;
				}
				this.changeSpeed = function(){
					if(this.score%30==0){
						if(speed>=100){
							speed -=50;	
						}
						clearInterval(timer);
						timer = setInterval("snake.run()",speed);
					}
				}
				this.checkIn = function(x,y){
					for (var i = 0; i < this.body.length; i++) {
						var item = this.body[i];
						if(x==item.x&&y==item.y){
							return true;
						}
					}
				}
				this.run = function(){
					for(var i=this.body.length-1;i>0;i--){
						this.body[i].x = this.body[i-1].x;
						this.body[i].y = this.body[i-1].y;
					}
					//改方向
					switch(this.direction){
						case "left":
							this.body[0].x -=1;
							break;
						case "right":
							this.body[0].x +=1;
							break;
						case "up":
							this.body[0].y -=1;
							break;
						case "down":
							this.body[0].y +=1;
							break;
					}
					//判断是否出界
					if(this.body[0].x<0||this.body[0].x>(this.maxWidth-1)
						||this.body[0].y<0||this.body[0].y>(this.maxHeight-1)){
						clearInterval(timer);
						alert(" GAME OVER &^&");
						restartGame(1);
						return false;
					}
					//吃到食物 蛇加一节
					//if(Math.abs(this.body[0].x-food.x)<=this.range && Math.abs(this.body[0].y-food.y)<=this.range){
					var header =this.body[0];
					var result = foods.checkIn(header.x,header.y);
					if(typeof result === 'number'){
						var foodIndex = result;
						this.body.push({x:null,y:null,flag:null});
						foods.clearItem(foodIndex);//清除食物
						this.score += foods.score;
						changeSpeed();
						changeView();
						if(!this.endGame){
							foods.displayItem();	
						}
					}
					//判断吃到自己
					for(var i=4;i<this.body.length;i++){
						if(this.body[0].x == this.body[i].x 
							&&this.body[0].y==this.body[i].y){
							clearInterval(timer);
							alert(" GAME OVER @^@");
							restartGame(1);
							return false;
						}
					}
					//判断碰到障碍物
					for (var i = 0; i < this.body.length; i++) {
						if(barrier.checkIn(this.body[i].x,this.body[i].y)){
							clearInterval(timer);
							alert(" GAME OVER (*^*)");
							restartGame(1);
							return false;	
						}
					}
					for(var i=0;i<this.body.length;i++){
						if(this.body[i].flag!=null){
							map.removeChild(this.body[i].flag);
						}
					}
					if(!this.endGame){
						this.display();	
					}
				}
			}
			//splice
			/*function Food(){
				this.width =10;
				this.height=10;
				this.score = 10;
				this.clear = function(){
					map.removeChild(this.flag);
				}
				this.display = function(){
					//排除障碍位置
					var f =document.createElement('div');
					this.flag =f;
					f.style.width = this.width+'px';
					f.style.height = this.height+'px';
					f.style.background = 'blue';
					f.style.borderRadius = '0%';
					f.style.position = 'absolute';
					do {
					    this.x = Math.floor(Math.random()*80);
						this.y = Math.floor(Math.random()*40);
					} while (barrier.checkIn(this.x,this.y));
					f.style.left = this.x*this.width+'px';
					f.style.top = this.y*this.height+'px';
					map.appendChild(f);					
				}
			}*/
			function Foods(){
				this.length = 4;
				this.score = 10;
				this.width =10;
				this.height=10;
				this.maxWidth = Math.floor(map.clientWidth/this.width);
				this.maxHeight = Math.floor(map.clientHeight/this.height);
				this.foods = [];
				this.clear = function(){
					this.foods.forEach(function(v,k){
					    if(typeof v.flag == 'object'){
					    	map.removeChild(v.flag);	
					    }
					    //this.clearItem(k);     
					 });  
					this.foods = [];
				}
				this.createPoint = function(){
					var x = Math.floor(Math.random()*this.maxWidth);
					var y = Math.floor(Math.random()*this.maxHeight);
					if(this.checkIn(x,y)||barrier.checkIn(x,y)||snake.checkIn(x,y)){
						return false;
					}else{
						return {x:x,y:y};
					}
				}
				this.checkIn = function(x,y){
					var result = false;
					this.foods.forEach(function(v,k){
						if(x==v.x&&y==v.y){
							result = k;
						}
					})
					return result;
				}
				this.getDIv = function() {
					var f =document.createElement('div');
					f.style.width = this.width+'px';
					f.style.height = this.height+'px';
					f.style.background = 'blue';
					f.style.borderRadius = '0%';
					f.style.position = 'absolute';
					return f;
				}
				this.clearItem = function(index){
					var obj = this.foods[index];
					if(typeof obj === 'object'){
						delete this.foods[index];
						map.removeChild(obj.flag);
					}
				}
				this.displayItem = function(){
					do{
						var obj = this.createPoint();
					}while(!obj)
					var x = obj.x;
					var y = obj.y;
					f = this.getDIv();
					f.style.left = x*this.width+'px';
					f.style.top = y*this.height+'px';
					this.foods.push({x:obj.x,y:obj.y,flag:f});
					map.appendChild(f);
				}
				this.display = function(){
					for (var i = 0; i < this.length; i++) {
						this.displayItem();	
					}	
				}
			}
			function  barrier(){
				this.width =10;
				this.height=10;
				//this.barrierLength = Math.floor(Math.random()*3);
				this.maxWidth = Math.floor(map.clientWidth/this.width);
				this.maxHeight = Math.floor(map.clientHeight/this.height);
				this.barrier = [];
				this.barrierLength = barrierNum;
				this.color = '#123456';
				this.clear = function(){
					for(var i=0;i<this.barrier.length;i++){
						var line = this.barrier[i];
						for (var j = 0; j < line.length; j++) {
							map.removeChild(item[j].flag);
						}
					}
					this.barrier = [];
				}
				this.createStartPoint = function(){
					var x = Math.floor(Math.random()*this.maxWidth);
					var y = Math.floor(Math.random()*this.maxHeight);	
					var direction = Math.floor(Math.random()*5);
					direction = direction<=0?1:direction;		
					x = x<4?4:x;
					y = y<3?3:y;
					var startPoint = {x:x,y:y,direction:direction};
					$result = this.checkStartPoint(x,y,direction);
					if(!$result){
						return false;
					}else{
						return {x:x,y:y,direction:direction};	
					}
				}
				this.checkIn = function(x,y){
					for (var i = 0; i < this.barrier.length; i++) {
						var line = this.barrier[i];
						for(var j = 0;j < line.point.length; j++){
							var item = line.point[j];
							if(x==item.x&&y==item.y){
								return true;
							}
						}
					}
					return false;
				}
				this.checkStartPoint = function(x,y,direction){
					var length = this.barrier.length;
					if(length>0){
						for (var i = 0; i < length; i++) {
							var objDirection = this.barrier[i].direction;
							var obj =this.barrier[i].point;
							var dWidth = Math.abs(obj[0].x-x);
							var dHeiht = Math.abs(obj[0].y-y);
							if((dWidth<=0||dHeiht<=0)&&objDirection==direction){
								return false;
							}
						}	
					}
					return true;
				}
				this.craeteBarrier = function(){
					for (var i = 0; i < this.barrierLength; i++) {
						var length = Math.floor(Math.random()*4);
						length = length<=0?3:length;
						//起始位置
						var startPoint = false;
						do{
							startPoint = this.createStartPoint();
						}while(!startPoint);
						var x = startPoint.x;
						var y = startPoint.y;	
						var direction = startPoint.direction;
						var body = {point:[],direction:direction};
						for (var j = 0; j < length; j++) {
							switch(direction){
								/*case 0:
									x +=1;
									y +=1;
								break;*/
								case 1:
									y -=1;//上
								break;
								case 2:
									y +=1;//下
								break;
								case 3:
									x -=1;//左
								break;
								case 4:
									x +=1;//右
								break;
								/*case 5:
									x -=1;
									y +=1;
								break;*/
							}
							body.point.push({x:x,y:y});	
						}
						this.barrier.push(body);
					}
				}
				this.display = function(){
					this.craeteBarrier();
					for (var i = 0; i < this.barrierLength; i++) {
						var barrierItem = this.barrier[i].point;
						for (var j = 0; j < barrierItem.length; j++) {
							var item = barrierItem[j];
							var b = document.createElement('div');
							b.style.width = this.width+'px';
							b.style.height = this.height+'px';
							b.style.background = this.color;
							b.style.borderRadius = '0%';
							b.style.position = 'absolute';
							b.style.left = item.x*this.width+'px';
							b.style.top = item.y*this.height+'px';
							this.barrier[i].flag = b;
							map.appendChild(b);	
						}
					}
				}	
			}
			document.body.onkeydown = function(e){
				var ev = e || window.event;
				switch(ev.keyCode){
					case 37:
						if(snake.direction !="right"){
							snake.direction = "left";
						}
						break;
					break;
					case 38:
						if(snake.direction !="down"){
							snake.direction = "up";	
						}
						break;
					break;
					case 39:
						if(snake.direction!="left"){
							snake.direction = "right";
						}
					break;
					case 40:
						if(snake.direction!="up"){
							snake.direction="down";
						}
					break;
				}
			}
			var begin = document.getElementById('begin');
			var isTemp = false;
			var stop = document.getElementById('stop');
			var timer;
			function initGame(){
				barrier.display();
				snake.display();
				foods.display();
				isTemp = false;	
				changeView();
			}
			function initLeve(){
				changeGameLevel(gameLevel);
			}
			function clearMap(){
				map.innerHTML = '';
			}
			function clearGame(){
				barrier.clear();
				snake.clear();
				foods.clear();
				clearMap();
			}
			function restartGame(level){
				if(1==level){
					gameLevel = 1;
				}
				initLeve();
				clearGame();
				initGame();
			}
			function changeView(){
				var scoreDiv = document.getElementById('score');
				var speedDiv = document.getElementById('speed');
				var levelDiv = document.getElementById('level');
				var lineDiv = document.getElementById('line');
				scoreDiv.innerHTML = snake.score;
				speedDiv.innerHTML = speed;
				levelDiv.innerHTML = gameLevel;
				lineDiv.innerHTML = barrierNum;
			}
			function changeSpeed(){
				//每一百分一关
				if(snake.score%20==0){
					/*if(speed>=100){
						speed -=50;	
					}
					clearInterval(timer);
					timer = setInterval("snake.run()",speed);*/
					if(gameLevel<=2){
						gameLevel += 1;	
						restartGame();
						alert('congratulation level:'+gameLevel);
					}else{
						clearInterval(timer);
						snake.endGame = true;
 						alert('~ game over ~ o(* ̄▽ ̄*)ブ');
						clearGame();
						//foods.clear();
					}
				}
			}
			function changeGameLevel(){
				switch(gameLevel){
					case 1:
						speed = 400;
						barrierNum = 2;
					break;
					case 2:
						speed = 300;
						barrierNum = 3;
					break;
					case 3:
						speed = 200;
						barrierNum = 4;
					break;
				}
				barrier.barrierLength = barrierNum;
			}
			initLeve();
			var snake = new Snake();
			var foods = new Foods();
			var barrier = new barrier();
			initGame();
			begin.onclick = function(){
				clearInterval(timer);
				timer = setInterval("snake.run()",speed);
			}
			stop.onclick = function(){
				clearInterval(timer);
			}
		</script>
	</div>
</body>
</html>

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lsswear

感谢大佬打赏 q(≧▽≦q)

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值