俄罗斯方块
24 May 2012源码:
001 function Tetris(){}
002 Tetris.prototype={
003 BlogsSetting:[//方块设置
004 [
005 [1,1,1,1],
006 [,,,],
007 [,,,],
008 [,,,]
009 ],
010 [
011 [1,1,1,],
012 [1,,,],
013 [,,,],
014 [,,,]
015 ],
016 [
017 [1,1,1,],
018 [,1,,],
019 [,,,],
020 [,,,]
021 ],
022 [
023 [1,1,1,],
024 [,,1,],
025 [,,,],
026 [,,,]
027 ],
028 [
029 [1,1,,],
030 [,1,1,],
031 [,,,],
032 [,,,]
033 ],
034 [
035 [,1,1,],
036 [1,1,,],
037 [,,,],
038 [,,,]
039 ],
040 [
041 [1,1,,],
042 [1,1,,],
043 [,,,],
044 [,,,]
045 ]
046 ],
047 GameMap:[],//游戏地图,对应table中的td值
048 BlokWidth:28,//方块集的宽高,也就是images/tetris_grid.gif图片的宽高
049 HorizontalNum:10,//水平td数量
050 VerticalNum:18,//垂直td数量
051 BlokSize:4,//设置方块占用位置4 * 4
052 BlockWidth:,//获取当前方块的非0的最大宽度
053 BlockHeight:,//获取当前方块的非0的最大高度
054 CurrentIndex:,//当前随机获得的索引
055 NextCurrentIndex:,//获取下一个方块的索引
056 BlokCurrent:[],//当前方块
057 InitPosition:{},//当前方块运动的x,y
058 IsPlay:false,//是否开始游戏
059 IsOver:false,//游戏是否结束
060 IsOverIndex:,//设置游戏结束的索引还有空几行
061 Score:,
062 ScoreIndex:100,
063 ColorEnum: [[, ], [-28, ], [-56, ], [-84, ], [-112, ], [-140, ], [-168, ], [, ]], //颜色的枚举,对应BlogsSetting
064 CreateMap:function(){
065 //加载地图,设置其宽高,根据HorizontalNum,VerticalNum的数量决定
066 var map = document.getElementById("map");
067 var w = this.BlokWidth*this.HorizontalNum;
068 var h = this.BlokWidth*this.VerticalNum;
069 map.style.width=w+"px";
070 map.style.height=h+"px";
071 //加载地图对应的数组,初始化为0,当被占据时为1
072 for(var i=;i<this.VerticalNum;i++){
073 this.GameMap.push([]);
074 for(var j=;j<this.HorizontalNum;j++){
075 this.GameMap[i][j]=;
076 }
077 }
078 //创建table td填充div根据HorizontalNum,VerticalNum的数量决定,创建HorizontalNum * VerticalNum的表格区域
079 var table = document.createElement("table");
080 table.id="area";
081 var tbody = document.createElement("tbody");
082 table.cellPadding=;
083 table.cellSpacing=;
084 table.appendChild(tbody);
085 for(var i=;i<this.VerticalNum;i++){
086 var tr = document.createElement("tr");
087 for(var j=;j<this.HorizontalNum;j++){
088 var td = document.createElement("td");
089 tr.appendChild(td);
090 }
091 tbody.appendChild(tr);
092 }
093 map.appendChild(table);
094 this.CreatePreViewMap();
095 this.CreateNextBlock();
096 },
097 CreatePreViewMap:function(){//加载一个4*4的表格到预览区域
098 var preview = document.getElementById("previewArea");
099 var table = document.createElement("table");
100 table.id="perviewTable";
101 var tbody = document.createElement("tbody");
102 table.cellPadding=;
103 table.cellSpacing=;
104 table.appendChild(tbody);
105 for(var i=;i<this.BlokSize;i++){
106 var tr = document.createElement("tr");
107 for(var j=;j<this.BlokSize;j++){
108 var td = document.createElement("td");
109 tr.appendChild(td);
110 }
111 tbody.appendChild(tr);
112 }
113 preview.appendChild(table);
114 },
115 LoadPreview:function(index){//加载到预览区域
116 var previewTable = document.getElementById("perviewTable");
117 for(var i=;i<this.BlogsSetting[index].length;i++){
118 for(var j=;j<this.BlogsSetting[index][i].length;j++){
119 previewTable.rows[i].cells[j].style.backgroundImage="";
120 if(this.BlogsSetting[index][i][j]==1){
121 previewTable.rows[i].cells[j].style.backgroundImage="url(images/tetris.gif)";
122 previewTable.rows[i].cells[j].style.backgroundPosition=this.ColorEnum[index][]+"px"+" "+this.ColorEnum[index][1]+"px";
123 }
124 }
125 }
126 },
127 SettingBlock:function(){//设置地图中方块的背景图片
128 var tb = this.getTable();
129 for(var i=;i<=this.BlockHeight;i++){
130 for(var j=;j<=this.BlockWidth;j++){
131 if(this.BlokCurrent[i][j]==1){
132 tb.rows[this.InitPosition.y+i].cells[this.InitPosition.x+j].style.backgroundImage="url(images/tetris.gif)";
133 tb.rows[this.InitPosition.y+i].cells[this.InitPosition.x+j].style.backgroundPosition=this.ColorEnum[this.CurrentIndex][]+"px"+" "+this.ColorEnum[this.CurrentIndex][1]+"px";
134 }
135 }
136 }
137 },
138 CanMove:function(x,y){//根据传过来的x,y,检测方块是否能左右下移动
139 if(y+this.BlockHeight>=this.VerticalNum)//判断是否有到最底部,如果到底部的话停止向下移动
140 return false;
141 for(var i=this.BlockHeight;i>=;i–){//检测方块的最高坐标相对应的地图的坐标是否有都等于1,如果有等于1说明地图放不下该方块
142 for(var j=;j<=this.BlockWidth;j++){
143 if(this.GameMap[i][x+j]==1&&this.BlokCurrent[i][j]==1){
144 this.IsOverIndex=i;
145 this.IsOver=true;
146 }
147 }
148 }
149 for(var i=this.BlockHeight;i>=;i–){//检测方块的移动轨迹在地图中是否有被标记为1,如果有被标记为1就是下一步的轨迹不能运行。
150 for(var j=;j<=this.BlockWidth;j++){
151 if(this.GameMap[y+i][x+j]==1&&this.BlokCurrent[i][j]==1){//判断方块的下一步轨迹是否是1并且判断下一步方块的轨迹在地图中是否有为1。
152 return false;
153 }
154 }
155 }
156 return true;
157 },
158 ClearOldBlok:function(){//当this.InitPosition.y>=0 也就是显示在地图的时候,每次左右下移动时清除方块,使得重新绘制方块
159 if(this.InitPosition.y>=){
160 for(var i=;i<=this.BlockHeight;i++){
161 for(var j=;j<=this.BlockWidth;j++){
162 if(this.BlokCurrent[i][j]==1){
163 this.getTable().rows[this.InitPosition.y+i].cells[this.InitPosition.x+j].style.backgroundImage="";
164 }
165 }
166 }
167 }
168 },
169 MoveLeft:function(){ //向左移动
170 var x = this.InitPosition.x-1;
171 if(x<||this.InitPosition.y==-1)
172 return;
173 if(this.CanMove(x,this.InitPosition.y)){
174 this.ClearOldBlok();
175 this.InitPosition.x=x;
176 }
177 this.SettingBlock();
178 },
179 MoveRight:function(){//向右移动
180 var x = this.InitPosition.x+1;
181 if(x+this.BlockWidth>=this.HorizontalNum||this.InitPosition.y==-1)
182 return;
183 if(this.CanMove(x,this.InitPosition.y)){
184 this.ClearOldBlok();
185 this.InitPosition.x=x;
186 }
187 this.SettingBlock();
188 },
189 MoveDown:function(){//向下移动
190 var y = this.InitPosition.y+1;
191 if(this.CanMove(this.InitPosition.x,y)){//判断是否能向下移动,不能的话表示该方块停止运行,继续判断是否游戏结束,如果游戏还没结束重新创建个方块继续游戏
192 this.ClearOldBlok();
193 this.InitPosition.y=y;
194 this.SettingBlock();
195 }
196 else{
197 if(this.IsOver){
198 window.clearTimeout(OverTime);
199 this.GameOver();
200 return;
201 }
202 this.SettingBlock();
203 this.SettingGameMap();
204 this.CheckFull();
205 this.NewBlock();
206 this.CreateNextBlock();
207 return;
208 }
209 },
210 ChangeBlock:function(){//向上方块变型
211 if(this.InitPosition.y==-1)
212 return;
213 var newBlock = [[,,,],[,,,],[,,,],[,,,]];
214 for(var i=;i<=this.BlockHeight;i++){
215 for(var j=;j<=this.BlockWidth;j++){
216 newBlock[this.BlockWidth-j][i] = this.BlokCurrent[i][j];
217 }
218 }
219 var temp = this.BlokCurrent;
220 this.ClearOldBlok();
221 this.BlokCurrent=newBlock;
222 this.BlockWidth=this.GetWidth(this.BlokCurrent);
223 this.BlockHeight=this.GetHeight(this.BlokCurrent);
224 if(this.InitPosition.x+this.BlockWidth>=this.HorizontalNum||!this.CanMove(this.InitPosition.x,this.InitPosition.y)){//this.InitPosition.x+this.BlockWidth>=this.HorizontalNum判断变型后x+它的宽度是否有超过地图的宽度
225 this.BlokCurrent=temp;
226 this.BlockHeight=this.GetHeight(this.BlokCurrent)
227 this.BlockWidth=this.GetWidth(this.BlokCurrent);
228 }
229 this.SettingBlock();
230 },
231 CheckFull:function(){//检测是否有满行的
232 var arr=[];
233 for(var i=;i<this.VerticalNum;i++){
234 var flag=true;
235 for(var j=;j<this.HorizontalNum;j++){
236 if(this.GameMap[i][j]==){
237 flag=false;
238 break;
239 }
240 }
241 if(flag){
242 this.ClearFull(i);
243 }
244 }
245
246 },
247 ClearFull:function(index){//清除满行的,使上一行的背景图等于该行,并使上一行的坐标值等于该行,如果是第一行的话坐标值清0,背景清空
248 var tb = this.getTable();
249 if(index==){
250 for(var i=;i<this.HorizontalNum;i++){
251 this.GameMap[][j]=;
252 tb.rows[i].cells[j].style.backgroundImage="";
253 }
254 }
255 else{
256 for(var i=index;i>;i–){
257 for(var j=;j<this.HorizontalNum;j++){
258 this.GameMap[i][j]=this.GameMap[i-1][j];
259 tb.rows[i].cells[j].style.backgroundImage=tb.rows[i-1].cells[j].style.backgroundImage;
260 tb.rows[i].cells[j].style.backgroundPosition=tb.rows[i-1].cells[j].style.backgroundPosition;
261 }
262 }
263 }
264 this.getScore().innerHTML=parseInt(this.getScore().innerHTML)+this.ScoreIndex;
265 },
266 NewBlock:function(){//创建方块,初始化数据
267 this.CurrentIndex=this.NextCurrentIndex;//获取下一个方块的索引作为当前索引
268 this.BlokCurrent=this.BlogsSetting[this.CurrentIndex];//根据获得的新索引重新获取方块
269 this.BlockWidth=this.GetWidth(this.BlokCurrent);//重新获取方块的最大宽值
270 this.BlockHeight=this.GetHeight(this.BlokCurrent);//重新获取方块的最大高值
271 this.GetInitPosition();//初始化方块出现的坐标
272 },
273 GameOver:function(){//游戏结束后补齐获得当前方块,补齐地图空白地方
274 var tb = this.getTable();
275 for(var i=this.IsOverIndex-1;i>=;i–){//循环空白的IsOverIndex-1行,给空白的行补上当前方块,从最高值递件。减1是因为IsOverIndex获取的是被占据的行,所以减1为空白行。
276 for(var j=;j<=this.BlockWidth;j++){
277 if(this.BlokCurrent[this.BlockHeight-i][j]==1){
278 tb.rows[i].cells[this.InitPosition.x+j].style.backgroundImage="url(images/tetris.gif)";
279 tb.rows[i].cells[this.InitPosition.x+j].style.backgroundPosition=this.ColorEnum[this.CurrentIndex][]+"px"+" "+this.ColorEnum[this.CurrentIndex][1]+"px";
280 }
281 }
282 }
283 this.IsPlay=false;
284 alert("游戏结束");
285 },
286 SettingGameMap:function(){//设置游戏地图被占有的位置标记为1
287 for(var i=;i<=this.BlockHeight;i++)
288 for(var j=;j<=this.BlockWidth;j++)
289 if(this.BlokCurrent[i][j]==1){
290 this.GameMap[this.InitPosition.y+i][this.InitPosition.x+j]=1;//减1是因为每次y加1,然后在去进行判断,所以当碰到方块或底部的时候要减去多加的1
291 }
292 },
293 Start:function(){//游戏开始
294 this.IsPlay=true;
295 this.CurrentIndex=this.NextCurrentIndex;
296 this.BlokCurrent=this.BlogsSetting[this.CurrentIndex];
297 this.BlockWidth=this.GetWidth(this.BlokCurrent);
298 this.BlockHeight=this.GetHeight(this.BlokCurrent);
299 this.GetInitPosition();
300 this.MoveDown();
301 this.CreateNextBlock();
302 },
303 CreateNextBlock:function(){//获取下一个方块的索引,并显示在预览区域中
304 this.NextCurrentIndex=this.getRandom();
305 this.LoadPreview(this.NextCurrentIndex);
306 },
307 GetHeight:function(blokArr){//获取当前方块不是0的最大高值
308 for(var i=blokArr.length-1;i>=;i–)
309 for(var j=;j<blokArr[i].length;j++)
310 if(blokArr[i][j]==1)
311 return i;
312 },
313 GetWidth:function(blokArr){//获取当前方块不是0的最大宽值
314 for(var i=blokArr.length-1;i>=;i–)
315 for(var j=;j<blokArr[i].length;j++)
316 if(blokArr[j][i]==1)
317 return i;
318 },
319 GetInitPosition:function(){//获取方块的初始位置
320 this.InitPosition = {x:Math.floor((this.HorizontalNum-this.BlokSize)/2),y:-1};
321 },
322 getRandom:function(){//随机获得7种放块中的其中一种
323 return Math.floor(Math.random()*7);
324 },
325 getTable:function(){
326 return document.getElementById("area");
327 },
328 getScore:function(){
329 return document.getElementById("score");
330 }
331 }
332 var t = new Tetris();
333 var OverTime=null;
334 var IsPause=false;
335 var Speed=500;
336 var btn_start;
337 window.onload=InitGame;
338 function InitGame(){
339 t.CreateMap();
340 btn_start = document.getElementById("start");
341 btn_start.onclick=function(){
342 t.Start();
343 this.value="P 暂停游戏"
344 OverTime=setInterval(MoveBoxDown,Speed);
345 this.disabled="disabled";
346 }
347 }
348 function MoveBoxDown(){
349 t.MoveDown();
350 }
351 function KeyDown(e){
352 if(!t.IsPlay||t.IsOver)return;
353 e=e||window.event;
354 var keyCode = e.keyCode||e.which||e.charCode;
355 switch(keyCode){
356 case 37://左
357 if(!IsPause)t.MoveLeft();
358 break;
359 case 38://上
360 if(!IsPause)t.ChangeBlock();
361 break;
362 case 39://右
363 if(!IsPause)t.MoveRight();
364 break;
365 case 40://下
366 if(!IsPause)t.MoveDown();
367 break;
368 case 80://p 暂停or开始
369 IsPause=!IsPause;
370 if(IsPause){
371 btn_start.value="P 开始游戏";
372 window.clearInterval(OverTime);
373 }
374 else{
375 btn_start.value="P 暂停游戏";
376 OverTime=setInterval(MoveBoxDown,Speed);
377 }
378 break;
379 }
380 }
002 Tetris.prototype={
003 BlogsSetting:[//方块设置
004 [
005 [1,1,1,1],
006 [,,,],
007 [,,,],
008 [,,,]
009 ],
010 [
011 [1,1,1,],
012 [1,,,],
013 [,,,],
014 [,,,]
015 ],
016 [
017 [1,1,1,],
018 [,1,,],
019 [,,,],
020 [,,,]
021 ],
022 [
023 [1,1,1,],
024 [,,1,],
025 [,,,],
026 [,,,]
027 ],
028 [
029 [1,1,,],
030 [,1,1,],
031 [,,,],
032 [,,,]
033 ],
034 [
035 [,1,1,],
036 [1,1,,],
037 [,,,],
038 [,,,]
039 ],
040 [
041 [1,1,,],
042 [1,1,,],
043 [,,,],
044 [,,,]
045 ]
046 ],
047 GameMap:[],//游戏地图,对应table中的td值
048 BlokWidth:28,//方块集的宽高,也就是images/tetris_grid.gif图片的宽高
049 HorizontalNum:10,//水平td数量
050 VerticalNum:18,//垂直td数量
051 BlokSize:4,//设置方块占用位置4 * 4
052 BlockWidth:,//获取当前方块的非0的最大宽度
053 BlockHeight:,//获取当前方块的非0的最大高度
054 CurrentIndex:,//当前随机获得的索引
055 NextCurrentIndex:,//获取下一个方块的索引
056 BlokCurrent:[],//当前方块
057 InitPosition:{},//当前方块运动的x,y
058 IsPlay:false,//是否开始游戏
059 IsOver:false,//游戏是否结束
060 IsOverIndex:,//设置游戏结束的索引还有空几行
061 Score:,
062 ScoreIndex:100,
063 ColorEnum: [[, ], [-28, ], [-56, ], [-84, ], [-112, ], [-140, ], [-168, ], [, ]], //颜色的枚举,对应BlogsSetting
064 CreateMap:function(){
065 //加载地图,设置其宽高,根据HorizontalNum,VerticalNum的数量决定
066 var map = document.getElementById("map");
067 var w = this.BlokWidth*this.HorizontalNum;
068 var h = this.BlokWidth*this.VerticalNum;
069 map.style.width=w+"px";
070 map.style.height=h+"px";
071 //加载地图对应的数组,初始化为0,当被占据时为1
072 for(var i=;i<this.VerticalNum;i++){
073 this.GameMap.push([]);
074 for(var j=;j<this.HorizontalNum;j++){
075 this.GameMap[i][j]=;
076 }
077 }
078 //创建table td填充div根据HorizontalNum,VerticalNum的数量决定,创建HorizontalNum * VerticalNum的表格区域
079 var table = document.createElement("table");
080 table.id="area";
081 var tbody = document.createElement("tbody");
082 table.cellPadding=;
083 table.cellSpacing=;
084 table.appendChild(tbody);
085 for(var i=;i<this.VerticalNum;i++){
086 var tr = document.createElement("tr");
087 for(var j=;j<this.HorizontalNum;j++){
088 var td = document.createElement("td");
089 tr.appendChild(td);
090 }
091 tbody.appendChild(tr);
092 }
093 map.appendChild(table);
094 this.CreatePreViewMap();
095 this.CreateNextBlock();
096 },
097 CreatePreViewMap:function(){//加载一个4*4的表格到预览区域
098 var preview = document.getElementById("previewArea");
099 var table = document.createElement("table");
100 table.id="perviewTable";
101 var tbody = document.createElement("tbody");
102 table.cellPadding=;
103 table.cellSpacing=;
104 table.appendChild(tbody);
105 for(var i=;i<this.BlokSize;i++){
106 var tr = document.createElement("tr");
107 for(var j=;j<this.BlokSize;j++){
108 var td = document.createElement("td");
109 tr.appendChild(td);
110 }
111 tbody.appendChild(tr);
112 }
113 preview.appendChild(table);
114 },
115 LoadPreview:function(index){//加载到预览区域
116 var previewTable = document.getElementById("perviewTable");
117 for(var i=;i<this.BlogsSetting[index].length;i++){
118 for(var j=;j<this.BlogsSetting[index][i].length;j++){
119 previewTable.rows[i].cells[j].style.backgroundImage="";
120 if(this.BlogsSetting[index][i][j]==1){
121 previewTable.rows[i].cells[j].style.backgroundImage="url(images/tetris.gif)";
122 previewTable.rows[i].cells[j].style.backgroundPosition=this.ColorEnum[index][]+"px"+" "+this.ColorEnum[index][1]+"px";
123 }
124 }
125 }
126 },
127 SettingBlock:function(){//设置地图中方块的背景图片
128 var tb = this.getTable();
129 for(var i=;i<=this.BlockHeight;i++){
130 for(var j=;j<=this.BlockWidth;j++){
131 if(this.BlokCurrent[i][j]==1){
132 tb.rows[this.InitPosition.y+i].cells[this.InitPosition.x+j].style.backgroundImage="url(images/tetris.gif)";
133 tb.rows[this.InitPosition.y+i].cells[this.InitPosition.x+j].style.backgroundPosition=this.ColorEnum[this.CurrentIndex][]+"px"+" "+this.ColorEnum[this.CurrentIndex][1]+"px";
134 }
135 }
136 }
137 },
138 CanMove:function(x,y){//根据传过来的x,y,检测方块是否能左右下移动
139 if(y+this.BlockHeight>=this.VerticalNum)//判断是否有到最底部,如果到底部的话停止向下移动
140 return false;
141 for(var i=this.BlockHeight;i>=;i–){//检测方块的最高坐标相对应的地图的坐标是否有都等于1,如果有等于1说明地图放不下该方块
142 for(var j=;j<=this.BlockWidth;j++){
143 if(this.GameMap[i][x+j]==1&&this.BlokCurrent[i][j]==1){
144 this.IsOverIndex=i;
145 this.IsOver=true;
146 }
147 }
148 }
149 for(var i=this.BlockHeight;i>=;i–){//检测方块的移动轨迹在地图中是否有被标记为1,如果有被标记为1就是下一步的轨迹不能运行。
150 for(var j=;j<=this.BlockWidth;j++){
151 if(this.GameMap[y+i][x+j]==1&&this.BlokCurrent[i][j]==1){//判断方块的下一步轨迹是否是1并且判断下一步方块的轨迹在地图中是否有为1。
152 return false;
153 }
154 }
155 }
156 return true;
157 },
158 ClearOldBlok:function(){//当this.InitPosition.y>=0 也就是显示在地图的时候,每次左右下移动时清除方块,使得重新绘制方块
159 if(this.InitPosition.y>=){
160 for(var i=;i<=this.BlockHeight;i++){
161 for(var j=;j<=this.BlockWidth;j++){
162 if(this.BlokCurrent[i][j]==1){
163 this.getTable().rows[this.InitPosition.y+i].cells[this.InitPosition.x+j].style.backgroundImage="";
164 }
165 }
166 }
167 }
168 },
169 MoveLeft:function(){ //向左移动
170 var x = this.InitPosition.x-1;
171 if(x<||this.InitPosition.y==-1)
172 return;
173 if(this.CanMove(x,this.InitPosition.y)){
174 this.ClearOldBlok();
175 this.InitPosition.x=x;
176 }
177 this.SettingBlock();
178 },
179 MoveRight:function(){//向右移动
180 var x = this.InitPosition.x+1;
181 if(x+this.BlockWidth>=this.HorizontalNum||this.InitPosition.y==-1)
182 return;
183 if(this.CanMove(x,this.InitPosition.y)){
184 this.ClearOldBlok();
185 this.InitPosition.x=x;
186 }
187 this.SettingBlock();
188 },
189 MoveDown:function(){//向下移动
190 var y = this.InitPosition.y+1;
191 if(this.CanMove(this.InitPosition.x,y)){//判断是否能向下移动,不能的话表示该方块停止运行,继续判断是否游戏结束,如果游戏还没结束重新创建个方块继续游戏
192 this.ClearOldBlok();
193 this.InitPosition.y=y;
194 this.SettingBlock();
195 }
196 else{
197 if(this.IsOver){
198 window.clearTimeout(OverTime);
199 this.GameOver();
200 return;
201 }
202 this.SettingBlock();
203 this.SettingGameMap();
204 this.CheckFull();
205 this.NewBlock();
206 this.CreateNextBlock();
207 return;
208 }
209 },
210 ChangeBlock:function(){//向上方块变型
211 if(this.InitPosition.y==-1)
212 return;
213 var newBlock = [[,,,],[,,,],[,,,],[,,,]];
214 for(var i=;i<=this.BlockHeight;i++){
215 for(var j=;j<=this.BlockWidth;j++){
216 newBlock[this.BlockWidth-j][i] = this.BlokCurrent[i][j];
217 }
218 }
219 var temp = this.BlokCurrent;
220 this.ClearOldBlok();
221 this.BlokCurrent=newBlock;
222 this.BlockWidth=this.GetWidth(this.BlokCurrent);
223 this.BlockHeight=this.GetHeight(this.BlokCurrent);
224 if(this.InitPosition.x+this.BlockWidth>=this.HorizontalNum||!this.CanMove(this.InitPosition.x,this.InitPosition.y)){//this.InitPosition.x+this.BlockWidth>=this.HorizontalNum判断变型后x+它的宽度是否有超过地图的宽度
225 this.BlokCurrent=temp;
226 this.BlockHeight=this.GetHeight(this.BlokCurrent)
227 this.BlockWidth=this.GetWidth(this.BlokCurrent);
228 }
229 this.SettingBlock();
230 },
231 CheckFull:function(){//检测是否有满行的
232 var arr=[];
233 for(var i=;i<this.VerticalNum;i++){
234 var flag=true;
235 for(var j=;j<this.HorizontalNum;j++){
236 if(this.GameMap[i][j]==){
237 flag=false;
238 break;
239 }
240 }
241 if(flag){
242 this.ClearFull(i);
243 }
244 }
245
246 },
247 ClearFull:function(index){//清除满行的,使上一行的背景图等于该行,并使上一行的坐标值等于该行,如果是第一行的话坐标值清0,背景清空
248 var tb = this.getTable();
249 if(index==){
250 for(var i=;i<this.HorizontalNum;i++){
251 this.GameMap[][j]=;
252 tb.rows[i].cells[j].style.backgroundImage="";
253 }
254 }
255 else{
256 for(var i=index;i>;i–){
257 for(var j=;j<this.HorizontalNum;j++){
258 this.GameMap[i][j]=this.GameMap[i-1][j];
259 tb.rows[i].cells[j].style.backgroundImage=tb.rows[i-1].cells[j].style.backgroundImage;
260 tb.rows[i].cells[j].style.backgroundPosition=tb.rows[i-1].cells[j].style.backgroundPosition;
261 }
262 }
263 }
264 this.getScore().innerHTML=parseInt(this.getScore().innerHTML)+this.ScoreIndex;
265 },
266 NewBlock:function(){//创建方块,初始化数据
267 this.CurrentIndex=this.NextCurrentIndex;//获取下一个方块的索引作为当前索引
268 this.BlokCurrent=this.BlogsSetting[this.CurrentIndex];//根据获得的新索引重新获取方块
269 this.BlockWidth=this.GetWidth(this.BlokCurrent);//重新获取方块的最大宽值
270 this.BlockHeight=this.GetHeight(this.BlokCurrent);//重新获取方块的最大高值
271 this.GetInitPosition();//初始化方块出现的坐标
272 },
273 GameOver:function(){//游戏结束后补齐获得当前方块,补齐地图空白地方
274 var tb = this.getTable();
275 for(var i=this.IsOverIndex-1;i>=;i–){//循环空白的IsOverIndex-1行,给空白的行补上当前方块,从最高值递件。减1是因为IsOverIndex获取的是被占据的行,所以减1为空白行。
276 for(var j=;j<=this.BlockWidth;j++){
277 if(this.BlokCurrent[this.BlockHeight-i][j]==1){
278 tb.rows[i].cells[this.InitPosition.x+j].style.backgroundImage="url(images/tetris.gif)";
279 tb.rows[i].cells[this.InitPosition.x+j].style.backgroundPosition=this.ColorEnum[this.CurrentIndex][]+"px"+" "+this.ColorEnum[this.CurrentIndex][1]+"px";
280 }
281 }
282 }
283 this.IsPlay=false;
284 alert("游戏结束");
285 },
286 SettingGameMap:function(){//设置游戏地图被占有的位置标记为1
287 for(var i=;i<=this.BlockHeight;i++)
288 for(var j=;j<=this.BlockWidth;j++)
289 if(this.BlokCurrent[i][j]==1){
290 this.GameMap[this.InitPosition.y+i][this.InitPosition.x+j]=1;//减1是因为每次y加1,然后在去进行判断,所以当碰到方块或底部的时候要减去多加的1
291 }
292 },
293 Start:function(){//游戏开始
294 this.IsPlay=true;
295 this.CurrentIndex=this.NextCurrentIndex;
296 this.BlokCurrent=this.BlogsSetting[this.CurrentIndex];
297 this.BlockWidth=this.GetWidth(this.BlokCurrent);
298 this.BlockHeight=this.GetHeight(this.BlokCurrent);
299 this.GetInitPosition();
300 this.MoveDown();
301 this.CreateNextBlock();
302 },
303 CreateNextBlock:function(){//获取下一个方块的索引,并显示在预览区域中
304 this.NextCurrentIndex=this.getRandom();
305 this.LoadPreview(this.NextCurrentIndex);
306 },
307 GetHeight:function(blokArr){//获取当前方块不是0的最大高值
308 for(var i=blokArr.length-1;i>=;i–)
309 for(var j=;j<blokArr[i].length;j++)
310 if(blokArr[i][j]==1)
311 return i;
312 },
313 GetWidth:function(blokArr){//获取当前方块不是0的最大宽值
314 for(var i=blokArr.length-1;i>=;i–)
315 for(var j=;j<blokArr[i].length;j++)
316 if(blokArr[j][i]==1)
317 return i;
318 },
319 GetInitPosition:function(){//获取方块的初始位置
320 this.InitPosition = {x:Math.floor((this.HorizontalNum-this.BlokSize)/2),y:-1};
321 },
322 getRandom:function(){//随机获得7种放块中的其中一种
323 return Math.floor(Math.random()*7);
324 },
325 getTable:function(){
326 return document.getElementById("area");
327 },
328 getScore:function(){
329 return document.getElementById("score");
330 }
331 }
332 var t = new Tetris();
333 var OverTime=null;
334 var IsPause=false;
335 var Speed=500;
336 var btn_start;
337 window.onload=InitGame;
338 function InitGame(){
339 t.CreateMap();
340 btn_start = document.getElementById("start");
341 btn_start.onclick=function(){
342 t.Start();
343 this.value="P 暂停游戏"
344 OverTime=setInterval(MoveBoxDown,Speed);
345 this.disabled="disabled";
346 }
347 }
348 function MoveBoxDown(){
349 t.MoveDown();
350 }
351 function KeyDown(e){
352 if(!t.IsPlay||t.IsOver)return;
353 e=e||window.event;
354 var keyCode = e.keyCode||e.which||e.charCode;
355 switch(keyCode){
356 case 37://左
357 if(!IsPause)t.MoveLeft();
358 break;
359 case 38://上
360 if(!IsPause)t.ChangeBlock();
361 break;
362 case 39://右
363 if(!IsPause)t.MoveRight();
364 break;
365 case 40://下
366 if(!IsPause)t.MoveDown();
367 break;
368 case 80://p 暂停or开始
369 IsPause=!IsPause;
370 if(IsPause){
371 btn_start.value="P 开始游戏";
372 window.clearInterval(OverTime);
373 }
374 else{
375 btn_start.value="P 暂停游戏";
376 OverTime=setInterval(MoveBoxDown,Speed);
377 }
378 break;
379 }
380 }