zoukankan      html  css  js  c++  java
  • html5面向对象做一个贪吃蛇小游戏

    canvas加面向对象方式的贪吃蛇 2016-08-25

               这个小游戏可以增加对面向对象的理解,可以加强js逻辑能力,总之认真自己敲一两遍收获还是不少啊!!适合刚学canvas的同学练习!!

          废话不多说,直接来讲思路和代码.

          -----------------------------------------------------------------------------------------------------------------

          开发思路:首先要有蛇吃的食物,就是一个个canvas随机画出的方块,然后是蛇,蛇也是方块组成。于是我们构造一个函数,功能是产生食物和蛇的原材料,和处理一些关于方块的函数(后面会上代码)。其次是,开始游戏的函数,当页面加载完成后开始游戏,然后是当游戏开始是时候,我们要初始化一个画布和随机产生食物,接着是关于画蛇和控制蛇的构造函数。最后是当触发游戏结束的条件时候的游戏结束函数。首先搭建一个整体思路然后再细细入手,博主是这样写的,大神别笑话.

    初始代码如下:

    ------

    <script>
           var canvas=document.getElementById("canvas");
           var ctx=canvas.getContext('2d');
           var gridWidth=10;
           var foods=new Array(),snakes=new Array();//放食物和蛇的数组
           //原料初始化
           function Node(x,y,w){
           
           }
    
           //生成一个画布和食物
           function Farm(){
        
            }
           //画蛇
           function Snake(x,y,len,speed){
                  }
           }
           //开始游戏
           function gameStart(){
              }
           gameStart();
           //结束游戏
           function gameover(){}
    <script>

    ------

        接着,就是一个一个思考:首先是Node函数里面设置一些基本生成方块方法,由于,蛇和食物并不同,所以分成单独的2个函数,并且,蛇运动的时候要去掉尾部的方块,所以这里还要加一个去掉clear方法:

    ---   

     1          var t=this;
     2            t.x=x;
     3            t.y=y;
     4            t.w=w;
     5            //食物
     6            t.foodInit=function(){
     7                ctx.fillStyle='red';
     8                ctx.fillRect(x,y,w,w);
     9            }  
    10            //
    11            t.snakeInit=function(){
    12                 ctx.fillStyle='black';
    13                 ctx.strokeStyle='white';
    14              ctx.fillRect(x,y,w,w);
    15              ctx.strokeRect(x,y,w,w);
    16                }
    17            //清除蛇尾
    18             t.clear=function(){
    19             ctx.fillStyle='white';
    20             ctx.strokeStyle='white';
    21             ctx.fillRect(x,y,w,w);
    22             ctx.strokeRect(x,y,w,w);
    23            }

    ----

         接着是Fram函数里,要设置一个画布环境并且要随机产生食物:

    ---- 

     1     function Farm(){
     2            var t=this;
     3             ctx.fillStyle='white';
     4             ctx.fillRect(0,0,canvas.width,canvas.height);
     5          //随机生成食物
     6          t.addfood=function(){
     7              var x=parseInt(canvas.width/gridWidth*Math.random())*gridWidth;
     8              var y=parseInt(canvas.height/gridWidth*Math.random())*gridWidth;
     9              var food=new Node(x,y,gridWidth);
    10              food.foodInit();
    11              foods.push(food);
    12          }
    13        }

    ----

       写到这里,当你启动gameStar函数时候会看到一些食物随机产生在画布上,颜色改一下,会有不同的画布环境:

    ---    

    1     //开始游戏
    2    function gameStart(){
    3       var farm=new Farm();
    4       setInterval(farm.addfood,2000);
    5    }
    6    gameStart();

     ---

       现在到了最难的地方就是处理蛇,首先是画一条蛇并启动它和键盘事件取如下:

    ---

     1          function Snake(x,y,len,speed){
     2           var t=this;
     3           t.x=x;
     4           t.y=y;
     5           t.dir='R';
     6           //t.len=len;
     7           var nx=x;ny=y;
     8           t.init=function(){
     9               for (var i = 0; i <len; i++) {
    10                   var tempNode=new Node(nx,ny,gridWidth);
    11                   tempNode.snakeInit();
    12                 nx-=gridWidth=10;
    13                 snakes.push(tempNode);        
    14               };
    15               //setInterval(t.move,speed)
    16           }
    17           
    18           //取得键盘方向
    19           document.onkeydown=function(e){
    20                 var code=e.keyCode;
    21             switch(code){
    22                case 37:
    23                  t.dir='L';
    24                break;
    25                case 38:
    26                  t.dir='U';
    27                break;
    28                case 39:
    29                   t.dir='R';
    30                break;
    31                case 40:
    32                   t.dir='D';
    33                break;
    34             } 
    35           }
    }

    ---

      这主要是让蛇动的move方法:

     1         //移动蛇
     2           t.move=function(){
     3              var newHead; 
     4              //初始化蛇头的位置从而确定方向
     5              if(snakes[0].x+snakes[0].w>=canvas.width||snakes[0].x-snakes[0].w<0||snakes[0].y-snakes[0].w<0||snakes[0].y+snakes[0].w>canvas.height)
     6              {
     7                 gameover();
     8              }
     9              else{
    10                   if(t.dir=='R'){
    11                    newHead=new Node(snakes[0].x+gridWidth,snakes[0].y,gridWidth);
    12                  }else if(t.dir=='L'){
    13                    newHead=new Node(snakes[0].x-gridWidth,snakes[0].y,gridWidth); 
    14                  }else if(t.dir=='D'){
    15                    newHead=new Node(snakes[0].x,snakes[0].y+gridWidth,gridWidth);
    16                  }else if(t.dir=='U'){
    17                    newHead=new Node(snakes[0].x,snakes[0].y-gridWidth,gridWidth);  
    18                  }
    19              }
    20              //画蛇头
    21              newHead.snakeInit();
    22              //追加到数组中(长度会自动加)
    23              snakes.unshift(newHead);            
    24              //清除尾部
    25              snakes[snakes.length-1].clear();
    26              //并从数组中移除(长度会自动减)
    27              snakes.pop();
    28              
    29              //判断食物是否和蛇头相撞
    30              for (var i = 0; i < foods.length; i++) {
    31                if(foods[i].equal(snakes[0])){
    32                  //给蛇增加长度
    33                  t.addFood();
    34                  clearInterval(snake_interval);
    35                }         
    36              }
    37 
    38             //给蛇增加长度(在尾巴加)
    39             t.addFood=function(){
    40               var tail1=snakes[snakes.length-1];
    41               var tail2=snakes[snakes.length-2];
    42               var addNode;
    43               if(tail1.x==tail2.x){
    44                   if(tail1.y>=tail2.y) 
    45                     addNode=new Node(tail1.x,tail1.y+gridWidth,gridWidth);
    46                   else
    47                     addNode=new Node(tail1.x,tail1.y-gridWidth,gridWidth);
    48                 }
    49                 else{
    50                   if(tail1.x>=tail2.x) 
    51                     addNode=new Node(tail1.x+gridWidth,tail1.y,gridWidth);
    52                   else
    53                     addNode=new Node(tail1.x-gridWidth,tail1.y,gridWidth);
    54               }
    55 
    56               //数组加入尾部
    57               snakes.push(addNode);
    58               addNode.snakeInit();            
    59             }//addFood函数
    60         }//move函数结束

    ---

        到现在就是一点 其他条件设置,比喻不能反方向穿,不能穿自己。设置游戏结束后的步骤,现在可以先自己 思考下怎么写。

    ---

      所有的代码在这里,有不足的可以提出一起进步:

      1         <!DOCTYPE html>
      2 <html lang="en">
      3 <head>
      4     <meta charset="UTF-8">
      5     <title>小游戏之贪吃蛇2次重写(面向对象)</title>
      6     <style>
      7       #canvas{border: 1px solid red;}
      8     </style>
      9 </head>
     10 <body>
     11     <canvas  id='canvas' width='800' height='600'></canvas>
     12     <script>
     13        var canvas=document.getElementById("canvas");
     14        var ctx=canvas.getContext('2d');
     15        var gridWidth=10;
     16        var foods=new Array(),snakes=new Array();//放食物和蛇的数组
     17        //原料初始化
     18        function Node(x,y,w){
     19            var t=this;
     20            t.x=x;
     21            t.y=y;
     22            t.w=w;
     23            //食物
     24            t.foodInit=function(){
     25                ctx.fillStyle='red';
     26                ctx.fillRect(x,y,w,w);
     27            }  
     28            //
     29            t.snakeInit=function(){
     30                 ctx.fillStyle='black';
     31                 ctx.strokeStyle='white';
     32              ctx.fillRect(x,y,w,w);
     33              ctx.strokeRect(x,y,w,w);
     34            }
     35            //清除蛇尾
     36            t.clear=function(){
     37              ctx.fillStyle='white';
     38              ctx.strokeStyle='white';
     39              ctx.fillRect(x,y,w,w);
     40              ctx.strokeRect(x,y,w,w);
     41            } 
     42            //判断是否重合
     43            t.equal=function(node){
     44               if(this.x==node.x&&this.y==node.y) {
     45                 return true;
     46               }else{
     47                 return false;
     48               } 
     49            }
     50        }
     51 
     52        //生成一个画布和食物
     53        function Farm(){
     54             var t=this;
     55             ctx.fillStyle='white';
     56             ctx.fillRect(0,0,canvas.width,canvas.height);
     57          //随机生成食物
     58          t.addfood=function(){
     59             var x=parseInt(canvas.width/gridWidth*Math.random())*gridWidth;
     60             var y=parseInt(canvas.height/gridWidth*Math.random())*gridWidth;
     61             var food=new Node(x,y,gridWidth);
     62             food.foodInit();
     63             foods.push(food);
     64          }
     65        }
     66        //画蛇
     67        function Snake(x,y,len,speed){
     68           var t=this;
     69           t.x=x;
     70           t.y=y;
     71           t.dir='R';
     72           //t.len=len;
     73           var nx=x;ny=y;
     74           t.init=function(){
     75               for (var i = 0; i <len; i++) {
     76                 var tempNode=new Node(nx,ny,gridWidth);
     77                 tempNode.snakeInit();
     78                 nx-=gridWidth;
     79                 snakes.push(tempNode);        
     80               };       
     81            snake_interval=setInterval(t.move,speed)
     82           }
     83           
     84           //取得键盘方向
     85           document.onkeydown=function(e){
     86                 var code=e.keyCode;
     87                 t.odir=t.dir;
     88             switch(code){
     89                case 37:
     90                  t.dir='L';
     91                break;
     92                case 38:
     93                  t.dir='U';
     94                break;
     95                case 39:
     96                   t.dir='R';
     97                break;
     98                case 40:
     99                   t.dir='D';
    100                break;
    101             } 
    102           }
    103            //移动蛇
    104           t.move=function(){
    105              var newHead; 
    106              //初始化蛇头的位置从而确定方向
    107              if(snakes[0].x+snakes[0].w>=canvas.width||snakes[0].x-snakes[0].w<0||snakes[0].y-snakes[0].w<0||snakes[0].y+snakes[0].w>canvas.height)
    108              {
    109                   gameover();
    110              }
    111              else{
    112                   if(t.dir=='R'){
    113                    newHead=new Node(snakes[0].x+gridWidth,snakes[0].y,gridWidth);
    114                  }else if(t.dir=='L'){
    115                    newHead=new Node(snakes[0].x-gridWidth,snakes[0].y,gridWidth); 
    116                  }else if(t.dir=='D'){
    117                    newHead=new Node(snakes[0].x,snakes[0].y+gridWidth,gridWidth);
    118                  }else if(t.dir=='U'){
    119                    newHead=new Node(snakes[0].x,snakes[0].y-gridWidth,gridWidth);  
    120                  }
    121              }
    122 
    123             //禁止反向跑
    124             if(newHead.x==snakes[1].x&&newHead.y==snakes[1].y){
    125                   t.dir=t.odir; 
    126                   return;                                 
    127             }
    128 
    129 
    130              //画蛇头
    131              newHead.snakeInit();
    132              //追加到数组中(长度会自动加)
    133              snakes.unshift(newHead);            
    134              //清除尾部
    135              snakes[snakes.length-1].clear();
    136              //并从数组中移除(长度会自动减)
    137              snakes.pop();
    138              
    139              //判断食物是否和蛇头相撞
    140              for (var i = 0; i < foods.length; i++) {
    141                if(foods[i].equal(snakes[0])){
    142                  //给蛇增加长度
    143                  t.addFood();
    144                  clearInterval(snake_interval);
    145                  speed=speed<20?speed:speed-10;
    146                  snake_interval=setInterval(t.move,speed);
    147                }         
    148              }
    149 
    150              //判断是否与自己相撞
    151              for (var i = 1; i < snakes.length; i++) {
    152                 if(snakes[i].equal(snakes[0])){
    153                      gameover();
    154                 }
    155              };
    156           
    157             //给蛇增加长度(在尾巴加)
    158             t.addFood=function(){
    159               var tail1=snakes[snakes.length-1];
    160               var tail2=snakes[snakes.length-2];
    161               var addNode;
    162               if(tail1.x==tail2.x){
    163                   if(tail1.y>=tail2.y) 
    164                     addNode=new Node(tail1.x,tail1.y+gridWidth,gridWidth);
    165                   else
    166                     addNode=new Node(tail1.x,tail1.y-gridWidth,gridWidth);
    167                 }
    168                 else{
    169                   if(tail1.x>=tail2.x) 
    170                     addNode=new Node(tail1.x+gridWidth,tail1.y,gridWidth);
    171                   else
    172                     addNode=new Node(tail1.x-gridWidth,tail1.y,gridWidth);
    173               }
    174 
    175               //数组加入尾部
    176               snakes.push(addNode);
    177               addNode.snakeInit();  
    178               console.log(snakes.length); 
    179 
    180             }//addFood函数
    181         }//move函数结束
    182 
    183        }/*snake函数结束*/
    184 
    185        //开始游戏
    186        function gameStart(){
    187           var farm=new Farm();
    188           food_interval=setInterval(farm.addfood,2000);
    189 
    190           //画蛇
    191           snakes=[];//重新初始化数组,不要把前一次的数组元素遗留
    192           var snake=new Snake(100,100,5,500);
    193           snake.init();
    194        }
    195        gameStart();
    196        //结束
    197        function gameover(){
    198         var  judge=confirm("游戏结束,是否重新开始");
    199         clearInterval(snake_interval);
    200         clearInterval(food_interval);
    201         while(!judge){
    202               //res= confirm("游戏结束,是否重新开始"); 
    203                 return false;
    204             }
    205             gameStart();
    206         
    207        }
    208     </script>
    209 </body>
    210 </html>
  • 相关阅读:
    汉诺塔
    协变和逆变随笔
    NetCore开发第一步 Log4Net日志引入
    插入排序算法
    选择排序算法
    冒泡排序算法
    排序算法
    线性链表
    SAN
    SAM -- Chap 8 提升方法 自我梳理
  • 原文地址:https://www.cnblogs.com/panhe-xue/p/5808319.html
Copyright © 2011-2022 走看看