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>
原文地址:https://www.cnblogs.com/panhe-xue/p/5808319.html