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>

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM