含有用户接口(UI)的应用程序,以前基本是都是桌面应用,随着HTML5的增强,现在用JS和HTML5可以实现跟桌面应用相媲美的任何客户端,比如经典的贪吃蛇,以前都是桌面版的二维动画,现在在浏览器里面实现起来也并非难事,而且加以改造,和websocket结合起来,完全可以打造B/S版的二维游戏,以前是一个客户端实现的贪吃蛇,完整代码在百度分享里面,分享地址如下:http://pan.baidu.com/s/1hszGxV2,其中common.js是本人开发的一个工具包,在其他博客里面有介绍。游戏操作如下:鼠标点击画面在点击处添加一个小蛇,箭头键调整方向,ESC暂停游戏,ENTER键重新开始。
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="UTF-8"> 5 <title>贪吃蛇</title> 6 <style type="text/css"> 7 #playground { 8 background-color: #000; 9 } 10 11 #console-container { 12 float: left; 13 margin-left: 15px; 14 width: 300px; 15 } 16 17 #console { 18 border: 1px solid #CCCCCC; 19 border-right-color: #999999; 20 border-bottom-color: #999999; 21 height: 600px; 22 overflow-y: scroll; 23 padding-left: 5px; 24 padding-right: 5px; 25 width: 100%; 26 } 27 28 #console p { 29 padding: 0; 30 margin: 0; 31 } 32 </style> 33 </head> 34 <body> 35 <div style="float: left"> 36 <canvas id="playground" width="1000" height="600" /> 37 </div> 38 <div id="console-container"> 39 <div id="console" /> 40 </div> 41 <script type="text/javascript" src="common.js"></script> 42 <script type="text/javascript"> 43 //单例,全局对象 44 var Game = { 45 //方向改变事件 46 onKeydown : function(e) { 47 switch (e.keyCode) { 48 //左箭头 49 case 37: 50 this.setDirection('west'); 51 break; 52 //上箭头 53 case 38: 54 this.setDirection('north'); 55 break; 56 //右箭头 57 case 39: 58 this.setDirection('east'); 59 break; 60 //下箭头 61 case 40: 62 this.setDirection('south'); 63 break; 64 //ESC键 65 case 27: 66 this.stop(); 67 break; 68 //Enter键 69 case 13: 70 this.start(); 71 break; 72 } 73 }, 74 //鼠标点击事件 75 onAppend : function(e) { 76 //头部位置 77 var x=e.clientX; 78 var y=e.clientY; 79 var body=[]; 80 for(var i=0;i<Game.LENGTH;i++) 81 { 82 //从数组头部加 83 body.unshift(new Location(x-i*Game.SIZE,y)); 84 } 85 //创建snake对象 86 this.add(new Snake('#ffffff',body)); 87 //消息 88 Console.log('追加一个蛇..........'); 89 }, 90 91 }; 92 //定义常量 93 Game.SIZE = 10; 94 //刷新频率 95 Game.fps = 20; 96 //蛇长度 97 Game.LENGTH=5; 98 //初始化 99 Game.initialize = function() { 100 this.canvas = document.querySelector('#playground'); 101 if (this.canvas.getContext) { 102 var context2d = this.canvas.getContext('2d'); 103 //追加键盘事件,控制方向 104 window.addEventListener('keydown', Game.onKeydown.bind(this), 105 false); 106 //追加点击事件,追加一个Snake实例 107 this.canvas.addEventListener('click', Game.onAppend.bind(this), 108 false); 109 110 } 111 }; 112 113 //开始 114 Game.start = function() { 115 //消息 116 Console.log('游戏开始..........'); 117 var requestAnimationFrame = window.requestAnimationFrame 118 || window.mozRequestAnimationFrame 119 || window.WebKitRequestAnimationFrame; 120 if (requestAnimationFrame) { 121 this.nextFrame = function() { 122 requestAnimationFrame(Game.run); 123 }; 124 } 125 //使用定时器 126 else { 127 this.timer = setInterval(Game.run, 1000 / Game.fps); 128 } 129 if (this.nextFrame) 130 this.nextFrame(); 131 }; 132 133 //运行 134 Game.run = function() { 135 Game.draw(); 136 //动画 137 if (Game.nextFrame) 138 Game.nextFrame(); 139 }; 140 141 //停止 142 Game.stop = function() { 143 //消息 144 Console.log('游戏停止..........'); 145 if (this.timer) { 146 this.timer.clearInterval(); 147 } 148 this.nextFrame = null; 149 }; 150 151 //绘制游戏场景 152 Game.draw = function() { 153 //清除屏幕 154 this.canvas.getContext('2d').clearRect(0, 0, this.canvas.width, 155 this.canvas.height); 156 //绘制所有的snake 157 for ( var i in this.snakes) { 158 this.snakes[i].move(this.direction); 159 this.snakes[i].draw(this.canvas.getContext('2d')); 160 } 161 }; 162 163 //追加一条新的蛇 164 Game.add = function(snake) { 165 Game.snakes = Game.snakes || []; 166 Game.snakes.push(snake); 167 }; 168 169 //设置方向 170 Game.setDirection = function(direction) { 171 //消息 172 Console.log('方向是:'+direction+'..........'); 173 this.direction = direction; 174 }; 175 176 //单例,打印日志 177 var Console = {}; 178 //定义log方法 179 Console.log = function(message) { 180 //创建元素:p 181 var p = document.createElement('p'); 182 //自动换行 183 p.style.wordWrap = 'break-word'; 184 //包装消息 185 p.innerHTML = message; 186 //追加p到div 187 var console = document.querySelector('#console'); 188 console.appendChild(p); 189 //移除不要的消息 190 if (console.childNodes.length > 50) 191 //删除第一条消息 192 { 193 console.removeChild(console.firstChild); 194 } 195 //滚动条移到最下面 196 console.scrollTop = console.scrollHeight; 197 }; 198 /* 199 *类,表示Snake的位置 200 *x:横坐标 201 *y:纵坐标 202 */ 203 function Location(x, y) { 204 this.x = x; 205 this.y = y; 206 } 207 /* 208 *定义方法,根据当前的位置求下一个位置 209 *direction:表示运动的方向 210 */ 211 Location.define('getNextLocation', function(direction) { 212 var x = this.x; 213 var y = this.y; 214 switch (direction) { 215 case 'east': 216 if (Game.direction !== 'west') { 217 x += Game.SIZE; 218 if(x>=Game.canvas.width) 219 { 220 x=0; 221 } 222 } 223 break; 224 case 'south': 225 if (Game.direction !== 'north') { 226 y += Game.SIZE; 227 if(y>=Game.canvas.height) 228 { 229 y=0; 230 } 231 } 232 break; 233 case 'west': 234 if (Game.direction !== 'east') { 235 x -= Game.SIZE; 236 if(x<=0) 237 { 238 x=Game.canvas.width; 239 } 240 } 241 break; 242 case 'north': 243 if (Game.direction !== 'south') { 244 y -= Game.SIZE; 245 if(y<=0) 246 { 247 y=Game.canvas.height; 248 } 249 } 250 break; 251 } 252 return new Location(x, y); 253 }); 254 255 /* 256 *贪吃蛇类:Snake 257 *color:蛇的颜色 258 *body:身体 259 */ 260 function Snake(color, body) { 261 this.color = color; 262 this.body = body; 263 } 264 /* 265 *绘制方法 266 *context2d:绘图上下文 267 */ 268 Snake.define('draw', function(context2d) { 269 context2d.fillStyle = this.color; 270 for (var i = 0; i < this.body.length; i++) { 271 var loc = this.body[i]; 272 context2d.fillRect(loc.x, loc.y, Game.SIZE, Game.SIZE); 273 } 274 }); 275 276 /* 277 *移动方法 278 *direction:移动的方向 279 */ 280 Snake.define('move', function(direction) { 281 if(!direction) 282 return; 283 //获得头 284 var head = this.body[this.body.length - 1]; 285 //新的头 286 head = head.getNextLocation(direction); 287 //新的头部放进身体 288 this.body.push(head); 289 //删除尾巴 290 this.body.shift(); 291 }); 292 293 //启动游戏 294 Game.initialize(); 295 Game.start(); 296 </script> 297 </body> 298 </html>
运行效果如下: