JS贪吃蛇

  随着学习的慢慢深入,对JS的了解也在慢慢一点一点的增加,第一次真正的体会到了JS的基于面向对象的编程,虽然JS只是一种脚本语言,但功能还是很强大的,经过这次的JS贪吃蛇编程,让我对编程语言有了更深一步的认识,编程并不是你会的语言越多越好,而是对一门语言深入进去,其他的都是大同小异,也渐渐的认识到了,编程最重要的还是自己解决问题的思路,当思路有了,一切的问题都是小问题,我这个游戏虽然是最简单的贪吃蛇游戏,但我自己从中也学到了很多的知识,认识到了很多的问题。

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title>JS贪吃蛇</title>
		<style type="text/css">
		  .map {
		  	width: 800px;
		  	height: 600px;
		  	background-color: #ccc;
		  	position: relative;//设置地图为相对定位
		  }	
		</style>
	</head>
	<body>
		<div class="map" id="map">
			
		</div>
		
		
		<script type="text/javascript">
			//食物的自调用函数
			(function(){
				var foodElements = [];//食物数组,用来保存每个小方块食物
				//创建食物的构造函数
				function Food(x,y,width,height,color){
					//小方块食物的各项属性,设置默认值
					this.x = x||0;
					this.y = y||0;
					this.width = width||20;
					this.height = height||20;
					this.color = color||"green";
				}
				//为Food原型添加初始化方法,将食物添加到地图里
				Food.prototype.init = function(map){
					removeFood();
					//传入map地图,确定食物要显示在那张地图里
					
					//创建食物
					var foodDiv = document.createElement("div");
					//将食物添加到地图map里
					map.appendChild(foodDiv);
					//为食物盒子设置样式
					foodDiv.style.width = this.width + "px";
					foodDiv.style.height = this.height + "px";
					foodDiv.style.backgroundColor = this.color;
					//随机产生食物盒子的横纵坐标,食物盒子的横纵坐标是随机产生的,不应当是固定的
					this.x = parseInt(Math.random()*(map.offsetWidth/this.width))*this.width;
					this.y = parseInt(Math.random()*(map.offsetHeight/this.height))*this.height;
					foodDiv.style.left = this.x + "px";
					foodDiv.style.top = this.y + "px";
					//食物盒子在map地图中,应当是浮动的,将食物盒子设置为绝对定位
					foodDiv.style.position = "absolute";
					//将创建好的食物添加到食物数组foodElements中
					foodElements.push(foodDiv);
				};
				//将Food构造函数挂到window中,以便外部可以直接调用
				
				//食物的删除方法--私有函数,仅食物对象自己能调用
				function removeFood(){
					//利用map父节点删除foodDiv食物节点
					for (var i = 0;i<foodElements.length;i++) {
						//找到需要删除的子元素
						var ele = foodElements[i];
						//获取该子元素的父节点
						ele.parentNode.removeChild(ele);
		//<------以上仅将地图里的食物删除掉,还需将食物数组foodElements里的该元素也删除掉----->//
		                foodElements.splice(i,1);
		                
					}
				}
				
				
				window.Food = Food;
				
			}());
			



			//小蛇的自调用函数
			(function(){
				//小蛇的构造函数
				var snakeElements = [];//存放小蛇的每个身体部分
				function Snake(width,height,direction){
					this.width = width||20;
					this.height = height||20;
					this.direction = direction||"right";
					//创建数组用以存放小蛇的身体
					this.snakeBody = [
					   {x:3,y:1,color:"red"},//蛇的头部
					   {x:2,y:1,color:"orange"},
					   {x:1,y:1,color:"orange"},
					];
				}
				//小蛇的初始化方法,需反复调用,将这个初始化方法添加到原型对象里
				Snake.prototype.init = function(map){//传入地图map,确定小蛇的位置
					//每次移动时,均会重新绘制小蛇,所以需要在重新绘制之前将原来的小蛇删除掉,以形成小蛇移动的效果
					removeSnake();
					//循环遍历snakeElements数组,初始化小蛇的身体各个部分
					for (var i = 0;i<this.snakeBody.length;i++) {

						var obj = this.snakeBody[i];
						//创建小蛇身体的各个部分,并将小蛇加入到地图map里
						var snakeDiv = document.createElement("div");
						map.appendChild(snakeDiv);
						//设置小蛇身体的属性
						snakeDiv.style.position = "absolute";
						snakeDiv.style.width = this.width+"px";
						snakeDiv.style.height = this.height+"px";
						//小蛇的横纵坐标
						snakeDiv.style.left = (obj.x*20)+"px";
						snakeDiv.style.top = (obj.y*20)+"px";
						snakeDiv.style.backgroundColor = obj.color;
						
						
						//将创建好的小蛇身体添加到snakeElements数组里
						snakeElements.push(snakeDiv);
					}
					//添加小蛇运动的方法
					Snake.prototype.move = function (food,map){
						var i = this.snakeBody.length - 1;
						//改变蛇身体各个部分的横纵坐标
						for (;i>0;i--) {
							//for (;i<0;i--) :错误,for中的i<0为判断条件,当判断条件为i<0时,该循环永不执行
							this.snakeBody[i].x = this.snakeBody[i-1].x;
							this.snakeBody[i].y = this.snakeBody[i-1].y;
						}
						//判断方向改变小蛇头部的位置
						switch(this.direction){
							case "right":this.snakeBody[0].x+=1;break;
							case "left":this.snakeBody[0].x-=1;break;
							case "top":this.snakeBody[0].y-=1;break;
							case "bottom":this.snakeBody[0].y+=1;break;
						}
						
						   //判断有没有吃到食物
					      //小蛇的头的坐标和食物的坐标一致
					      var headX=this.snakeBody[0].x*this.width;
					      var headY=this.snakeBody[0].y*this.height;
					      //判断小蛇的头的坐标和食物的坐标是否相同
					      if(headX==food.x&&headY==food.y){
					        //获取小蛇的最后的尾巴
					        var snakeLast=this.snakeBody[this.snakeBody.length-1];
					        //把最后的蛇尾复制一个,重新的加入到小蛇的snakeBody中
					        this.snakeBody.push({
					          x:snakeLast.x,
					          y:snakeLast.y,
					          color:snakeLast.color
					        });
					        //把食物删除,重新初始化食物
					        food.init(map);
					      }
					}
					
					//小蛇的删除方法
					function removeSnake(){
						//在创建小蛇时,将小蛇添加到了snakeElements中,所以在删除小蛇时应当从保存小蛇的
						//snakeElements数组中入手
						var i = snakeElements.length-1;
						for (;i>=0;i--) {
							//小蛇对象存在与map对象中,所以在删除小蛇时,先找到小蛇身体对象的父级元素即:map
							//然后再利用map对象删除这个小蛇的身体对象
							var ele = snakeElements[i];
							ele.parentNode.removeChild(ele);
			//<------以上仅将地图里的小蛇删除掉,还需将食物数组snakeElements里的该元素也删除掉----->//
							snakeElements.splice(i,1);
						}
					}
					
					
				};
				window.Snake = Snake;
			}());
			
            //游戏的自调用函数
            (function(){
            	var that = null;
            	//游戏的构造函数
            	function Game(map){
            		this.food = new Food();
            		this.snake = new Snake();
            		this.map = map;
            		that = this;
            	};
            	//初始化游戏
            	Game.prototype.init = function(){
            		//食物初始化
            		this.food.init(this.map);
            		//小蛇初始化
            		this.snake.init(this.map);

                   //调用自动函数,让小蛇动起来
                   this.runSnake(this.food,this.map);
                   //调用按键的方法
                   this.bindKey();
            	};
            
                //设置原型方法,让小蛇可以自动的运动起来
               Game.prototype.runSnake = function (food, map) {
               //自动的去移动
                 var timeId = setInterval(function () {
                      //此时的this是window
                      //移动小蛇
                    this.snake.move(food, map);
                    //初始化小蛇
                   this.snake.init(map);
				    //横坐标的最大值
				    var maxX = map.offsetWidth / this.snake.width;
				    //纵坐标的最大值
				    var maxY = map.offsetHeight / this.snake.height;
				    //小蛇的头的坐标
				    var headX = this.snake.snakeBody[0].x;
				    var headY = this.snake.snakeBody[0].y;
				    //横坐标
				    if (headX < 0 || headX >= maxX) {
				      //撞墙了,停止定时器
				      clearInterval(timeId);
				      alert("游戏结束");
				    }
				    //纵坐标
				    if (headY < 0 || headY >= maxY) {
				      //撞墙了,停止定时器
				      clearInterval(timeId);
				      alert("游戏结束");
				    }
                   
                   }.bind(that), 150);
               };
   
                 //添加原型方法---设置用户按键,改变小蛇移动的方向
			    Game.prototype.bindKey=function () {
			      //获取用户的按键,改变小蛇的方向,
			      //addEventListener为document对象绑定keydown事件
			      document.addEventListener("keydown",function (e) {
			        //这里的this应该是触发keydown的事件的对象---document,
			        //所以,这里的this就是document
			        //获取按键的值
			        switch (e.keyCode){
			          case 65:this.snake.direction="left";break;
			          case 87:this.snake.direction="top";break;
			          case 68:this.snake.direction="right";break;
			          case 83:this.snake.direction="bottom";break;
			        }
			      }.bind(that),false);
			    };
    
           window.Game = Game;
            }());
            
            
			  //初始化游戏对象
			  var gm = new Game(document.getElementById("map"));
			  //初始化游戏---开始游戏
			  gm.init();





			
					
		</script>
	</body>
</html>

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值