javascript:用原生js模拟贪吃蛇游戏练习

本次练习全部的代码:能够直接复制所有而后运行看效果~html

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4   <meta charset="UTF-8">
 5   <title>title</title>
 6   <style>
 7  .map {
 8  width: 800px;
 9  height: 600px;
 10  background-color: #CCC;
 11  position: relative;
 12     }
 13   </style>
 14 </head>
 15 <body>
 16 <!--画出地图,设置样式-->
 17 <div class="map"></div>
 18 <script>
 19 
 20 
 21   //自调用函数----食物的
 22  (function () {  23     var elements = [];//用来保存每一个小方块食物的
 24     //食物就是一个对象,有宽,有高,有颜色,有横纵坐标,先定义构造函数,而后建立对象
 25     function Food(x, y, width, height, color) {  26       //横纵坐标
 27       this.x = x || 0;  28       this.y = y || 0;  29       //宽和高
 30       this.width = width || 20;  31       this.height = height || 20;  32       //背景颜色
 33       this.color = color || "green";  34  }  35 
 36     //为原型添加初始化的方法(做用:在页面上显示这个食物)
 37     //由于食物要在地图上显示,因此,须要地图的这个参数(map---就是页面上的.class=map的这个div)
 38  Food.prototype.init = function (map) {  39       //先删除这个小食物
 40       //外部没法访问的函数
 41  remove();  42 
 43       //建立div
 44       var div = document.createElement("div");  45       //把div加到map中
 46  map.appendChild(div);  47       //设置div的样式
 48  div.style.width = this.width + "px";  49  div.style.height = this.height + "px";  50  div.style.backgroundColor = this.color;  51       //先脱离文档流
 52  div.style.position = "absolute";  53       //随机横纵坐标
 54       this.x = parseInt(Math.random() * (map.offsetWidth / this.width)) * this.width;  55       this.y = parseInt(Math.random() * (map.offsetHeight / this.height)) * this.height;  56  div.style.left = this.x + "px";  57  div.style.top = this.y + "px";  58 
 59       //把div加入到数组elements中
 60  elements.push(div);  61  };  62 
 63     //私有的函数---删除食物的
 64     function remove() {  65       //elements数组中有这个食物
 66       for (var i = 0; i < elements.length; i++) {  67         var ele = elements[i];  68         //找到这个子元素的父级元素,而后删除这个子元素
 69  ele.parentNode.removeChild(ele);  70         //再次把elements中的这个子元素也要删除
 71  elements.splice(i, 1);  72  }  73  }  74 
 75     //把Food暴露给Window,外部能够使用
 76  window.Food = Food;  77  }());  78 
 79   //自调用函数---小蛇
 80  (function () {  81     var elements = [];//存放小蛇的每一个身体部分
 82     //小蛇的构造函数
 83     function Snake(width, height, direction) {  84       //小蛇的每一个部分的宽
 85       this.width = width || 20;  86       this.height = height || 20;  87       //小蛇的身体
 88       this.body = [  89  {x: 3, y: 2, color: "red"},//
 90  {x: 2, y: 2, color: "orange"},//身体
 91  {x: 1, y: 2, color: "orange"}//身体
 92  ];  93       //方向
 94       this.direction = direction || "right";  95  }  96 
 97     //为原型添加方法--小蛇初始化的方法
 98  Snake.prototype.init = function (map) {  99       //先删除以前的小蛇
100  remove();//===========================================
101 
102       //循环遍历建立div
103       for (var i = 0; i < this.body.length; i++) { 104         //数组中的每一个数组元素都是一个对象
105         var obj = this.body[i]; 106         //建立div
107         var div = document.createElement("div"); 108         //把div加入到map地图中
109  map.appendChild(div); 110         //设置div的样式
111  div.style.position = "absolute"; 112  div.style.width = this.width + "px"; 113  div.style.height = this.height + "px"; 114         //横纵坐标
115  div.style.left = obj.x * this.width + "px"; 116  div.style.top = obj.y * this.height + "px"; 117         //背景颜色
118  div.style.backgroundColor = obj.color; 119         //方向暂时不定
120         //把div加入到elements数组中----目的是为了删除
121  elements.push(div); 122  } 123  }; 124 
125     //为原型添加方法---小蛇动起来
126  Snake.prototype.move = function (food, map) { 127       //改变小蛇的身体的坐标位置
128       var i = this.body.length - 1;//2
129       for (; i > 0; i--) { 130         this.body[i].x = this.body[i - 1].x; 131         this.body[i].y = this.body[i - 1].y; 132  } 133       //判断方向---改变小蛇的头的坐标位置
134       switch (this.direction) { 135         case "right": 136           this.body[0].x += 1; 137           break; 138         case "left": 139           this.body[0].x -= 1; 140           break; 141         case "top": 142           this.body[0].y -= 1; 143           break; 144         case "bottom": 145           this.body[0].y += 1; 146           break; 147  } 148 
149       //判断有没有吃到食物
150       //小蛇的头的坐标和食物的坐标一致
151       var headX=this.body[0].x*this.width; 152       var headY=this.body[0].y*this.height; 153       //判断小蛇的头的坐标和食物的坐标是否相同
154       if(headX==food.x&&headY==food.y){ 155         //获取小蛇的最后-的尾巴
156         var last=this.body[this.body.length-1]; 157         //把最后的蛇尾复制一个,从新的加入到小蛇的body中
158         this.body.push({ 159  x:last.x, 160  y:last.y, 161  color:last.color 162  }); 163         //把食物删除,从新初始化食物
164  food.init(map); 165  } 166  }; 167 
168     //删除小蛇的私有的函数=============================================================================
169     function remove() { 170       //删除map中的小蛇的每一个div,同时删除elements数组中的每一个元素,从蛇尾向蛇头方向删除div
171       var i = elements.length - 1; 172       for (; i >= 0; i--) { 173         //先从当前的子元素中找到该子元素的父级元素,而后再弄死这个子元素
174         var ele = elements[i]; 175         //从map地图上删除这个子元素div
176  ele.parentNode.removeChild(ele); 177  elements.splice(i, 1); 178  } 179  } 180 
181     //把Snake暴露给window,外部能够访问
182  window.Snake = Snake; 183  }()); 184 
185   //自调用函数---游戏对象================================================
186  (function () { 187 
188     var that = null;//该变量的目的就是为了保存游戏Game的实例对象-------
189 
190     //游戏的构造函数
191     function Game(map) { 192       this.food = new Food();//食物对象
193       this.snake = new Snake();//小蛇对象
194       this.map = map;//地图
195  that = this;//保存当前的实例对象到that变量中-----------------此时that就是this
196  } 197 
198     //初始化游戏-----能够设置小蛇和食物显示出来
199  Game.prototype.init = function () { 200       //初始化游戏
201       //食物初始化
202       this.food.init(this.map); 203       //小蛇初始化
204       this.snake.init(this.map); 205       //调用自动移动小蛇的方法========================||调用了小蛇自动移动的方法
206       this.runSnake(this.food, this.map); 207       //调用按键的方法
208       this.bindKey();//========================================
209  }; 210 
211     //添加原型方法---设置小蛇能够自动的跑起来
212  Game.prototype.runSnake = function (food, map) { 213 
214       //自动的去移动
215       var timeId = setInterval(function () { 216         //此时的this是window
217         //移动小蛇
218         this.snake.move(food, map); 219         //初始化小蛇
220         this.snake.init(map); 221         //横坐标的最大值
222         var maxX = map.offsetWidth / this.snake.width; 223         //纵坐标的最大值
224         var maxY = map.offsetHeight / this.snake.height; 225         //小蛇的头的坐标
226         var headX = this.snake.body[0].x; 227         var headY = this.snake.body[0].y; 228         //横坐标
229         if (headX < 0 || headX >= maxX) { 230           //撞墙了,中止定时器
231  clearInterval(timeId); 232  alert("游戏结束"); 233  } 234         //纵坐标
235         if (headY < 0 || headY >= maxY) { 236           //撞墙了,中止定时器
237  clearInterval(timeId); 238  alert("游戏结束"); 239  } 240  }.bind(that), 150); 241  }; 242 
243     //添加原型方法---设置用户按键,改变小蛇移动的方向
244  Game.prototype.bindKey=function () { 245 
246       //获取用户的按键,改变小蛇的方向
247  document.addEventListener("keydown",function (e) { 248         //这里的this应该是触发keydown的事件的对象---document,
249         //因此,这里的this就是document
250         //获取按键的值
251         switch (e.keyCode){ 252           case 37:this.snake.direction="left";break; 253           case 38:this.snake.direction="top";break; 254           case 39:this.snake.direction="right";break; 255           case 40:this.snake.direction="bottom";break; 256  } 257  }.bind(that),false); 258  }; 259 
260     //把Game暴露给window,外部就能够访问Game对象了
261  window.Game = Game; 262  }()); 263 
264 
265 
266   //初始化游戏对象
267   var gm = new Game(document.querySelector(".map")); 268 
269   //初始化游戏---开始游戏
270  gm.init(); 271 
272 
273  
274 
275 </script>
276 </body>
277 </html>
View Code

以下图:单个方块表示食物,三个方块链接一块儿表示小蛇,其中紫色方块是蛇头,虽然看起来简单,作起来也须要很多的步骤,咱们先分析一下思路~前端

 

首先,建立一个地图~而后坐标随机显示食物方块,每次食物被小蛇“吃掉”的时候从新初始化;数组

而后,设置固定位置显示小蛇方块,设置定时器,让小蛇动起来,判断小蛇是否“吃掉”食物,是则初始化食物,复制蛇身最后一个方块加到小蛇身体最后~判断小蛇是否“撞墙”,是则提示游戏提示。app

那么具体步骤如今开始~dom

设置食物方块的自调用函数

  • 设置方块的构造函数,同时设置一个变量准备存储每一个小方块食物:
(function () { var elements = []; 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暴露给window,外部能够访问
window.Food = Food;
}());
  • 初始化食物,赋值而且在地图上显示出来,注意:记得把食物加到一开始设置的变量中 var elements = [ ];
Food.prototype.init = function (map) { remove(); var div = document.createElement("div"); map.appendChild(div); div.style.width = this.width + "px"; div.style.height = this.height + "px"; div.style.backgroundColor = this.color; div.style.position = "absolute"; this.x = parseInt(Math.random() * (map.offsetWidth / this.width)) * this.width; this.y = parseInt(Math.random() * (map.offsetHeight / this.height)) * this.height; div.style.left = this.x + "px"; div.style.top = this.y + "px"; //把div加入到数组elements中 elements.push(div); };
  • 设置初始化食物的第一个步骤,先在地图上删除这个食物:
 function remove() { for (var i = 0; i < elements.length; i++) { var ele = elements[i]; ele.parentNode.removeChild(ele); elements.splice(i, 1); } }

设置小蛇的自调用函数

  • 设置方块的构造函数,同时设置一个变量准备存储每一个小蛇的单个身体:
(function () { var elements = []; function Snake(width, height, direction) { this.width = width || 20; this.height = height || 20; this.body = [ {x: 3, y: 2, color: "red"},//头 {x: 2, y: 2, color: "orange"},//身体 {x: 1, y: 2, color: "orange"}//身体 ]; //方向 this.direction = direction || "right"; }
//把Snake暴露给window,外部能够访问
window.Snake = Snake;
}());
  • 设置小蛇初始化的函数
 Snake.prototype.init = function (map) { //先删除以前的小蛇 remove(); for (var i = 0; i < this.body.length; i++) { var obj = this.body[i]; var div = document.createElement("div"); map.appendChild(div); div.style.position = "absolute"; div.style.width = this.width + "px"; div.style.height = this.height + "px"; div.style.left = obj.x * this.width + "px"; div.style.top = obj.y * this.height + "px"; div.style.backgroundColor = obj.color //把div加入到elements数组中----目的是为了删除 elements.push(div); } };
  • 设置小蛇动起来的函数:
    • 让小蛇动起来至关因而改变了小蛇的坐标
    • 判断小蛇动起来的方向,而后坐标对应处理
    • 判断小蛇是否“吃到”了食物,是则初始化食物,而且把蛇身最后一个部分复制一分加到蛇身最后
Snake.prototype.move = function (food, map) { //改变小蛇的身体的坐标位置 var i = this.body.length - 1;//2 for (; 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 "right": this.body[0].x += 1; break; case "left": this.body[0].x -= 1; break; case "top": this.body[0].y -= 1; break; case "bottom": this.body[0].y += 1; break; } var headX=this.body[0].x*this.width; var headY=this.body[0].y*this.height; if(headX==food.x&&headY==food.y){ var last=this.body[this.body.length-1]; this.body.push({ x:last.x, y:last.y, color:last.color }); //把食物删除,从新初始化食物 food.init(map); } };
  • 不要忘记设置初始化小蛇的第一个步骤,在地图上删除这个小蛇:
 function remove() { var i = elements.length - 1; for (; i >= 0; i--) { var ele = elements[i]; ele.parentNode.removeChild(ele); elements.splice(i, 1); } }

 

设置游戏的自调用函数:

  • 设置游戏的构造函数,同时设置一个变量准备存储游戏Game的实例对象:var that=this;
 (function () { var that = null;//该变量的目的就是为了保存游戏Game的实例对象------ function Game(map) { this.food = new Food();//食物对象 this.snake = new Snake();//小蛇对象 this.map = map;//地图 that = this;//保存当前的实例对象到that变量中------此时that就是this } //把Game暴露给window,外部就能够访问Game对象了 window.Game = Game; }());
  • 初始化游戏:能够设置小蛇和食物显示出来
 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.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.body[0].x; var headY = this.snake.body[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 () { document.addEventListener("keydown",function (e) { switch (e.keyCode){ case 37:this.snake.direction="left";break; case 38:this.snake.direction="top";break; case 39:this.snake.direction="right";break; case 40:this.snake.direction="bottom";break; } }.bind(that),false); };

初始化游戏对象,开始游戏

var gm = new Game(document.querySelector(".map")); gm.init();

好的,到这里结束啦~ide

另外若是有前端学习者想要寻找伙伴一块儿合做项目,能够来我这个群~群内还有大神等你哈哈哈~函数

前端学习交流群 883726280 学习

相关文章
相关标签/搜索