原生JavaScript贪吃蛇
在实例开发过程中还是能认识到很多不足的,并且加强了一些基础。
简单写一下制作过程:
1.创建画布
2.创建蛇和老鼠 坐标不能重叠
3.让蛇移动起来
4.添加死亡方法
5.添加转点坐标和方向
6.添加吃老鼠的方法
整个开发的难点有几个:
1.蛇身体的转向
2.吃老鼠添加蛇长度
总结:
1.原来玩的FC贪吃蛇100合一的小游戏其实就是根据画布大小/蛇的移动速度/蛇的长度来设置关卡。
2.最后测试时老有个bug就是删除了最后的转点但是蛇尾没转过去,一直找不到原因,虽然最后修复了,但不是很满意。
在线测试地址:http://jsfiddle.net/dtdxrk/aL9DF/embedded/result/
1 <!DOCTYPE HTML> 2 <html lang="en"> 3 <head> 4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 5 <title>贪吃蛇JavaScript版</title> 6 <style type="text/css"> 7 *{margin:0;padding: 0;line-height: 1;} 8 body{font-family: Arial, 'Microsoft Yahei', Simsun, sans-serif;background-color: #7bef70;} 9 #con{width:400px;margin: 20px auto;} 10 #con span.r{float: right;} 11 #con h1{text-align: center;} 12 #Canvas{margin: 20px auto;background-color: #f4f9f5;overflow: hidden;} 13 #Canvas table{width: 100%;border:2px solid #000;border-collapse: collapse;} 14 #Canvas table td{border-collapse: collapse;border:1px solid #bfcde9;width: 8px;height: 8px;} 15 #Canvas table td.SnakeBody{background-color: #82f170} 16 #Canvas table td.SnakeHead{background-color: #4ca72e;} 17 #Canvas table td.Mouse{background-color: red;} 18 /*#Canvas table td.SnakeBody, #Canvas table td.SnakeHead, #Canvas table td.Mouse{border:1px solid #000;*border:0;}*/ 19 </style> 20 </head> 21 <body> 22 <div id="con"> 23 <h1>贪吃蛇JavaScript版</h1> 24 <div id="Canvas"> 25 </div> 26 27 <div> 28 <span>分数:<i id="integral">0</i></span> 29 <span class="r">速度:<i id="speed">200</i></span> 30 </div> 31 </div> 32 33 <script type="text/javascript"> 34 var Snake = { 35 time : "", 36 mapX : 40, 37 mapY : 40, 38 speed : 200, 39 mousePos : {}, //老鼠坐标 40 snakeStartPos : {"x":10,"y":20}, //蛇起始位置 41 snakeDirection : "Right", //起始方向 42 snakeLen : 5, //长度 43 snakeArr : [], //蛇身体的坐标 44 pointArr : [], //转点数组 45 $ : function(id){ 46 return document.getElementById(id); 47 }, 48 init : function(){ 49 this.CreateMap(); 50 this.CreateSnake(); 51 this.CreateMouse(); 52 document.onkeydown = this.keyDirection; 53 this.timer = setInterval(this.MoveSnake, this.speed); 54 }, 55 CreateMap : function(){ //创建画布 56 var x = this.mapX, 57 y = this.mapY, 58 html = ["<table>"]; 59 for(var i=0; i<y; i++){ 60 html.push("<tr>"); 61 for(var j=0; j<x; j++){ 62 html.push("<td id='map_"+j+"_"+i+"'></td>"); 63 } 64 html.push("</tr>"); 65 } 66 html.push("</table>"); 67 this.$("Canvas").innerHTML = html.join(""); 68 }, 69 CreateMouse : function(){ //创建老鼠 70 var x,y,id, 71 that = this, 72 getMouse = function(){ 73 for(var i in that.snakeArr){ 74 if(x==that.snakeArr[i]["x"] && y==that.snakeArr[i]["y"]){ //如果坐标与snake身体重叠重置 75 return random(); 76 } 77 } 78 that.mousePos.x = x; 79 that.mousePos.y = y; 80 that.$("map_"+x+"_"+y).className = "Mouse"; 81 }, 82 random = function(){ 83 x = Math.floor(Math.random()*(that.mapX-1)); 84 y = Math.floor(Math.random()*(that.mapY-1)); 85 getMouse(); 86 }; 87 88 random(); 89 }, 90 CreateSnake : function(){ 91 var $ = this.$, 92 snakeArr = this.snakeArr, 93 snakeLen = this.snakeLen, 94 posX = this.snakeStartPos.x, 95 posY = this.snakeStartPos.y, 96 n = snakeLen + posX; 97 for(var i = posX; i<n; i++){ 98 if(i==n-1){ 99 $("map_"+i+"_"+posY).className = "SnakeHead"; 100 }else{ 101 $("map_"+i+"_"+posY).className = "SnakeBody"; 102 } 103 snakeLen--; 104 snakeArr[snakeLen] = []; 105 snakeArr[snakeLen]["x"] = i; 106 snakeArr[snakeLen]["y"] = posY; 107 snakeArr[snakeLen]["d"] = this.snakeDirection; 108 } 109 }, 110 MoveSnake : function(){ 111 var body, 112 _d, 113 snakeLen = Snake.snakeLen, 114 snakeArr = Snake.snakeArr; 115 116 Snake.$('map_'+snakeArr[snakeLen-1]['x']+'_'+snakeArr[snakeLen-1]['y']).className = ""; //蛇尾去除css样式 117 for(var i=0,len =snakeLen; i<len; i++){ 118 body = snakeArr[i]; 119 if(i==0) { 120 Snake.$("map_"+body['x']+"_"+body['y']).className = "SnakeBody"; 121 } 122 _d = Snake.getPoint(body['x'],body['y']); 123 if(_d) body['d'] = _d; //获取转点改变蛇的方向 124 125 //bug 删除转点的时候蛇尾没有转过来 126 if(i==snakeLen-1 && Snake.pointArr.length>0) Snake.delPoint(body['x'],body['y']); //删除转点 127 128 switch(body['d']){ 129 case "Left": 130 if(i==0)Snake.GameOver(body['x']-1,body['y']), Snake.eatMouse(body['x']-1,body['y']); 131 body['x']--; 132 break; 133 case "Up": 134 if(i==0)Snake.GameOver(body['x'],body['y']-1), Snake.eatMouse(body['x'],body['y']-1); 135 body['y']--; 136 break; 137 case "Right": 138 if(i==0)Snake.GameOver(body['x']+1,body['y']), Snake.eatMouse(body['x']+1,body['y']); 139 body['x']++; 140 break; 141 case "Down": 142 if(i==0)Snake.GameOver(body['x'],body['y']+1), Snake.eatMouse(body['x'],body['y']+1); 143 body['y']++; 144 break; 145 } 146 147 } 148 Snake.$("map_"+snakeArr[0]['x']+"_"+snakeArr[0]['y']).className = "SnakeHead"; 149 }, 150 GameOver : function(x,y){ //游戏结束 151 if(x<0 || y<0 || x>this.mapX-1 || y>this.mapY-1){ //超出边界 152 clearInterval(this.timer); 153 return alert("GameOver"); 154 } 155 156 for(var i in this.snakeArr){ //碰到身体 157 if(x==this.snakeArr[i]['x'] && y==this.snakeArr[i]['y']){ 158 clearInterval(this.timer); 159 return alert("GameOver"); 160 } 161 } 162 }, 163 keyDirection : function(event){ //键盘控制方向 164 var event = event || window.event, 165 key = event.which || event.keyCode, 166 _snakeDirection = Snake.snakeDirection, 167 pointArr = Snake.pointArr, 168 pointNum = pointArr.length, 169 snakeArr = Snake.snakeArr, 170 bool = true; 171 switch(key){ 172 case 37: 173 if(_snakeDirection=="Left"){ 174 bool = false; 175 }else{ 176 Snake.snakeDirection="Left"; 177 } 178 break; 179 case 38: 180 if(_snakeDirection=="Up"){ 181 bool = false; 182 }else{ 183 Snake.snakeDirection="Up"; 184 } 185 break; 186 case 39: 187 if(_snakeDirection=="Right"){ 188 bool = false; 189 }else{ 190 Snake.snakeDirection="Right"; 191 } 192 break; 193 case 40: 194 if(_snakeDirection=="Down"){ 195 bool = false; 196 }else{ 197 Snake.snakeDirection="Down"; 198 } 199 break; 200 } 201 if(bool){ 202 if(pointNum>0){ 203 if(pointArr[pointNum-1]['x']!= snakeArr[0]['x'] || pointArr[pointNum-1]['y'] != snakeArr[0]['y']) Snake.CreatePoint(); 204 }else{ 205 Snake.CreatePoint(); 206 } 207 } 208 }, 209 CreatePoint : function(){ //创建转点 210 var pointArr = this.pointArr, 211 pointNum = pointArr.length; 212 pointArr[pointNum] = []; 213 pointArr[pointNum]['x'] = this.snakeArr[0]['x']; 214 pointArr[pointNum]['y'] = this.snakeArr[0]['y']; 215 pointArr[pointNum]['d'] = this.snakeDirection; 216 }, 217 getPoint : function(x,y){ 218 var _d = "", 219 pointArr = Snake.pointArr; 220 for(var i in pointArr){ 221 if(x==pointArr[i]['x'] && y==pointArr[i]['y']){ 222 _d = pointArr[i]['d']; 223 } 224 } 225 return _d; 226 }, 227 delPoint : function(x,y){ //删除转点 228 var pointArr = Snake.pointArr; 229 if(x==pointArr[0]['x'] && y==pointArr[0]['y']){ 230 var _a = Snake.snakeArr[Snake.snakeArr.length-2], 231 _b = Snake.snakeArr[Snake.snakeArr.length-1]; 232 if(_a['x']==_b['x'] && _a['y']==_b['y']) _b['d']=_a['d']; 233 Snake.pointArr.shift(); 234 } 235 }, 236 eatMouse : function(x,y){ 237 if(x==this.mousePos.x && y==this.mousePos.y){ 238 var _x, _y, 239 _tail = this.snakeArr[this.snakeLen-1]; 240 this.snakeArr[this.snakeLen]=[]; 241 this.snakeArr[this.snakeLen]['x'] = _tail['x']; 242 this.snakeArr[this.snakeLen]['y'] = _tail['y']; 243 this.snakeArr[this.snakeLen]['d'] = _tail['d']; 244 this.snakeLen++; 245 this.speed-=5; 246 clearInterval(this.timer); 247 this.CreateMouse(); 248 this.integral(); 249 this.timer = setInterval(this.MoveSnake, this.speed); 250 } 251 }, 252 integral : function(){ 253 this.$("integral").innerHTML= Number(this.$("integral").innerHTML)+5; 254 this.$("speed").innerHTML=this.speed; 255 } 256 } 257 258 Snake.init(); 259 </script> 260 </body> 261 </html>