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>