你的位置:首页 > Java教程

[Java教程][原创]html5游戏_贪吃蛇


代码随便写写,尚有许多不足,PC与手机端皆可运行

手机端滑屏操作,PC端方向键操作

疑问:

生成食物,与判断是否可以移动方面

有两种实现方式,

1.使用js内存,数组循环判断

2.使用dom的query方法

哪种比较快,哪种比较好?

目前的代码是用第二种方法实现

在线地址:

http://wangxinsheng.herokuapp.com/snake

截图:

部分代码:

html:

 1 <!DOCTYPE html> 2 <html> 3   <head> 4     <meta charset="utf-8"> 5     <meta name="description" content="html5 snake game"> 6     <meta name="keywords" content="snake,html5,canvas,web,game"> 7     <meta name="author" content="WangXinsheng"> 8     <meta name="apple-mobile-web-app-capable" content="yes"> 9     <meta name="apple-mobile-web-app-status-bar-style" content="black">10     <meta name="viewport" id="viewport" content="width = device-width, initial-scale = 1, minimum-scale = 1, maximum-scale = 1, user-scalable=no">11     <meta http-equiv="X-UA-Compatible" content="chrome=1">12     <meta http-equiv="Pragma" content="no-cache">13     <meta http-equiv="Cache-Control" content="no-cache">14     <meta equiv="Expires" content="0">15     <meta http-equiv="content-script-type" content="text/javascript">16     <title>CopyRight&copy;WangXinsheng</title>17     <script src="game/requestNextAnimationFrame.js"></script>18     <style type="text/css">19      html {color:#000;background:gray;margin:0px; overflow:hidden;}20      body {-webkit-user-select:none;margin:0px;}21      #gameWorld {background-color:#C6EEC6}22      #opp{color:red; font-size:30px; font-weight:bold; text-align:center;vertical-align:middle; cursor:pointer;}23     </style>24   </head>25   <body>26     <canvas id="gameWorld" style="position: absolute; left: 0px; top: 0px;">27       <p>You need a modern browser to view this.</p>28     </canvas>29     <div id="opp" style="position: absolute; left: 0px; top: 0px;">点击开始游戏</div>30     <ul style='display:none' id='dataDom'></ul>31   </body>32   <script src="game/snakeGame_min.js"></script>33 </html>

View Code

js使用dom方法:

1.初期往页面放入dom

 1 /*put data dom*/ 2 var dataDom = document.getElementById("dataDom"); 3 // document.querySelector("#dataDom"); 4 var domInner = ""; 5 for(var i = 1;i<=blockWNum;i++){ 6   for(var j = 1;j<=blockHNum;j++){ 7     domInner += liStr 8       .replace("{%x%}",i) 9       .replace("{%y%}",j)10       .replace("{%s%}","0");11   }12 }13 dataDom.innerHTML =domInner; //domInner;

2.判断是否撞到自己

1 result = 2 ("1"==document.querySelector("#dataDom [data-x='"+nx+"'][data-y='"+ny+"']").getAttribute("data-s"))3 ?false4 :true;

3.蛇移动:1)移动目的地作为头部插入蛇身体。2)删除蛇尾部

 1 switch(dir){ 2   case "N": 3     this.body.splice(0,0,{"x":this.body[0].x,"y":this.body[0].y-1}); 4     break; 5   case "S": 6     this.body.splice(0,0,{"x":this.body[0].x,"y":this.body[0].y+1}); 7     break; 8   case "W": 9     this.body.splice(0,0,{"x":this.body[0].x-1,"y":this.body[0].y});10     break;11   case "E":12     this.body.splice(0,0,{"x":this.body[0].x+1,"y":this.body[0].y});13     break;14   default:;15 }16 this.setSnakeSts(this.body[0].x,this.body[0].y,1);17 document.querySelector("#dataDom [data-x='"+x+"'][data-y='"+y+"']").setAttribute("data-s",s);

1 this.setSnakeSts(this.body[this.body.length-1].x,this.body[this.body.length-1].y,0);2 this.body.splice(this.body.length-1,1);

4.事件绑定

1 if(!v){2   document.addEventListener("keyup", onKeyPress, false);3 }else{4   caObj.addEventListener("touchstart", onTouchStart, false);5   caObj.addEventListener("touchmove", onTouchMove, false);6   caObj.addEventListener("touchend", onTouchEnd, false);7 }8 window.addEventListener("resize", doSize, false);

逻辑流程:

1.初期化canvas大小,位置和蛇身体单格大小

2.生成蛇,食物

3.蛇动作:可否移动,移动,吃食

4.循环动画[定期生成食物,移动操作蛇]

这个非常简单,js完整源码:

 1 ; 2 var debug = true; 3 var gameWorld = function () { 4   /*function init params*/ 5   function doVarInit() { 6     //started = true; 7     if(debug) 8       console.log("hello snake powered by WangXinsheng"); 9   } 10   /*function on resize the window*/ 11   function doSize() { 12     // should start again 13     var minLength = window.innerWidth>window.innerHeight 14       ?window.innerHeight 15       :window.innerWidth, 16       maxLength = window.innerWidth<window.innerHeight 17       ?window.innerHeight 18       :window.innerWidth; 19     blockW = Math.floor(minLength / blockMinNum); 20     var caMin = blockW * blockMinNum; 21     var caMax = Math.floor(maxLength / blockW) * blockW; 22  23     caW = window.innerWidth>window.innerHeight 24       ?caMax 25       :caMin; 26     caH = window.innerWidth<window.innerHeight 27       ?caMax 28       :caMin; 29  30     blockWNum = caW / blockW; 31     blockHNum = caH / blockW; 32  33     var top = (window.innerHeight - caH) * 0.5, 34       left = (window.innerWidth - caW) * 0.5; 35  36     //if(debug) 37       //console.log(blockWNum,blockHNum,top,left);// 38  39     caObj.width = caW; 40     caObj.height = caH; 41     caObj.style.width = caW + "px"; 42     caObj.style.height = caH + "px"; 43     caObj.style.left = left + "px"; 44     caObj.style.top = top + "px"; 45     oppDiv.width = caW; 46     oppDiv.height = caH; 47     oppDiv.style.width = caW + "px"; 48     oppDiv.style.height = caH + "px"; 49     oppDiv.style.left = left + "px"; 50     oppDiv.style.top = top + "px"; 51     oppDiv.style.lineHeight = caH + "px"; 52  53      54     /*put data dom*/ 55     var dataDom = document.getElementById("dataDom"); 56     // document.querySelector("#dataDom"); 57     var domInner = ""; 58     for(var i = 1;i<=blockWNum;i++){ 59       for(var j = 1;j<=blockHNum;j++){ 60         domInner += liStr 61           .replace("{%x%}",i) 62           .replace("{%y%}",j) 63           .replace("{%s%}","0"); 64       } 65     } 66     dataDom.innerHTML =domInner; //domInner; 67     //var oldDom = document.querySelector("#dataDom"); 68     //removeDom(oldDom); 69  70     lastFpsUpdateTime = (+new Date); 71     lastFpsUpdateTimeFood = (+new Date); 72   } 73   function setSnakeSts(x,y,s){ 74     document.querySelector("#dataDom [data-x='"+x+"'][data-y='"+y+"']").setAttribute("data-s",s); 75   } 76   function gen(name) { 77     /*product object*/ 78     switch(name){ 79       case "snake": 80         var body = []; 81         body.splice(0,0,{"x":1,"y":1}); 82         body.splice(0,0,{"x":2,"y":1}); 83         body.splice(0,0,{"x":3,"y":1}); 84         body.splice(0,0,{"x":4,"y":1}); 85         setSnakeSts(1,1,1); 86         setSnakeSts(2,1,1); 87         setSnakeSts(3,1,1); 88         setSnakeSts(4,1,1); 89  90         snakeObj = new snake(snakeColor,true,"E",blockW,initSpeed,body); 91         snakeObj.draw(caCt); 92         break; 93       case "food": 94         var allFood = document.querySelectorAll("#dataDom [data-s='0']"), 95           foodX,foodY,index; 96         if(allFood.length==1){ 97           index = 0; 98         }else if(allFood.length>1){ 99           index = Math.round(Math.random()*(allFood.length-1));100         }101         if(allFood.length>=1){102           foodX = parseInt(allFood[index].getAttribute("data-x"));103           foodY = parseInt(allFood[index].getAttribute("data-y"));104           allFood[index].getAttribute("data-s","2");105           foodObj.x = foodX;106           foodObj.y = foodY;107           foodObj.live = true;108         }109         drawFood();110         break;111       default:112     }113   }114   function picIsLoaded() {115     return true;116   }117   function loadPics() {118     /*load pic to objectList*/119   }120   function loadedImg() {121     /*if image loaded do here*/122   }123   function drawObject(name){124     /*draw object to canvas*/125   }126   function animate(time) {127     if (started) {128       var now = (+new Date);129       if (now - lastFpsUpdateTime > snakeObj.speed) {130         /*animate*/131         if(snakeObj.canMove(snakeObj.dir,blockWNum,blockHNum)){132           if(snakeObj.canEat(snakeObj.dir,foodObj)){133             snakeObj.doEat(snakeObj.dir,foodObj);134           }else{135             snakeObj.doMove(snakeObj.dir);136           }137         }else{138           // over139           started = false;140           oppDiv.style.display = "block";141           oppDiv.innerHTML = "点击再次游戏";142           return;143         }144         145         caCt.save();146         caCt.fillStyle = "#C6EEC6";147         caCt.fillRect(0,0,caW,caH);148         149         caCt.font = '40px Helvetica';150         caCt.textAlign = "center";151         caCt.textBaseline = "middle";152         caCt.fillStyle = '#8CCDD8';153         caCt.strokeStyle = '#8CCDD8';154         caCt.fillText("WangXinsheng", caW/2,caH/2);155         caCt.strokeText("WangXinsheng", caW/2,caH/2);156 157         caCt.restore();158 159         snakeObj.draw(caCt);160 161         // draw food162         drawFood();163         164         lastFpsUpdateTime = (+new Date);165       }166       167       if (now - lastFpsUpdateTimeFood > snakeObj.speed*5) {168         if(!foodObj.live){169           gen("food");170         }else{171           lastFpsUpdateTimeFood = (+new Date);172         }173       }174     }175     window.requestNextAnimationFrame(animate);176   }177   function drawFood(){178     if(foodObj.live){179       caCt.save();180       caCt.fillStyle = foodObj.color;181       caCt.fillRect(182         (foodObj.x-1)*blockW,183         (foodObj.y-1)*blockW,184         blockW,185         blockW186       );187       caCt.restore();188     }189   }190   function eventBund(){191     if(!v){192       document.addEventListener("keyup", onKeyPress, false);193     }else{194       caObj.addEventListener("touchstart", onTouchStart, false);195       caObj.addEventListener("touchmove", onTouchMove, false);196       caObj.addEventListener("touchend", onTouchEnd, false);197       caObj.addEventListener("touchcancel", stopEvent, false);198       caObj.addEventListener("gesturestart", stopEvent, false);199       caObj.addEventListener("gesturechange", stopEvent, false);200       caObj.addEventListener("gestureend", stopEvent, false);201     }202     window.addEventListener("resize", doSize, false);203   }204   function onKeyPress(e){205     //console.log(e);206     var dir = "";207     switch(e.keyCode){208       case 38:209         dir =snakeObj.dir=="S"?"":"N";210         break;211       case 40:212         dir =snakeObj.dir=="N"?"":"S";213         break;214       case 37:215         dir =snakeObj.dir=="E"?"":"W";216         break;217       case 39:218         dir =snakeObj.dir=="W"?"":"E";219         break;220       default:;221     }222     if(dir!="")223       snakeObj.dir = dir;224   }225   function onTouchEnd(e){226     e.preventDefault();227     if(mouseTObj.x!=null && mouseTObj.y!=null228       && mouseTMObj.x!=null && mouseTMObj.y!=null){229       var diffX = mouseTMObj.x - mouseTObj.x,230         diffY = mouseTMObj.y - mouseTObj.y,231         dir = "";232       if(Math.abs(diffY)>Math.abs(diffX)){233         dir = diffY>0?"S":"N";234       }else if(Math.abs(diffY)<Math.abs(diffX)){235         dir = diffX>0?"E":"W";236       }237       switch(dir){238         case "N":239           snakeObj.dir =snakeObj.dir=="S"?"S":"N";240           break;241         case "S":242           snakeObj.dir =snakeObj.dir=="N"?"N":"S";243           break;244         case "W":245           snakeObj.dir =snakeObj.dir=="E"?"E":"W";246           break;247         case "E":248           snakeObj.dir =snakeObj.dir=="W"?"W":"E";249           break;250         default:;251       }252       mouseTObj.x = null;253       mouseTObj.y = null;254       mouseTMObj.x = null;255       mouseTMObj.y = null;256     }257     e.stopPropagation();258     return false;259   }260   function onTouchMove(e){261     e.preventDefault();262     var touch = e.touches[0];263     mouseTMObj.x = touch.pageX;264     mouseTMObj.y = touch.pageY;265     e.stopPropagation();266     return false;267   }268   function onTouchStart(e){269     e.preventDefault();270     var touch = e.touches[0];271     mouseTObj.x = touch.pageX;272     mouseTObj.y = touch.pageY;273     e.stopPropagation();274     return false;275   }276   function stopEvent(e) { e.preventDefault(); e.stopPropagation(); }277   var v = navigator.userAgent.toLowerCase().indexOf("android") != -1 || navigator.userAgent.toLowerCase().indexOf("iphone") != -1 || navigator.userAgent.toLowerCase().indexOf("ipad") != -1,278   caW = window.innerWidth,279   caH = window.innerHeight,280   caObj = document.getElementById("gameWorld"),281   caCt = caObj.getContext("2d"),282   oppDiv = document.getElementById("opp"),283   lastFpsUpdateTime = new Date,284   lastFpsUpdateTimeFood = new Date,285   started = false,286   blockW = 0,287   blockMinNum = 20,288   blockWNum = 0,289   blockHNum = 0,290   snakeObj = null,291   snakeColor = "gray",292   initSpeed = 150,293   liStr = "<li data-x='{%x%}' data-y='{%y%}' data-s='{%s%}'></li>", //s:0-empty,1-snake,2-food294   foodObj = {"x":0,"y":0,"live":false,"color":"red"},295   mouseTObj = {"x":null,"y":null},296   mouseTMObj = {"x":null,"y":null}297   ;298 299   this.init = function () {300     //*********init params*******301     doVarInit();302     //*********init size and vars*******303     doSize();304     //*********product bell and rabit*******305     gen("snake");306     gen("food");307     //gen("yyy");308     //*********Event***********309     eventBund();310     //*********Gen***********311     //*********animate***********312     animate();313   }314   this.start = function(){315     oppDiv.style.display = "none";316     started = true;317   }318 }319 320 /*321 * object322 */323 function snake(bgC,live,dir,blockW,speed,body) {324   this.bgC = bgC; // 涂色325   this.live=live; // 存活状态 true,false326   this.dir=dir; // 移动方向 N,S,W,E327   this.blockW=blockW; // 方块边大小328   this.speed=speed; // 速度 1000329   this.body = body; // 蛇身体330 }331 snake.prototype.draw = function (context) {332   context.save();333   context.fillStyle = "gray";334   for(var i = 0;i<this.body.length;i++){335     context.fillRect(336       (this.body[i].x-1)*this.blockW,337       (this.body[i].y-1)*this.blockW,338       this.blockW,339       this.blockW340     );341   }342   context.restore();343 }344 snake.prototype.canMove = function (dir,xMax,yMax) {345   var result = false,346     nx = this.body[0].x,347     ny = this.body[0].y;348   // 边框检测349   switch(dir){350     case "N":351       result = this.body[0].y==1?false:true;352       ny--;353       break;354     case "S":355       result = this.body[0].y==yMax?false:true;356       ny++;357       break;358     case "W":359       result = this.body[0].x==1?false:true;360       nx--;361       break;362     case "E":363       result = this.body[0].x==xMax?false:true;364       nx++;365       break;366     default:;367   }368   // 自己检测369   //console.log(document.querySelector("#dataDom [data-x='"+nx+"'][data-y='"+ny+"']").getAttribute("data-s"));370   if(result)371     result = 372     ("1"==document.querySelector("#dataDom [data-x='"+nx+"'][data-y='"+ny+"']").getAttribute("data-s"))373     ?false374     :true;375   return result;376 }377 snake.prototype.canEat = function (dir,food) {378   var sx=this.body[0].x,379     sy=this.body[0].y;380   switch(dir){381     case "N":382       sy--;383       break;384     case "S":385       sy++;386       break;387     case "W":388       sx-1;389       break;390     case "E":391       sx+1;392       break;393     default:;394   }395   return (food.x==sx && food.y==sy);396 }397 // push第一个,pop最后一个398 snake.prototype.doMove = function (dir) {399   this.doEat(dir,null);400   this.setSnakeSts(this.body[this.body.length-1].x,this.body[this.body.length-1].y,0);401   this.body.splice(this.body.length-1,1);402 }403 // push第一个404 snake.prototype.doEat = function (dir,food) {405   switch(dir){406     case "N":407       this.body.splice(0,0,{"x":this.body[0].x,"y":this.body[0].y-1});408       break;409     case "S":410       this.body.splice(0,0,{"x":this.body[0].x,"y":this.body[0].y+1});411       break;412     case "W":413       this.body.splice(0,0,{"x":this.body[0].x-1,"y":this.body[0].y});414       break;415     case "E":416       this.body.splice(0,0,{"x":this.body[0].x+1,"y":this.body[0].y});417       break;418     default:;419   }420   this.setSnakeSts(this.body[0].x,this.body[0].y,1);421   if(food!=null)422     food.live = false;423 }424 snake.prototype.setSnakeSts = function(x,y,s){425   document.querySelector("#dataDom [data-x='"+x+"'][data-y='"+y+"']").setAttribute("data-s",s);426 }427 428 var gameWorldObj = null;429 window.onload = function () {430   document.getElementsByTagName('title')[0].innerHTML = "[WXS]贪吃蛇";431   snakeGameGo();432 }433 function snakeGameGo(){434   if(gameWorldObj == null)435     gameWorldObj = new gameWorld();436   gameWorldObj.init();437   var opp = document.getElementById("opp");438   opp.addEventListener("click", doPlay, false);439 }440 function doPlay(){gameWorldObj.init();gameWorldObj.start();}

View Code

运行文件下载地址:

http://download.csdn.net/detail/wangxsh42/8515975