html5 canvas做的俄罗斯方块
做的有点乱,主要是为了练手
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 5 <title>俄罗斯方块</title> 6 <meta charset="utf-8" /> 7 <style type="text/css"> 8 #canvas { 9 background-color: #eee; 10 } 11 12 body { 13 text-align: center; 14 } 15 </style> 16 <script type="text/javascript"> 17 window.onload = function myfunction() { 18 var canvas = document.getElementById("canvas"); 19 var cobj = canvas.getContext("2d"); 20 var size = 30; 21 var width = 240; 22 var height = 450; 23 var wNum = width / size; 24 var hNum = height / size; 25 var fenshuNum = 0; 26 document.getElementById("btnStart").onclick = function () { 27 28 } 29 dewaBorder(); 30 //drawBorder 31 function dewaBorder() { 32 cobj.clearRect(0, 0, canvas.width, canvas.height); 33 var color = "#ddd"; 34 for (var i = 0; i <= wNum ; i++) { 35 drawLine(i * size, 0, i * size, height, color); 36 } 37 for (var i = 0; i <= hNum ; i++) { 38 drawLine(0, i * size, width, i * size, color); 39 } 40 function drawLine(startX, startY, endX, endY, color) { 41 cobj.beginPath(); 42 cobj.strokeStyle = color; 43 cobj.lineWidth = 1; 44 cobj.moveTo(endX, endY); 45 cobj.lineTo(startX, startY); 46 cobj.closePath(); 47 cobj.stroke(); 48 } 49 } 50 51 var arr = []; 52 arr.push({ color: "#fffddd", w: 2, h: 2, data: [[0, 1], [1, 0]] }); 53 arr.push({ color: "#f00", w: 4, h: 1, data: [[1, 1, 1, 1]] }); 54 arr.push({ color: "#0f0", w: 1, h: 1, data: [[1]] }); 55 arr.push({ color: "#B3D325", w: 2, h: 3, data: [[0, 1], [1, 1], [0, 1]] }); 56 arr.push({ color: "#854AA6", w: 2, h: 3, data: [[0, 1], [0, 1], [1, 1]] }); 57 arr.push({ color: "#812AA6", w: 2, h: 3, data: [[1, 1], [0, 1], [0, 1]] }); 58 arr.push({ color: "#85b5A6", w: 2, h: 2, data: [[1, 1], [1, 1]] }); 59 60 var currentArr = null;//当前操作的对象 61 var allArr = []; 62 63 64 //初始化形状 65 function initShape(index) { 66 // index = 6; 67 currentArr = []; 68 var item = arr[index]; 69 var startDot = Math.floor((wNum - item.w) / 2); 70 var y = 1 - item.h; 71 for (var i = 0; i < item.h; i++) { 72 var x = startDot; 73 for (var j = 0; j < item.w; j++) { 74 if (item.data[i][j] == 1) { 75 currentArr.push({ 76 color: item.color, 77 x: x, 78 y: y 79 }); 80 } 81 x++; 82 } 83 y++; 84 } 85 } 86 //画形状 87 function drawShape() { 88 for (var i = 0; i < allArr.length; i++) { 89 var item = allArr[i]; 90 drawRec(item.x * size, item.y * size, item.color); 91 } 92 for (var i = 0; i < currentArr.length; i++) { 93 var item = currentArr[i]; 94 drawRec(item.x * size, item.y * size, item.color); 95 } 96 } 97 function isOK(keyCode) { 98 for (var i = 0; i < currentArr.length; i++) { 99 var item = currentArr[i]; 100 switch (keyCode) { 101 case 37://左 102 if (!isExist(item.x - 1, item.y)) 103 return false; 104 break; 105 case 38://上 106 107 break; 108 case 39://右 109 if (!isExist(item.x + 1, item.y)) 110 return false; 111 break; 112 case 40://下 113 if (!isExist(item.x, item.y + 1)) 114 return false; 115 break; 116 default: 117 break; 118 } 119 } 120 return true; 121 } 122 123 function isExist(x, y) { 124 if (x < 0 || x >= width / size || y >= height / size) { 125 return false; 126 } 127 for (var i = 0; i < allArr.length; i++) { 128 var item = allArr[i]; 129 if (item.x == x && item.y == y) { 130 return false; 131 } 132 } 133 return true; 134 } 135 136 function down() { 137 if (!isOK(40)) { 138 return false; 139 } 140 for (var i = 0; i < currentArr.length; i++) { 141 currentArr[i].y++; 142 } 143 return true 144 } 145 function left() { 146 if (!isOK(37)) { 147 return; 148 } 149 for (var i = 0; i < currentArr.length; i++) { 150 currentArr[i].x--; 151 } 152 } 153 function rigth() { 154 if (!isOK(39)) { 155 return; 156 } 157 for (var i = 0; i < currentArr.length; i++) { 158 currentArr[i].x++; 159 } 160 } 161 function up() { 162 /* 163 逆时针旋转 164 //设原点(x,y),中心点(x0,y0) ,原点绕中心点旋转90度后为(x1,y1); 165 //则(x-x0)(x1-x0)+(y-y0)(y1-y0)=0 166 //所以 x1-x0=y-y0 且 y1-y0= -(x-x0) ; 167 //解得一通解为 x1=y-y0+x0,y1=x0-x+y0 ,这就是旋转90度的坐标变换公式 168 */ 169 var x0, y0, minX, maxX, minY, maxY; 170 for (var i = 0; i < currentArr.length; i++) { 171 var item = currentArr[i]; 172 if (i == 0) { 173 minX = maxX = item.x; 174 minY = maxY = item.y; 175 } else { 176 if (minX > item.x) 177 minX = item.x; 178 if (maxX < item.x) 179 maxX = item.x; 180 if (minY > item.y) 181 minY = item.y; 182 if (maxY < item.y) 183 maxY = item.y; 184 } 185 } 186 x0 = Math.floor((maxX + 1 - minX) / 2 + minX); 187 y0 = Math.floor((maxY + 1 - minY) / 2 + minY); 188 var tempArr = []; 189 190 for (var i = 0; i < currentArr.length; i++) { 191 var item = clone(currentArr[i]); 192 tempArr.push(item); 193 } 194 for (var i = 0; i < tempArr.length; i++) { 195 var item = tempArr[i]; 196 var tempx = item.x; 197 item.x = item.y - y0 + x0; 198 item.y = x0 - tempx + y0; 199 if (!isExist(item.x, item.y)) { 200 return; 201 } 202 } 203 currentArr = []; 204 for (var i = 0; i < tempArr.length; i++) { 205 var item = clone(tempArr[i]); 206 currentArr.push(item); 207 } 208 } 209 210 function clone(myObj) { 211 if (typeof (myObj) != 'object') return myObj; 212 if (myObj == null) return myObj; 213 214 var myNewObj = new Object(); 215 216 for (var i in myObj) 217 myNewObj[i] = clone(myObj[i]); 218 219 return myNewObj; 220 } 221 //画小方块 222 function drawRec(x, y, color) { 223 cobj.fillStyle = color; 224 cobj.fillRect(x, y, size, size); 225 } 226 var time1 = setInterval(function () { 227 if (currentArr != null) { 228 if (!down()) { 229 var clearRowArr = checkClear(); 230 for (var i = 0; i < clearRowArr.length; i++) { 231 var rowIndex = clearRowArr[i]; 232 for (var j = currentArr.length - 1; j >= 0; j--) { 233 if (currentArr[j].y == rowIndex) { 234 currentArr.splice(j, 1); 235 } 236 } 237 for (var j = allArr.length - 1; j >= 0; j--) { 238 if (allArr[j].y == rowIndex) { 239 allArr.splice(j, 1); 240 } 241 } 242 for (var j = 0; j < allArr.length; j++) { 243 if (allArr[j].y < rowIndex) { 244 allArr[j].y++; 245 } 246 } 247 248 for (var j = 0; j < currentArr.length; j++) { 249 if (currentArr[j].y < rowIndex) { 250 currentArr[j].y++; 251 } 252 } 253 fenshuNum++; 254 window.document.getElementById("fenshu").innerText = "总分:" + fenshuNum; 255 } 256 for (var i = 0; i < currentArr.length; i++) { 257 if (currentArr[i].y < 0) { 258 clearInterval(time1); 259 clearInterval(time2); 260 alert("游戏结束"); 261 return; 262 } 263 } 264 for (var i = 0; i < currentArr.length; i++) { 265 allArr.push(currentArr[i]); 266 } 267 initShape(Math.floor(Math.random() * arr.length)); 268 } 269 } else { 270 initShape(Math.floor(Math.random() * arr.length)); 271 } 272 }, 500); 273 274 function checkClear() { 275 var clearRow = []; 276 for (var i = 0; i < height / size; i++) { 277 var flag = false; 278 for (var j = 0; j < width / size; j++) { 279 if (!isExist2(allArr, currentArr, j, i)) { 280 flag = false; 281 break; 282 } else { 283 flag = true; 284 } 285 } 286 if (flag) { 287 clearRow.push(i); 288 } 289 } 290 return clearRow; 291 } 292 293 function isExist2(arr1, arr2, x, y) { 294 for (var i = 0; i < arr1.length; i++) { 295 var item = arr1[i]; 296 if (item.x == x && item.y == y) { 297 return true; 298 } 299 } 300 for (var i = 0; i < arr2.length; i++) { 301 var item = arr2[i]; 302 if (item.x == x && item.y == y) { 303 return true; 304 } 305 } 306 } 307 308 309 310 311 var time2 = setInterval(function () { 312 if (currentArr != null) { 313 dewaBorder(); 314 drawShape(); 315 } 316 }, 20); 317 318 document.onkeydown = function (event) { 319 var e = event || window.event || arguments.callee.caller.arguments[0]; 320 if (!e) { 321 return; 322 } 323 if (e.keyCode == 37) {//左 324 left(); 325 } else if (e.keyCode == 38) {//上 326 up(); 327 } else if (e.keyCode == 39) {//右 328 rigth(); 329 } else if (e.keyCode == 40) {//下 330 down(); 331 } 332 } 333 } 334 </script> 335 </head> 336 <body> 337 <canvas id="canvas" width="240" height="450"> 338 您的浏览器不支持 339 </canvas> 340 <input type="button" id="btnStart" value="开始" /> 341 <h3 id="fenshu"></h3> 342 </body> 343 </html>