zoukankan      html  css  js  c++  java
  • js贪吃蛇(构造函数)

    给大家分享一下这几天我研究的一个贪吃蛇,挺简单的,但是实现起来其实有点绕的,我给大家附上完整代码,一起分析学习一下,主要用的是构造函数。

       

      

    思想:

    1、设计蛇:属性有宽、高、方向、状态(有多少节),方法:显示,跑
    
    2、设计食物:属性宽、高
    
    3、显示蛇:根据状态向地图里加元素
    
    4、蛇跑起来:下一节到前一节的位置,蛇头根据方向变,删除原来的蛇,新建蛇;当出界时,死亡,初始化;当蛇头吃到自己的时候,死亡,初始化
    
    5、食物被吃掉,蛇加一节,去掉原来的食物,生成新的食物
    
    6、添加定时器,绑定按键

    这里先给大家简单的说一下构造函数:

    构造函数 ,是一种特殊的方法。主要用来在创建对象时初始化对象, 即为对象成员变量赋初始值,总与new运算符一起使用在创建对象的语句中。特别的一个类可以有多个构造函数 ,可根据其参数个数的不同或参数类型的不同来区分它们 即构造函数的重载

    new data();

    然后开始我们的贪吃蛇之旅:

    1.设置变量,定义蛇的初始状态

     1  // 设置蛇的宽、高、默认走的方向
     2             this.width = 10;
     3             this.height = 10;
     4             this.direction = 'right';
     5 
     6             // 记住蛇的状态,当吃完食物的时候,就要加一个,初始为3个小点为一个蛇,
     7             this.body = [
     8                 {x:2, y:0},   // 蛇头,第一个点
     9                 {x:1, y:0},   // 蛇脖子,第二个点
    10                 {x:0, y:0},   // 蛇尾,第三个点
    11             ];

    这里面我会在代码里做详细的解释,大家注意看!!!!

    2.显示蛇

     1  for (var i=0; i<this.body.length; i++) {
     2                     if (this.body[i].x != null) {   // 当吃到食物时,x==null,不能新建,不然会在0,0处新建一个
     3                         var s = document.createElement('div');//创建元素节点
     4                         // 将节点保存到状态中,以便于后面删除
     5                         this.body[i].flag = s;
     6                         // 设置宽高
     7                         s.style.width = this.width + 'px';
     8                         s.style.height = this.height + 'px';
     9                         s.style.borderRadius =  "50%";
    10                         s.style.background = "rgb(" + Math.floor(Math.random()*256) + "," + Math.floor(Math.random()*256) + "," + Math.floor(Math.random()*256) + ")";//这个就是一个随机颜色
    11                         // 设置位置
    12                         s.style.position = 'absolute';
    13                         s.style.left = this.body[i].x * this.width + 'px';
    14                         s.style.top = this.body[i].y * this.height + 'px';//设置每一个舍身的位置  
    15                         // 添加进去
    16                         map.appendChild(s);//把元素追加到div中
    17                     }
    18                 }

    这里使用到for循环,为每一个对象创建一个flag对象,也就是蛇身。

    3.让蛇动起来

    我的想法就是让后一个元素到前一个元素来,然后这样蛇就动起来了,

    1 // 后一个元素到前一个元素的位置
    2                 for (var i=this.body.length-1; i>0; i--) {
    3                     this.body[i].x = this.body[i-1].x;
    4                     this.body[i].y = this.body[i-1].y;
    5                     //这里就相当于是后一个元素到前一个元素  这样让小蛇动起来
    6                 }

    4.调整蛇头方向

     1 // 根据方向处理蛇头
     2                 switch(this.direction)
     3                 {
     4                     //这里不仅调整蛇头方向,还为迟到的食物赋值  下边会有解释
     5                     case "left":
     6                         this.body[0].x -= 1;
     7                         break;
     8                     case "right":
     9                         this.body[0].x += 1;
    10                         break;
    11                     case "up":
    12                         this.body[0].y -= 1;
    13                         break;
    14                     case "down":
    15                         this.body[0].y += 1;
    16                         break;
    17                 }

    5.判断吃到食物和吃到自己和撞墙的事件

    这里提醒一下呢就是,不管你是吃到食物了还是撞墙了还是吃到自己了你到要重新创建蛇。

    然后呢我会在代码里标注清楚每一个代码的作用。

     1  // 判断是否出界,一蛇头判断,出界的话,
     2                 if (this.body[0].x < 0 || this.body[0].x > 79 || this.body[0].y < 0 || this.body[0].y > 39) {
     3                     clearInterval(timer);   // 清除定时器,
     4                     alert("你瞎吗?撞死了!");
     5                     // 删除旧的
     6                     for (var i=0; i<this.body.length; i++) {
     7                         if (this.body[i].flag != null) {   // 如果刚吃完就死掉,会加一个值为null的
     8                             map.removeChild(this.body[i].flag);
     9                         }
    10                     }
    11                     //这里呢一定要删除 之后  初始化一下  因为上边的this.display() 为每一个body对象都添加了一个flag  所以这里删除原本的蛇 重新初始化一下蛇
    12                     this.body = [   // 回到初始状态,
    13                         {x:2, y:0},
    14                         {x:1, y:0},
    15                         {x:0, y:0}
    16                     ];
    17                     this.direction = 'right';
    18                     this.display();   // 显示初始状态
    19                     return false;   // 结束
    20                 }
    21                
    22                 // 判断蛇头吃到食物,xy坐标重合,
    23                 if (this.body[0].x == food.x && this.body[0].y == food.y) {
    24                     // 蛇加一节,因为根据最后节点定,下面display时,会自动赋值的
    25                     this.body.push({x:null, y:null, flag: null});
    26 
    27                     //在这里 看了上边的小伙伴可能会有疑惑  this.display  函数里面生成小蛇的判断是x!=null   那我吃到实物以后push进去的都是null  为什么还会创建出来????
    28                     //这里呢大家就注意看  this.run()  这个方法  他让后一个元素到前一个元素来  然后你新添加的这一截蛇它会被替换为蛇头  然后进入 下边的switch语句  x,y都会变为-1 或者是1  那么这个时候在走上边的 this.display() 就可以生成一个新的小蛇。
    29 
    30 
    31                     // 清除食物,重新生成食物
    32                     map.removeChild(food.flag);
    33                     food.display();
    34                 }
    35                 // 吃到自己死亡,从第五个开始与头判断,因为前四个永远撞不到
    36                 for (var i=4; i<this.body.length; i++) {
    37                     if (this.body[0].x == this.body[i].x && this.body[0].y == this.body[i].y) {
    38                         clearInterval(timer);   // 清除定时器,
    39                         alert("傻子!你怎么能吃自己呢?");
    40                         // 删除旧的
    41                         for (var i=0; i<this.body.length; i++) {
    42                             if (this.body[i].flag != null) {   // 如果刚吃完就死掉,会加一个值为null的
    43                                 map.removeChild(this.body[i].flag);
    44                             }
    45                         }
    46                         this.body = [   // 回到初始状态,
    47                             {x:2, y:0},
    48                             {x:1, y:0},
    49                             {x:0, y:0}
    50                         ];
    51                         this.direction = 'right';
    52                         this.display();   // 显示初始状态
    53                         return false;   // 结束
    54                     }
    55                 }
    56 
    57                 // 先删掉初始的蛇,在显示新蛇
    58                 for (var i=0; i<this.body.length; i++) {
    59                     if (this.body[i].flag != null) {   // 当吃到食物时,flag是等于null,且不能删除
    60                         map.removeChild(this.body[i].flag);
    61                     }
    62                 }
    63                 // 重新显示蛇
    64                 this.display();

    6.构造食物

    食物呢,我们就是创建一个,当蛇吃到食物,也就是蛇头与食物的xy坐标一样后删除食物,然后随机新建一个食物

     1   this.width = 10;
     2             this.height = 10;
     3 
     4             this.display = function() {
     5                 var f = document.createElement('div');
     6                 this.flag = f;
     7                 f.style.width = this.width + 'px';
     8                 f.style.height = this.height + 'px';
     9                 f.style.background = 'red';
    10                 f.style.borderRadius = '50%';
    11                 f.style.position = 'absolute';
    12                 //设置随机位置
    13                 this.x = Math.floor(Math.random()*80);
    14                 this.y = Math.floor(Math.random()*40);
    15                 f.style.left = this.x * this.width + 'px';
    16                 f.style.top = this.y * this.height + 'px';
    17                 //把创建好的食物添加进地图里
    18                 map.appendChild(f);

    7.然后我们要使用构造函数调用食物和蛇的方法

    1 var snake = new Snake();// 构造函数
    2         var food = new Food();
    3         snake.display();   // 初始化显示
    4         food.display();

    这里呢,一定要注意,他改变了this的指向,大家可以输出一下this指向,

    如果直接调用函数的话,this是指向window,使用构造函数的话this就指向调用者

    8.点击开始游戏添加键盘事件

     1 document.body.onkeydown = function(e) {
     2             // 有事件对象就用事件对象,没有就自己创建一个,兼容低版本浏览器
     3             var ev = e || window.event;
     4 
     5             switch(ev.keyCode)
     6             {
     7                 case 38:
     8                     if (snake.direction != 'down') {   // 不允许返回,向上的时候不能向下
     9                         snake.direction = "up";
    10                     }
    11                     break;
    12                 case 40:
    13                     if (snake.direction != "up") {
    14                         snake.direction = "down";
    15                     }
    16                     break;
    17                 case 37:
    18                     if (snake.direction != "right") {
    19                         snake.direction = "left";
    20                     }
    21                     break;
    22                 case 39:
    23                     if (snake.direction != "left") {
    24                         snake.direction = "right";
    25                     }
    26                     break;
    27             }
    28         };

    9.设置定时器,让小蛇自己动起来

    1 // 点击开始时,动起来
    2         var begin = document.getElementById('begin');
    3         var timer;
    4         begin.onclick = function() {
    5             clearInterval(timer);
    6               // 先执行run函数,把执行得到的结果,每500毫秒执行一次,不会在执行内部代码
    7              // 小技巧,每500毫秒执行字符串,字符串执行内部代码
    8              timer = setInterval("snake.run()", 500);
    9         };

    最后一定要记住,调用定时器前一定要先清除定时器!!!!

    给大家附上完整代码:

      1 <!doctype html>
      2 <html lang="en">
      3 <head>
      4     <meta charset="UTF-8">
      5     <meta name="viewport"
      6           content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
      7     <meta http-equiv="X-UA-Compatible" content="ie=edge">
      8     <title>Document</title>
      9     <style type="text/css">
     10         body {
     11             margin: 0;
     12             padding: 0;
     13         }
     14         .main {
     15              800px;
     16             height: 400px;
     17             margin: 50px auto;
     18         }
     19         .btn {
     20              100px;
     21             height: 40px;
     22             background: red;
     23         }
     24         .map {
     25             position: relative;
     26              800px;
     27             height: 400px;
     28             background: yellow;
     29         }
     30     </style>
     31 </head>
     32 <body>
     33 <div class="main">
     34     <button class="btn" id="begin">开始游戏</button>
     35     <div class="map" id="map"></div>
     36 
     37     <script type="text/javascript">
     38         var map = document.getElementById('map');
     39         // 使用构造方法创建蛇,
     40         function Snake()
     41         {
     42             // 设置蛇的宽、高、默认走的方向
     43             this.width = 10;
     44             this.height = 10;
     45             this.direction = 'right';
     46 
     47             // 记住蛇的状态,当吃完食物的时候,就要加一个,初始为3个小点为一个蛇,
     48             this.body = [
     49                 {x:2, y:0},   // 蛇头,第一个点
     50                 {x:1, y:0},   // 蛇脖子,第二个点
     51                 {x:0, y:0},   // 蛇尾,第三个点
     52             ];
     53 
     54             // 显示蛇
     55             this.display = function() {
     56                 // 创建蛇
     57                 for (var i=0; i<this.body.length; i++) {
     58                     if (this.body[i].x != null) {   // 当吃到食物时,x==null,不能新建,不然会在0,0处新建一个
     59                         var s = document.createElement('div');//创建元素节点
     60                         // 将节点保存到状态中,以便于后面删除
     61                         this.body[i].flag = s;
     62                         // 设置宽高
     63                         s.style.width = this.width + 'px';
     64                         s.style.height = this.height + 'px';
     65                         s.style.borderRadius =  "50%";
     66                         s.style.background = "rgb(" + Math.floor(Math.random()*256) + "," + Math.floor(Math.random()*256) + "," + Math.floor(Math.random()*256) + ")";//这个就是一个随机颜色
     67                         // 设置位置
     68                         s.style.position = 'absolute';
     69                         s.style.left = this.body[i].x * this.width + 'px';
     70                         s.style.top = this.body[i].y * this.height + 'px';//设置每一个舍身的位置  
     71                         // 添加进去
     72                         map.appendChild(s);//把元素追加到div中
     73                     }
     74                 }
     75             };
     76 
     77             // 让蛇跑起来,后一个元素到前一个元素的位置
     78             // 蛇头根据方向处理,所以i不能等于0
     79             this.run = function() {
     80                 // 后一个元素到前一个元素的位置
     81                 for (var i=this.body.length-1; i>0; i--) {
     82                     this.body[i].x = this.body[i-1].x;
     83                     this.body[i].y = this.body[i-1].y;
     84                     //这里就相当于是后一个元素到前一个元素  这样让小蛇动起来
     85                 }
     86 
     87                 // 根据方向处理蛇头
     88                 switch(this.direction)
     89                 {
     90                     //这里不仅调整蛇头方向,还为迟到的食物赋值  下边会有解释
     91                     case "left":
     92                         this.body[0].x -= 1;
     93                         break;
     94                     case "right":
     95                         this.body[0].x += 1;
     96                         break;
     97                     case "up":
     98                         this.body[0].y -= 1;
     99                         break;
    100                     case "down":
    101                         this.body[0].y += 1;
    102                         break;
    103                 }
    104 
    105                 // 判断是否出界,一蛇头判断,出界的话,
    106                 if (this.body[0].x < 0 || this.body[0].x > 79 || this.body[0].y < 0 || this.body[0].y > 39) {
    107                     clearInterval(timer);   // 清除定时器,
    108                     alert("你瞎吗?撞死了!");
    109                     // 删除旧的
    110                     for (var i=0; i<this.body.length; i++) {
    111                         if (this.body[i].flag != null) {   // 如果刚吃完就死掉,会加一个值为null的
    112                             map.removeChild(this.body[i].flag);
    113                         }
    114                     }
    115                     //这里呢一定要删除 之后  初始化一下  因为上边的this.display() 为每一个body对象都添加了一个flag  所以这里删除原本的蛇 重新初始化一下蛇
    116                     this.body = [   // 回到初始状态,
    117                         {x:2, y:0},
    118                         {x:1, y:0},
    119                         {x:0, y:0}
    120                     ];
    121                     this.direction = 'right';
    122                     this.display();   // 显示初始状态
    123                     return false;   // 结束
    124                 }
    125                
    126                 // 判断蛇头吃到食物,xy坐标重合,
    127                 if (this.body[0].x == food.x && this.body[0].y == food.y) {
    128                     // 蛇加一节,因为根据最后节点定,下面display时,会自动赋值的
    129                     this.body.push({x:null, y:null, flag: null});
    130 
    131                     //在这里 看了上边的小伙伴可能会有疑惑  this.display  函数里面生成小蛇的判断是x!=null   那我吃到实物以后push进去的都是null  为什么还会创建出来????
    132                     //这里呢大家就注意看  this.run()  这个方法  他让后一个元素到前一个元素来  然后你新添加的这一截蛇它会被替换为蛇头  然后进入 下边的switch语句  x,y都会变为-1 或者是1  那么这个时候在走上边的 this.display() 就可以生成一个新的小蛇。
    133 
    134 
    135                     // 清除食物,重新生成食物
    136                     map.removeChild(food.flag);
    137                     food.display();
    138                 }
    139                 // 吃到自己死亡,从第五个开始与头判断,因为前四个永远撞不到
    140                 for (var i=4; i<this.body.length; i++) {
    141                     if (this.body[0].x == this.body[i].x && this.body[0].y == this.body[i].y) {
    142                         clearInterval(timer);   // 清除定时器,
    143                         alert("傻子!你怎么能吃自己呢?");
    144                         // 删除旧的
    145                         for (var i=0; i<this.body.length; i++) {
    146                             if (this.body[i].flag != null) {   // 如果刚吃完就死掉,会加一个值为null的
    147                                 map.removeChild(this.body[i].flag);
    148                             }
    149                         }
    150                         this.body = [   // 回到初始状态,
    151                             {x:2, y:0},
    152                             {x:1, y:0},
    153                             {x:0, y:0}
    154                         ];
    155                         this.direction = 'right';
    156                         this.display();   // 显示初始状态
    157                         return false;   // 结束
    158                     }
    159                 }
    160 
    161                 // 先删掉初始的蛇,在显示新蛇
    162                 for (var i=0; i<this.body.length; i++) {
    163                     if (this.body[i].flag != null) {   // 当吃到食物时,flag是等于null,且不能删除
    164                         map.removeChild(this.body[i].flag);
    165                     }
    166                 }
    167                 // 重新显示蛇
    168                 this.display();
    169 
    170             }
    171         }
    172 
    173         // 构造食物
    174         function Food()
    175         {
    176             this.width = 10;
    177             this.height = 10;
    178 
    179             this.display = function() {
    180                 var f = document.createElement('div');
    181                 this.flag = f;
    182                 f.style.width = this.width + 'px';
    183                 f.style.height = this.height + 'px';
    184                 f.style.background = 'red';
    185                 f.style.borderRadius = '50%';
    186                 f.style.position = 'absolute';
    187                 //设置随机位置
    188                 this.x = Math.floor(Math.random()*80);
    189                 this.y = Math.floor(Math.random()*40);
    190                 f.style.left = this.x * this.width + 'px';
    191                 f.style.top = this.y * this.height + 'px';
    192                 //把创建好的食物添加进地图里
    193                 map.appendChild(f);
    194             }
    195         }
    196 
    197         var snake = new Snake();// 构造函数
    198         var food = new Food();
    199         snake.display();   // 初始化显示
    200         food.display();
    201 
    202         // 给body加按键事件,上下左右
    203         document.body.onkeydown = function(e) {
    204             // 有事件对象就用事件对象,没有就自己创建一个,兼容低版本浏览器
    205             var ev = e || window.event;
    206 
    207             switch(ev.keyCode)
    208             {
    209                 case 38:
    210                     if (snake.direction != 'down') {   // 不允许返回,向上的时候不能向下
    211                         snake.direction = "up";
    212                     }
    213                     break;
    214                 case 40:
    215                     if (snake.direction != "up") {
    216                         snake.direction = "down";
    217                     }
    218                     break;
    219                 case 37:
    220                     if (snake.direction != "right") {
    221                         snake.direction = "left";
    222                     }
    223                     break;
    224                 case 39:
    225                     if (snake.direction != "left") {
    226                         snake.direction = "right";
    227                     }
    228                     break;
    229             }
    230         };
    231 
    232         // 点击开始时,动起来
    233         var begin = document.getElementById('begin');
    234         var timer;
    235         begin.onclick = function() {
    236             clearInterval(timer);
    237               // 先执行run函数,把执行得到的结果,每500毫秒执行一次,不会在执行内部代码
    238              // 小技巧,每500毫秒执行字符串,字符串执行内部代码
    239              timer = setInterval("snake.run()", 500);
    240         };
    241 
    242 
    243     </script>
    244 </div>
    245 </body>
    246 </html>

    详细的解释我已经在代码中注释,大家把代码复制下来就可以直接查看效果!!!

  • 相关阅读:
    slqmap简单使用
    Sql注入类型
    路由器协议----IGP、EGP、RIP、OSPF、BGP、MPLS
    TCPIP协议簇-各层主要协议帧格式
    TCP/IP协议(7):应用层
    TCP/IP协议(5):传输层之TCP
    TCP/IP协议(6):传输层之UDP
    Mysql数据库优化之SQL及索引优化
    公众号支付时,如何判断是否是微信浏览器
    ajax返回数据为undefined
  • 原文地址:https://www.cnblogs.com/yushihao/p/11993668.html
Copyright © 2011-2022 走看看