學習了Html5的Canvas的使用,和JS建立對象,作了一個貪吃蛇小遊戲,來鞏固JS面向對象編程和Canvas的用法。javascript
Node.jscss
1 /** 2 * 格子類,組成貪吃蛇和舞臺 3 */ 4 function Node(x,y){ 5 this.x=x; 6 this.y=y; 7 /** 8 * 比較兩個格子是否重合 9 */ 10 this.equals=function(x,y){ 11 return this.x==x&&this.y==y; 12 } 13 }
Snake.jshtml
1 /*定義全局變量UP,表示方向向上*/ 2 var UP=0; 3 /*定義全局變量LEFT,表示方向向左*/ 4 var LEFT=1; 5 /*定義全局變量RIGHT,表示方向向右*/ 6 var RIGHT=2; 7 /*定義全局變量DOWN,表示方向向下*/ 8 var DOWN=3; 9 /*初始化方向向右*/ 10 var DIR=RIGHT; 11 /*初始化分數爲0*/ 12 var SCORE=0; 13 /*遊戲是否結束*/ 14 var GAMEOVER=false; 15 /*等級*/ 16 var LEVEL=1; 17 /*速度*/ 18 var SPEED=30; 19 /*最高等級*/ 20 var MAXLEVEL=6; 21 /*繪畫的時間間隔*/ 22 var TIME=200; 23 /** 24 * 貪吃蛇類 25 */ 26 function Snake(){ 27 /** 28 * 初始化貪吃蛇 29 */ 30 this.nodes=[]; 31 this.nodes.push(new Node(20,20)); 32 this.nodes.push(new Node(20,21)); 33 this.nodes.push(new Node(20,22)); 34 this.nodes.push(new Node(20,23)); 35 this.nodes.push(new Node(21,23)); 36 this.nodes.push(new Node(22,23)); 37 this.nodes.push(new Node(23,23)); 38 this.nodes.push(new Node(23,24)); 39 this.nodes.push(new Node(23,25)); 40 this.nodes.push(new Node(23,26)); 41 /** 42 * 判斷蛇身是否包含當前座標 43 */ 44 this.contains=function(x,y){ 45 for(i=0;i<this.nodes.length;i++){ 46 var node=this.nodes[i]; 47 if(node.equals(x,y)){ 48 return true; 49 } 50 } 51 return false; 52 }; 53 /** 54 * 得到一個與蛇身不重合的格子節點 55 */ 56 this.randomFood=function(){ 57 var x; 58 var y; 59 do{ 60 x=Math.floor(Math.random()*50); 61 y=Math.floor(Math.random()*50); 62 }while(this.contains(x,y)); 63 return new Node(x,y); 64 }; 65 /** 66 * 初始化食物 67 */ 68 this.food=this.randomFood(); 69 70 /** 71 * 向前走一步 72 * 添加頭節點 73 * 刪除尾節點 74 */ 75 this.step=function(){ 76 var oldHead=this.nodes[0]; 77 //根據方向計算新頭節點 78 var newHead; 79 switch (DIR){ 80 case UP: 81 newHead=new Node(oldHead.x,oldHead.y-1); 82 if(newHead.y==-1){ 83 newHead.y=49; 84 } 85 break; 86 case DOWN: 87 newHead=new Node(oldHead.x,oldHead.y+1); 88 if(newHead.y==50){ 89 newHead.y=0; 90 } 91 break; 92 case LEFT: 93 newHead=new Node(oldHead.x-1,oldHead.y); 94 if(newHead.x==-1){ 95 newHead.x=49; 96 } 97 break; 98 case RIGHT: 99 newHead=new Node(oldHead.x+1,oldHead.y); 100 if(newHead.x==50){ 101 newHead.x=0; 102 } 103 break; 104 default: 105 break; 106 } 107 /** 108 * 若是吃到本身則結束遊戲 109 */ 110 if(this.contains(newHead.x,newHead.y)){ 111 GAMEOVER=true; 112 } 113 /** 114 * 每走一步,添加新的頭節點 115 */ 116 this.nodes.unshift(newHead); 117 /** 118 * 若是新添加的頭節點與食物重合,即吃掉食物, 119 * 從新爲食物賦值,而且分數加1 120 */ 121 if(newHead.x==this.food.x&&newHead.y==this.food.y){ 122 this.food=this.randomFood(); 123 SCORE+=1; 124 /*每吃5個食物,則等級加1*/ 125 if(SCORE%5==0){ 126 /*最高等級爲5*/ 127 if(LEVEL<MAXLEVEL){ 128 LEVEL+=1; 129 } 130 } 131 }else{ 132 /*若是沒有吃掉食物,則刪除尾節點*/ 133 this.nodes.pop(); 134 } 135 //爲時間間隔從新賦值 136 TIME=200-LEVEL*SPEED; 137 }; 138 139 }
Stage.jsjava
1 /** 2 * 舞臺類 3 */ 4 function Stage(){ 5 this.width=50; 6 this.height=50; 7 this.snake=new Snake(); 8 this.print=function(ctx){ 9 //繪製舞臺的背景 10 ctx.fillStyle="#abcdef"; 11 ctx.fillRect(0,0,500,500); 12 //繪製一條蛇 13 ctx.fillStyle="chartreuse"; 14 for(i=0;i<this.snake.nodes.length;i++){ 15 var node=this.snake.nodes[i]; 16 ctx.fillRect(node.x*10,node.y*10,9,9); 17 } 18 //繪製食物 19 ctx.fillStyle="#0000ff"; 20 ctx.fillRect(this.snake.food.x*10,this.snake.food.y*10,9,9); 21 //繪製分數 22 ctx.font="20px 微軟雅黑"; 23 ctx.fillStyle="green"; 24 ctx.fillText("分數:"+SCORE,5,25); 25 //繪製等級 26 ctx.font="20px 微軟雅黑"; 27 ctx.fillStyle="green"; 28 ctx.fillText("等級:"+LEVEL,100,25); 29 } 30 }
snake.htmlnode
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="UTF-8"> 5 <title>貪吃蛇</title> 6 <style type="text/css"> 7 canvas{ 8 border: 1px solid black; 9 } 10 </style> 11 <script type="text/javascript" src="Node.js" ></script> 12 <script type="text/javascript" src="Snake.js" ></script> 13 <script type="text/javascript" src="Stage.js" ></script> 14 <script type="text/javascript"> 15 var game; 16 function load(){ 17 var stage=new Stage(); 18 //獲取用於繪製canvas的Context對象 19 var canvas=document.getElementById("mCanvas"); 20 var ctx=canvas.getContext("2d"); 21 //繪製初始界面 22 stage.print(ctx); 23 game=window.setInterval(function(){ 24 stage.snake.step(); 25 stage.print(ctx); 26 if(GAMEOVER){ 27 ctx.fillStyle="red"; 28 ctx.font="50px 微軟雅黑"; 29 ctx.fillText("GAMEOVER!",100,250); 30 window.clearInterval(game); 31 } 32 },TIME); 33 } 34 /** 35 * 方向鍵控制貪吃蛇的方向 36 * @param {Object} dir 37 */ 38 function changeDir(dir){ 39 switch (dir){ 40 case UP: 41 if(DIR!=DOWN){ 42 DIR=dir; 43 } 44 break; 45 case DOWN: 46 if(DIR!=UP){ 47 DIR=dir; 48 } 49 break; 50 case LEFT: 51 if(DIR!=RIGHT){ 52 DIR=dir; 53 } 54 break; 55 case RIGHT: 56 if(DIR!=LEFT){ 57 DIR=dir; 58 } 59 break; 60 default: 61 break; 62 } 63 } 64 </script> 65 </head> 66 <body onload="load()"> 67 <canvas id="mCanvas" width="500" height="500"></canvas> 68 <!--控制方向--> 69 <table cellpadding="0px" cellspacing="0px"> 70 <tr> 71 <td></td> 72 <td><input type="button" value="上" onclick="changeDir(UP)"/></td> 73 <td></td> 74 </tr> 75 <tr> 76 <td><input type="button" value="左" onclick="changeDir(LEFT)"></td> 77 <td></td> 78 <td><input type="button" value="右" onclick="changeDir(RIGHT)"/></td> 79 </tr> 80 <tr> 81 <td></td> 82 <td><input type="button" value="下" onclick="changeDir(DOWN)"/></td> 83 <td></td> 84 </tr> 85 </table> 86 </body> 87 </html>