使用Html5+JS做的贪吃蛇小游戏

学习了Html5的Canvas的使用,和JS创建对象,做了一个贪吃蛇小游戏,来巩固JS面向对象编程和Canvas的用法。

Node.js

 

 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.js

  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.js

 

 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.html

 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>

 

posted @ 2016-01-20 19:52  fighting9527  阅读(2576)  评论(0编辑  收藏  举报