吉吉于

俄罗斯方块

在线试玩

源码:

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        }

转载请注明:于哲的博客 » 俄罗斯方块