下面是俄罗斯方块的截图:

请到这里下载源码:

俄罗斯方块

下面是代码:

 

  1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  2 <html xmlns="http://www.w3.org/1999/xhtml" >
  3 <head>
  4     <title></title>
  5     <script type="text/javascript">
  6         /********************************************js俄罗斯方块源码***********************************************/
  7         //作者:高山流水 QQ:21243468 
  8         //创建日期:2009-08-06
  9         //版权声明:该作品由高山流水创作,转载请注明出处,谢谢合作!
 10         //游戏设计说明:
 11         //1.由于该游戏属于二维游戏,所以布置好网格是写好该游戏的关键,无论是游戏窗口还是预览窗口、
 12         //方块集虚拟map等都用到了网格的概念,这样做的好处可以避免频繁的获取元素的位置,另外还可以对方块集的移动
 13         //进行精确的定位和变形。这里比较重要的一点就是提前定义好方块集的map,比如对于L方块集,应定义一个三乘三的正方形
 14         //网格,然后根据L的每一个形状,确定方块集中的每个方块在正方形网格中的位置,另外还需要保存方块集在map
 15         //(游戏窗口或者预览窗)中的位置,这样任意时刻,通过方块集的位置,和方块在正方形网格中的位置,就可以确定
 16         //方块集中的每一个方块在map中的位置。
 17         //2.该游戏主要用到了一些OOP的思想。比如定义一个基类base,方块集类继承自base类,其中还有对象的封装,属性,
 18         //枚举的定义等,当然还有事件,委托,attribute,垃圾收集器等,因为时间关系,就不做代码演示了,各位有兴趣可以自己
 19         //扩展一下,加深对js OOP的理解。
 20         //3.js内置对象的扩展:比如Array.prototype.removeAt等
 21         /********************************************js俄罗斯方块源码**********************************************/
 22         var Sys = null;
 23         function sys() { }
 24         sys.prototype = {
 25             GameMap: [],
 26             PreviewMap: [],
 27             BlocksObj: [],
 28             Timer: null,
 29             HorizontalNum: 10//游戏map的水平格数
 30             VerticalNum: 18//游戏map的竖直格数
 31             IsGameOver: false//判断游戏是否结束
 32             ScoreStrategy: [100300500800], //得分策略
 33             LevelScores: [10020000400006000080000100000120000140000160000200000], //分数等级
 34             IsPlay: false//游戏进行中
 35             IsFirstPlay: true//是否第一次玩
 36             SmallGridNum: 6//预览map的格子数,为正方形
 37             DirectionEnum: { left: 0, right: 1, up: 2, down: 3 }, //方向的枚举
 38             Speeds: [1000900800700600500400300200100], //速度,或者说级别
 39             CurrentSpeed: 1000//当前级别或者说速度
 40             TypeEnum: { none: 0, block: 1, blocks: 2 }, //类型
 41             BlocksEnum: [0123456789], //0为LL,1为LR,2为T,3为ZL,4为ZR,5为I,6为F,7为长T
 42             BlocksStateNum: [4442221442], //对应BlocksEnum中每个方块集的变形个数,即有多少种变形
 43             BlocksShapeMaps: [ //方块形状集的集合
 44                        [ //方块集的虚拟map集合,对应BlocksEnum,比如该map是L的map
 45                            [[[21]], [[02], [12], [22]]], //L中的其中一个变形
 46                            [[[10]], [[11]], [[12], [22]]],
 47                            [[[01], [11], [21]], [[02]]],
 48                            [[[10], [20]], [[21]], [[22]]]
 49                        ],
 50                        [
 51                            [[[20]], [[21]], [[12], [22]]],
 52                            [[[01]], [[02], [12]], [[22]]],
 53                            [[[00], [10]], [[01]], [[02]]],
 54                            [[[01], [11], [21]], [[22]]]
 55                        ],
 56                        [
 57                            [[[00], [10], [20]], [[11]]],
 58                            [[[10]], [[01], [11]], [[12]]],
 59                            [[[11]], [[02], [12], [22]]],
 60                            [[[00]], [[01], [11]], [[02]]]
 61                        ],
 62                        [
 63                            [[[00]], [[01], [11]], [[12]]],
 64                            [[[11], [21]], [[02], [12]]]
 65                        ],
 66                        [
 67                            [[[10]], [[01], [11]], [[02]]],
 68                            [[[01], [11]], [[12], [22]]]
 69                        ],
 70                        [
 71                            [[[00]], [[01]], [[02]], [[03]]],
 72                            [[[03]], [[13]], [[23]], [[33]]]
 73                        ],
 74                        [
 75                            [[[00], [01]], [[10], [11]]]
 76                        ],
 77                        [
 78                            [[[00], [10], [20]], [[11]], [[12]]],
 79                            [[[20]], [[01], [11], [21]], [[22]]],
 80                            [[[10]], [[11]], [[02], [12], [22]]],
 81                            [[[00]], [[01], [11], [21]], [[02]]]
 82                        ],
 83                        [
 84                            [[[01], [11], [21]], [[02]], [[22]]],
 85                            [[[10], [20]], [[21]], [[12], [22]]],
 86                            [[[01], [21]], [[02], [12], [22]]],
 87                            [[[10], [20]], [[11]], [[12], [22]]]
 88                        ],
 89                        [
 90                            [[[00], [10]], [[11]], [[12], [22]]],
 91                            [[[20]], [[01], [11], [21]], [[02]]]
 92                        ],
 93                       ],
 94             ColorEnum: [[00], [-280], [-560], [-840], [-1120], [-1400], [-1680], [00], [-280], [-560]], //颜色的枚举,对应BlocksEnum
 95             CreateGameMap: function() { //创建游戏map
 96                 for (var i = 0; i < this.VerticalNum; i++) {
 97                     this.GameMap.push([]);
 98                     for (var j = 0; j < this.HorizontalNum; j++) {
 99                         this.GameMap[i][j] = {};
100                         this.GameMap[i][j][Sys.TypeEnum.blocks] = null;
101                     }
102                 }
103             },
104             GetBlocks: function() { //获取GameMap里的方块集
105                 for (var i = 0; i < this.BlocksObj.length; i++) {
106                     if (this.BlocksObj[i].isInGameMap) {
107                         return this.BlocksObj[i];
108                     }
109                 }
110                 return null;
111             },
112             AllowBlocksMove: function() {  //是否允许方块集移动
113                 var blocksItem = this.GetBlocks();
114                 var itemPosArray = this._getBlocksItemPosArray(blocksItem, false);
115                 return this.NoBlocksInthePlace(itemPosArray, blocksItem) && this.CheckBoundary(itemPosArray, blocksItem);
116             },
117             GetMaxAndMinItemPosArray: function(itemPosArray) {  //获取最大最小方块位置集合
118                 itemPosArray.ItemPosXArray.sorts();
119                 itemPosArray.ItemPosYArray.sorts();
120                 return { maxItemPosX: itemPosArray.ItemPosXArray[itemPosArray.ItemPosXArray.length - 1], maxItemPosY: itemPosArray.ItemPosYArray[itemPosArray.ItemPosYArray.length - 1], minItemPosX: itemPosArray.ItemPosXArray[0], minItemPosY: itemPosArray.ItemPosYArray[0] };
121             },
122             NoBlocksInthePlace: function(itemPosArray, blocksItem) { //检测游戏方格中是否已经有方块
123                 return this._isOverMapChild(itemPosArray, blocksItem) ? false : true;
124             },
125             CheckBoundary: function(itemPosArray, blocksItem) { //是否到达边界了
126                 var maxAndMinItemPosArray = this.GetMaxAndMinItemPosArray(itemPosArray);
127                 var isNotToBoundary = false;
128                 switch (blocksItem.currentDirectionEnum) {
129                     case this.DirectionEnum.left:
130                         isNotToBoundary = (maxAndMinItemPosArray.minItemPosX > 0)
131                         break;
132                     case this.DirectionEnum.right:
133                         isNotToBoundary = (maxAndMinItemPosArray.maxItemPosX < this.HorizontalNum - 1)
134                         break;
135                     case this.DirectionEnum.down:
136                         isNotToBoundary = (maxAndMinItemPosArray.maxItemPosY < this.VerticalNum - 1);
137                         break;
138                 }
139                 return isNotToBoundary;
140             },
141             _isOverMapChild: function(itemPosArray, blocksItem) { //检测是否会覆盖某个游戏方格中的元素
142                 var isOverMapChild = false;
143                 for (var i = 0; i < itemPosArray.ItemPosYArray.length; i++) {
144                     var itemX = itemPosArray.ItemPosXArray[i];
145                     var itemY = itemPosArray.ItemPosYArray[i];
146                     if (blocksItem.currentDirectionEnum == this.DirectionEnum.left) {
147                         itemX--;
148                     }
149                     else if (blocksItem.currentDirectionEnum == this.DirectionEnum.right) {
150                         itemX++;
151                     }
152                     else if (blocksItem.currentDirectionEnum == this.DirectionEnum.down) {
153                         itemY++;
154                     }
155                     if (this.GameMap[itemY] && this.GameMap[itemY][itemX] && this.GameMap[itemY][itemX][this.TypeEnum.blocks] != null) {
156                         isOverMapChild = true;
157                         break;
158                     }
159                 }
160                 return isOverMapChild;
161             },
162             _getBlocksItemPosArray: function(blocksItem, isRelative) {  //获取方块集的位置集合,isRelative=true获取的是方块相对方块集map的位置,否则是方块相对游戏map的位置
163                 var itemPosXArray = [];
164                 var itemPosYArray = [];
165                 for (var i = 0; i < blocksItem.blocks.length; i++) {
166                     if (isRelative) {
167                         itemPosXArray.push(blocksItem.blocks[i].x);
168                         itemPosYArray.push(blocksItem.blocks[i].y);
169                     }
170                     else {
171                         itemPosXArray.push(blocksItem.blocks[i].x + blocksItem.x);
172                         itemPosYArray.push(blocksItem.blocks[i].y + blocksItem.y);
173                     }
174                 }
175                 return { ItemPosXArray: itemPosXArray, ItemPosYArray: itemPosYArray };
176             },
177             GetBlocksInitPos: function(blocks) { //获取方块的初始位置
178                 var blocksItem = null;
179                 if (!blocks)
180                     blocksItem = this.GetBlocks();
181                 else
182                     blocksItem = blocks;
183                 var itemPosArray = this._getBlocksItemPosArray(blocksItem, true);
184                 itemPosArray.ItemPosXArray = itemPosArray.ItemPosXArray.filter();
185                 itemPosArray.ItemPosYArray = itemPosArray.ItemPosYArray.filter();
186                 var childsNumX = itemPosArray.ItemPosXArray.length;
187                 var childsNumY = itemPosArray.ItemPosYArray.length;
188                 var maxAndMinItemPosArray = this.GetMaxAndMinItemPosArray(itemPosArray);
189                 if (blocks) //获取方块集在预览map中的初始位置
190                     return { x: (this.SmallGridNum - childsNumX - 1/ 2 + 0.5 - maxAndMinItemPosArray.minItemPosX, y: (this.SmallGridNum - childsNumY - 1/ 2 + 0.5 - maxAndMinItemPosArray.minItemPosY };
191                 else //获取方块集在游戏map中的初始位置
192                     return { x: parseInt((this.HorizontalNum - childsNumX - 1/ 2+ 1 - maxAndMinItemPosArray.minItemPosX, y: -(childsNumY + maxAndMinItemPosArray.minItemPosY) };
193             },
194             GetNextActiviteBrocks: function() { //获取下一个活动的方块集
195                 for (var i = 0; i < this.BlocksObj.length; i++) {
196                     if (this.BlocksObj[i].isInGameMap) {
197                         this.BlocksObj.removeAt(i);
198                     }
199                 }
200                 this.BlocksObj[0].isInGameMap = true;
201                 var itemPos = this.GetBlocksInitPos();
202                 this.BlocksObj[0].x = itemPos.x;
203                 this.BlocksObj[0].y = itemPos.y;
204                 this.BlocksObj[0].AddToMap(falsefalse);
205                 this.CreateBlocks();
206             },
207             PlayGame: function() { //启动游戏
208                 this.IsPlay = true;
209                 this.NaturalMove();
210                 if (!this.IsFirstPlay) {
211                     return;
212                 }
213                 this.GetNextActiviteBrocks();
214             },
215             AddToGameMapGrid: function() { //加入到游戏map网格中
216                 var blocks = this.GetBlocks();
217                 blocks.UseGrid(this.GameMap, blocks);
218             },
219             GetScore: function() { //分数处理
220                 var rowIndexArray = [];
221                 for (var i = 0; i < this.VerticalNum; i++) { //获取满行的行数
222                     var entireRow = true;
223                     for (var j = 0; j < this.HorizontalNum; j++) {
224                         if (this.GameMap[i][j][this.TypeEnum.blocks] == null) {
225                             entireRow = false;
226                             break;
227                         }
228                     }
229                     if (entireRow)
230                         rowIndexArray.push(i);
231                 }
232                 if (rowIndexArray.length > 0) {
233                     this._FreeMapGrid(rowIndexArray);
234                     document.getElementById("score").innerText = this.ScoreStrategy[rowIndexArray.length - 1+ parseInt(document.getElementById("score").innerText);
235                     this.CheckTheLevel();
236                 }
237             },
238             CheckTheLevel: function() { //检测是否进入下一个级别
239                 var currentScore = parseInt(document.getElementById("score").innerText);
240                 var speedList = document.getElementById("speed");
241                 var currentLevel = parseInt(speedList.options[speedList.selectedIndex].text) - 1;
242                 var levelScore = this.LevelScores[currentLevel];
243                 if (currentScore >= levelScore) {
244                     if (currentLevel < this.LevelScores.length) {
245                         var element = document.getElementById("gameOver");
246                         element.innerText = "恭喜你通过第" + (speedList.selectedIndex + 1+ "";
247                         element.style.display = "block";
248                         this.PauseGame();
249                         document.getElementById("btnStart").disabled = true;
250                         document.getElementById("speed").disabled = true;
251                         this._goToNextLevel.delay(3000);
252                     }
253                     else {
254                         this._finishAllTheLevel(element);
255                     }
256                 }
257             },
258             _goToNextLevel: function() { //进入下一个级别,速度加快
259                 Sys.IsPlay = true;
260                 document.getElementById("btnStart").disabled = false;
261                 var speedList = document.getElementById("speed");
262                 speedList.disabled = false;
263                 speedList.options[speedList.selectedIndex + 1].selected = true;
264                 Sys.CurrentSpeed = Sys.Speeds[speedList.selectedIndex + 1];
265                 Sys.NaturalMove();
266                 document.getElementById("gameOver").style.display = "none";
267             },
268             _finishAllTheLevel: function() { //完成所有的游戏级别
269                 this.PauseGame();
270             },
271             _FreeMapGrid: function(rowIndexArray) { //从游戏map中释放满行的网格
272                 var gameMap = this.GameMap;
273                 var startIndex = rowIndexArray[0];
274                 var len = rowIndexArray.length;
275                 var maxIndex = startIndex + len - 1;
276                 for (var i = startIndex; i <= maxIndex; i++) {
277                     for (var j = 0; j < this.HorizontalNum; j++) {
278                         if (gameMap[i][j][this.TypeEnum.blocks] != null) {
279                             document.getElementById("map").removeChild(gameMap[i][j][this.TypeEnum.blocks].domElement);
280                             gameMap[i][j][this.TypeEnum.blocks] = null;
281                         }
282                     }
283                 }
284                 this.ResetMapGrid(rowIndexArray);
285             },
286             ResetMapGrid: function(rowIndexArray) { //重置游戏网格
287                 var gameMap = this.GameMap;
288                 var maxIndex = rowIndexArray[0];
289                 var len = rowIndexArray.length;
290                 for (var i = maxIndex - 1; i >= 0; i--) {
291                     for (var j = 0; j < this.HorizontalNum; j++) {
292                         if (gameMap[i][j][this.TypeEnum.blocks] != null) {
293                             this._resetMapElement(gameMap[i][j][this.TypeEnum.blocks].domElement, len);
294                             gameMap[i + len][j][this.TypeEnum.blocks] = gameMap[i][j][this.TypeEnum.blocks];
295                             gameMap[i][j][this.TypeEnum.blocks] = null;
296                         }
297                     }
298                 }
299             },
300             _resetMapElement: function(element, len) { //重置dom元素,比如共有满行两行,则之上的元素均需下降两个
301                 element.style.top = (parseInt(element.style.top) + 28 * len) + "px";
302             },
303             InitSpeed: function() { //初始化游戏级别
304                 var speedList = document.getElementById("speed");
305                 if (speedList.options.length == 0) {
306                     for (var i = 0; i < this.Speeds.length; i++) {
307                         var varItem = new Option(i + 1this.Speeds[i]);
308                         speedList.options.add(varItem);
309                     }
310                 }
311                 this.SetSpeedSelected();
312             },
313             SetSpeedSelected: function() { //选中级别
314                 var speedList = document.getElementById("speed");
315                 for (var i = 0; i < speedList.options.length; i++) {
316                     if (speedList.options[i].value == this.CurrentSpeed) {
317                         speedList.options[i].selected = true;
318                         break;
319                     }
320                 }
321             },
322             GameOver: function() { //游戏结束
323                 this.IsGameOver = true;
324                 this.PauseGame();
325                 var element = document.getElementById("gameOver");
326                 element.innerText = "Game Over!";
327                 element.style.display = "block";
328                 document.getElementById("btnStart").value = "try again";
329             },
330             PauseGame: function() { //暂停游戏
331                 this.IsPlay = false;
332                 clearInterval(this.Timer);
333             },
334             CreateBlocks: function() { //创建方块集
335                 var currentNum = this.BlocksEnum.length.getRandom();
336                 var blocks = new Blocks(00this.BlocksStateNum[currentNum], currentNum, this.ColorEnum[currentNum]);
337                 blocks.Init();
338                 if (this.BlocksObj.length == 3)
339                     Sys.BlocksObj.pop();
340                 Sys.BlocksObj.push(blocks);
341             },
342             NaturalMove: function() { //自然下落
343                 this.Timer = setInterval("Moving()", Sys.CurrentSpeed);
344             }
345         }
346         function Base() { } //定义base类
347         Base.prototype.AddToMap = function(isAddToPreviewMap, isMoving) { //添加方块集到map中
348             for (var i = 0; i < this.blocks.length; i++) {
349                 var element = null;
350                 if (!this.isInGameMap) { //如果方块集是在预览map中
351                     element = document.createElement("DIV");
352                     document.getElementById("PreviewMap").appendChild(element);
353                     this.blocksElement.push(element);
354                     this.blocks[i].domElement = element;
355                 }
356                 else
357                     element = this.blocksElement[i];
358                 if (!isAddToPreviewMap && !isMoving) //由预览map移动到游戏map时
359                     document.getElementById("map").appendChild(element);
360                 element.style.position = "absolute";
361                 element.style.left = ((this.x + this.blocks[i].x) * 28+ "px"//设置元素所在的map的位置
362                 element.style.top = ((this.y + this.blocks[i].y) * 28+ "px";
363                 element.style.backgroundPositionX = this.color[0];
364                 element.style.backgroundPositionY = this.color[1];
365             }
366         }
367         Base.prototype.UseGrid = function(map, blocksItem) { //方块集加入到游戏map中
368             for (var i = 0; i < blocksItem.blocks.length; i++) {
369                 var itemX = blocksItem.x + blocksItem.blocks[i].x;
370                 var itemY = blocksItem.y + blocksItem.blocks[i].y;
371                 if (blocksItem.y < 0) {
372                     Sys.GameOver();
373                     return;
374                 }
375                 map[itemY][itemX] = {};
376                 map[itemY][itemX][this.type] = blocksItem.blocks[i];
377             }
378         }
379         function Block(x, y) { //定义方块结构体
380             this.x = x;
381             this.y = y;
382             this.type = Sys.TypeEnum.block;
383             this.domElement = null;
384         }
385         function Blocks(x, y, state, blocksEnum, colorEnum) { //方块集类
386             this.x = x;
387             this.y = y;
388             this.state = state;
389             this.blocksEnum = blocksEnum;  //方块类型(比如L,I,田字形,Z等)
390             this.color = colorEnum;
391             this.type = Sys.TypeEnum.blocks; //废弃属性
392             this.blocks = []; //方块集下的方块的集合
393             this.blocksElement = []; //方块集下的方块的对应dom元素集
394             this.currentState = 0//当前的状态,比如L有四种类型的变形
395             this.isInGameMap = false//是否在游戏map中
396             this.currentDirectionEnum = Sys.DirectionEnum.down; //默认方向向下
397         }
398         Blocks.prototype = new Base(); //继承base类
399         Blocks.prototype.Init = function() {//初始化blocks
400             var blocksPoses = Sys.BlocksShapeMaps[this.blocksEnum];
401             this.currentState = Sys.BlocksStateNum[this.blocksEnum].getRandom(); //随机获取方块集的状态
402             var blocksPos = blocksPoses[this.currentState]; //获取方块集的map
403             for (var i = 0; i < blocksPos.length; i++) {
404                 for (var j = 0; j < blocksPos[i].length; j++) {
405                     var block = new Block(blocksPos[i][j][0], blocksPos[i][j][1]);
406                     this.blocks.push(block);
407                 }
408             }
409             var itemPos = Sys.GetBlocksInitPos(this); //获取初始位置,也就是说在预览map中的位置
410             this.x = itemPos.x;
411             this.y = itemPos.y;
412             this.AddToMap(truefalse); //加入到预览map中
413         }
414         Blocks.prototype.ChangeShape = function() {//方块变换形状
415             var gameMap = Sys.GameMap;
416             var allowChangeShape = true;
417             var blocksPoses = Sys.BlocksShapeMaps[this.blocksEnum];
418             var num = Sys.BlocksStateNum[this.blocksEnum];
419             var currentState1 = -1;
420             this.currentState == num - 1 ? currentState1 = 0 : currentState1 = this.currentState + 1;
421             var blocksPos = blocksPoses[currentState1];
422             var k = 0;
423             for (var i = 0; i < blocksPos.length; i++) { //主要是检测方块集的下一个变形是否合理
424                 for (var j = 0; j < blocksPos[i].length; j++) {
425                     var block = this.blocks[k];
426                     var itemX = this.x + blocksPos[i][j][0];
427                     var itemY = this.y + blocksPos[i][j][1];
428                     if ((itemX > Sys.HorizontalNum - 1|| (itemX < 0|| (itemY > Sys.VerticalNum - 1|| itemY >= 0 && gameMap[itemY][itemX] != null && gameMap[itemY][itemX][Sys.TypeEnum.blocks] != null) {
429                         allowChangeShape = false;
430                         break;
431                     }
432                     k++;
433                 }
434             }
435             if (allowChangeShape)//如果允许变形
436             {
437                 this.currentState == num - 1 ? this.currentState = 0 : this.currentState++//设置下一个变形的状态
438                 k = 0;
439                 for (var i = 0; i < blocksPos.length; i++) {
440                     for (var j = 0; j < blocksPos[i].length; j++) {
441                         var block = this.blocks[k];
442                         block.x = blocksPos[i][j][0];
443                         block.y = blocksPos[i][j][1];
444                         k++;
445                     }
446                 }
447                 this.AddToMap(falsetrue); //变形后加入到游戏map中
448             }
449         }
450         Blocks.prototype.BlocksMoveDown = function(isMoving) { //方块集下落
451             this.currentDirectionEnum = Sys.DirectionEnum.down;
452             if (!Sys.AllowBlocksMove()) { //如果不允许移动
453                 Sys.AddToGameMapGrid(); //固定方块集在游戏map中的位置
454                 Sys.GetScore(); //得分处理
455                 Sys.GetNextActiviteBrocks(); //获取下一个方块集
456             }
457             else { //下落一格
458                 this.y++;
459                 this.AddToMap(false, isMoving);
460             }
461         }
462         Number.prototype.getRandom = function() {//获取0至number之间的随机数
463             var num = this;
464             var i = this + 1;
465             while (i >= num) {
466                 i = Math.round(Math.random() * 10);
467             }
468             return i;
469         }
470         Array.prototype.sorts = function() { return this.sort(compare); } //数组排序,按照升序排序
471         function compare(a, b) { return a - b; } //定义排序规则
472         Array.prototype.removeAt = function(dx) { //清除指定索引的数组元素
473             if (isNaN(dx) || dx > this.length) { return false; }
474             for (var i = 0, n = 0; i < this.length; i++) {
475                 if (this[i] != this[dx])
476                     this[n++= this[i];
477             }
478             this.length -= 1;
479         }
480         Array.prototype.filter = function() { //清除数组中的重复值
481             var arr = [];
482             for (var i = 0; i < this.length; i++) {
483                 if (!arr.contains(this[i]))
484                     arr.push(this[i]);
485             }
486             return arr;
487         }
488         Array.prototype.contains = function(item) { //检测数组是否包含某元素
489             for (var i = 0; i < this.length; i++) {
490                 if (this[i] == item)
491                     return true;
492             }
493             return false;
494         }
495         Function.prototype.delay = function(time) { var timer = setTimeout(this, time); } //函数延迟time毫秒执行
496         window.onload = InitGame;
497         function InitGame() {//初始化游戏
498             Sys = new sys();
499             Sys.BlocksObj = [];
500             Sys.InitSpeed(); //初始化游戏速度
501             Sys.CreateGameMap(); //创建游戏map
502             Sys.CreateBlocks(); //创建方块集
503         }
504         function GameStart(element) {
505             if (element.value == "start") { //开始游戏
506                 element.value = "pause";
507                 Sys.PlayGame();
508                 Sys.IsFirstPlay = false;
509             }
510             else if (element.value == "pause") { //暂停游戏
511                 element.value = "start"
512                 Sys.PauseGame();
513             }
514             else { //游戏结束后重新开始
515                 window.location.reload();
516             }
517         }
518         function Moving() {//移动
519             Sys.GetBlocks().BlocksMoveDown(false);
520         }
521         function ChangeSpeed(e) {//切换级别
522             var speedlist = document.getElementById("speed");
523             Sys.CurrentSpeed = speedlist.options[speedlist.selectedIndex].value;
524             if (!Sys.IsGameOver) {
525                 clearInterval(Sys.Timer);
526                 this.NaturalMove();
527             }
528         }
529         function keyDown(e) { //按键操作
530             if (Sys.IsGameOver || !Sys.IsPlay) return;
531             var blocks = Sys.GetBlocks();
532             if (e.keyCode == 37) {  //向左
533                 blocks.currentDirectionEnum = Sys.DirectionEnum.left;
534                 if (Sys.AllowBlocksMove())
535                     blocks.x--;
536                 if (blocks.x != 0)
537                     blocks.AddToMap(falsetrue);
538             }
539             else if (e.keyCode == 38) {  //向上
540                 blocks.currentDirectionEnum = Sys.DirectionEnum.up;
541                 blocks.ChangeShape();
542             }
543             else if (e.keyCode == 39) { //向右
544                 blocks.currentDirectionEnum = Sys.DirectionEnum.right;
545                 var oldX = blocks.x;
546                 if (Sys.AllowBlocksMove())
547                     blocks.x++;
548                 if (blocks.x != oldX)
549                     blocks.AddToMap(falsetrue);
550             }
551             else if (e.keyCode == 40)  //向下
552             {
553                 blocks.currentDirectionEnum = Sys.DirectionEnum.down;
554                 blocks.BlocksMoveDown(true);
555             }
556         }
557     </script>
558      <style type="text/css">
559      body
560      {
561         background-color:#ffffff;
562         overflow:hidden;
563         font-size:14px;
564      }
565      .gameZone
566      {
567         position:absolute;
568         left:0px;
569         top:0px;
570         width:100%;
571         height:550px;
572         background-Color:white;
573      }
574     .mask
575     {
576         position:absolute;
577         left:100px;
578         top:0px;
579         width:300px;
580         height:20px;
581         background-color:White;
582         border:solid 0px;
583         z-index:5;
584     }
585     .map
586     {
587         position:absolute;
588         left:100px;
589         top:20px;
590         width:280px;
591         height:504px;
592         background-image:url(images/tetris_grid.gif);
593         border:solid 3px green;
594     }
595     .gameOver
596     {
597         position:absolute;
598         left:100px;
599         top:20px;
600         width:280px;
601         height:504px;
602         font-weight:800;
603         font-size:xx-large;
604         color:Red;
605         text-align:center;
606         border:solid 3px;
607         line-height:420px;
608         display:none;
609         filter: Alpha(Opacity=80); 
610         background-color:pink;
611     }
612      .map div
613     {
614      BACKGROUND-IMAGE: url(images/tetris.gif); 
615      WIDTH: 28px; 
616      BACKGROUND-REPEAT: no-repeat; 
617      POSITION: absolute; 
618      HEIGHT: 28px
619     }
620     .PreviewMap
621     {
622         position:absolute;
623         left:400px;
624         top:20px;
625         width:168px;
626         height:168px;
627         background-color:pink;
628         border:solid 2px green;
629     }
630     .PreviewMap div
631     {
632      BACKGROUND-IMAGE: url(images/tetris.gif); 
633      WIDTH: 28px; 
634      BACKGROUND-REPEAT: no-repeat; 
635      POSITION: absolute; 
636      HEIGHT: 28px
637     }
638     .start
639     {
640         position:absolute;
641         left:400px;
642         top:240px;
643         width:168px;
644         height:40px;
645     }
646      .scoreSpeed
647     {
648         position:absolute;
649         left:400px;
650         top:200px;
651         width:190px;
652         height:40px;
653     }
654     .score
655     {
656         color:pink;
657         font-weight:bold;
658         width:20px;
659         height:20px;
660         background-color:blue;
661         padding-left:10px;
662         padding-right:10px;
663         font-size:medium;
664     }
665     .speed
666     {
667         color:pink;
668         font-weight:bold;
669         width:20px;
670         height:20px;
671         background-color:blue;
672         padding-left:5px;
673         padding-right:5px;
674         font-size:medium;
675     }
676      .copyright
677     {
678         position:absolute;
679         left:400px;
680         top:280px;
681         word-break:break-all; 
682         width:160px;
683         height:225px;
684         border:solid 2px green;
685         padding:5px;
686     }
687     </style>
688 </head>
689 <body  onkeydown="keyDown(event)">
690 <div class="gameZone">
691 <div id="mask" class="mask"></div>
692 <div id="map" class="map"></div>
693 <div id="gameOver" class="gameOver"></div>
694 <div id="PreviewMap" class="PreviewMap"></div>
695 <div id="scoreSpeed" class="scoreSpeed">得分:<span id="score" class="score">0</span></div>
696 <div id="start" class="start">
697 <input type="button" id="btnStart" value="start" onclick="GameStart(this);" />&nbsp;
698 级别:<select id="speed" onchange="ChangeSpeed();"></select>
699 </div>
700 <div id="copyright" class="copyright">
701 <b><center>版权所有</center></b><br />
702 此俄罗斯方块由高山流水开发,欢迎各位使用,
703 如有bug或者好的意见,请给我留言,谢谢支持!
704 另如需转载,请注明出处!<br />
705 <font color=red><b>顺便,宣传一下我的MVC qq群:45660795,欢迎加入!</b></font>
706 <br /><br />
707 作者:<a href="http://www.cnblogs.com/JackFeng/" target="_blank">高山流水</a><br />
708 QQ:21243468
709 </div>
710 </div>
711 </body>
712 </html>

 

 

 

posted on 2010-12-10 23:45  高山流水2012  阅读(2052)  评论(12编辑  收藏  举报