We all know Tetris is a popular game, I played at a very young age, this year is 25 years old, it can be said that Tetris is indeed a long history, do Tetris is my idea of the beginning of last week. Perhaps because I have never written this kind of things, so there is unfamiliar. Code, only a small part of the completion, about 1/5 or so. Today, I decided to write some ideas first.
As for Tetris, there are a lot of difficulties, if there is JS to write, to consider the collision Ah, border ah, whereabouts and other issues, this article most of these issues will not be considered, just provide a part of the idea, began to say, because they have not finished this game, but also out of want to write blog records, That's why we have this series of blogs.
Back to the point, let's first think about what Tetris needs. I make a simple generalization. If I simply say that it is a Tetris object, then what is there in this object? We can imagine that there is a planar Cartesian coordinate system with the x-axis, the y-axis, and the "every equal" distance (unit), while the Tetris is a "lattice" where the squares begin to fall from one place to the next, where they stop falling, So we set the "Drop zone" (area) of Tetris. But the drop is an "action", so we have to have a class (defined here as operate) to control the whereabouts of the action.
Well, first introduced here, we will do a code of the nature of the induction, the above code to do a summary.
/* Tetris entity Class */function Tetris () {var self =this;//this.area=null;//zone this.operate=null;//operation/* initialize x, y, Unit 5 or 20*/ This.x=5;this.y=5;this.unit=20;this.running=null; Whether in run//Tetris entity idthis.id= "tempid";//Start Game this.start=function () {this.area=new Getarea (This.x,this.y,this.unit, " Tempid "); Get the area object, where Tempid is the Russian block entity class Idthis.operate=new Operatetetris (this.area,self);//whether to replace Tetris if ( This.operate.mayPlace ()) {//alert (1); This.operate.place ();}} Start Game document.getElementById ("Startgame"). Onclick=function () {Self.start ()};}
So, when we click on Startgame, start the game, that is, run the start () method. Well, we're starting to think about what's in the Area object. function Getarea (x,y,unit,id) parameters need to be brought in 4, the first 3 have just said, the fourth parameter is the ID of area. We need the area object, so we can set the ID by HTML code. We have played Tetris know that every time the bottom, will add a new element, and the new element is "random", whenever a line is full (here does not consider the color of the case), it will eliminate a line, of course, we once formed a number of rows can be eliminated when the block, then we can eliminate more lines. The following is the code, which is a small summary of the above text, has not finished the code.
//obtains the regional horizontal and vertical function Getarea (x,y,unit,id) {this.x=x;this.y=y; This.unit=unit; The size of each cell, measured in pixels this.el=document.getelementbyid (ID); Get ID object this.board=[]; The panel, that is, the element in the Zone range (Tetris)//Add element This.addelement=function () {//Get start element x start coordinate and y start coordinate position (Error)//get x-coordinate the number of drops, and y-axis of the number of moves left and right Var Xbegin=parseint (el.offsetleft/unit); var ybegin=parseint (El.offsettop/unit); if (xbegin>=0&&xbegin<= THIS.X&&YBEGIN>=0&&YBEGIN<=THIS.Y) {Board[ybegin][xbegin]=el;//determines the position of the element}}// Erase all Rows this.removefulllines=function () {var lines=0;for (var i=this.y-1;y>0;y--) {if (this.linesrelated (y)) {lines+ +;this.y++;}}} This.linesrelated=function (y) {for (Var x=this.x;x>0;x--) {this.removelines (y), if (this.board[ Y][x]) {return false;}//Unknown sensation}return true;};/ /Remove line this.removelines=function (y) {for (Var x=0;x<this.x;x++) {this.el.removeChild (this.board[y][x]); this.board[ y][x]=0;} Y--;for (; y>0;y--) {/* Today is temporarily written here */}};}
One thing to note is that Tetris is a "two-dimensional nature", so here I define a two-dimensional array of board types, i.e. board[rows [columns] (Board[y][x]). Well, here we certainly need a class, which is the class of "actions" that control the whereabouts of the element, So what is there to be in this falling "action" class? We need to consider the boundary, and then we have the (region), we have to consider Tetris and then have a Tetris object (Tetris), because of the different types of blocks, there are various shapes so we have to consider the category of blocks (types), and the next category (Nexttype), Because the block has the next hint, we need to consider the position of the block in the area so there is (position), we need to determine whether the game is paused and then have running, of course, the speed of the falling of the block must also be considered, if the game Over then you have to judge whether the game stop stopped, of course, the block is an element of the so we have to consider elements, of course, the most important is the whereabouts (Falldown). The following is the defined code:
var self=this; Current object this.area=area;this.tetris=tetris;this.types=null; The type of block; this.nexttype=null; Next type//Initialize x and ythis.x=null;this.y=null;this.position=0; Initial position this.board=[]; The this.elements=[];this.running=null used to populate HTML elements; Whether the this.stopped=null is in operation; whether to stop This.falldownid=null; A this.speed=null falling down; Speed
This is a little dizzy, we choose a point of entry, our starting point is how to construct the block. You should know several shapes of Tetris, such as T-shaped, L-shaped, mouth, and so on, then we can imagine that the Russian block is defined as a two-dimensional array, then there are elements of the place is 1, no element of the place for the zero structure shape, such as the following code:
/* block combination, with arrays (two-dimensional arrays) with 0,1 to indicate whether there is a block, if it is 0: not exist, 1: exist, the following logic can be very clear. */this.blockcomplex=[[[0,0,1],[1,1,1],[0,0,0] //_|],[[1,0,0],[1,1,1],[0,0,0]//l],[[0,1,0],[1,1,1],[0,0,0] //t],[[0,0,0],[1,1,1],[0,0,0]//--],[[0,0,0],[0,1,1],[0,1,1]//Mouth],[[0,1,1],[0,1,0],[1,1,0]//Z];
Well, after the shape is constructed, of course we need to consider the performance aspects of the program, so I created the following getter method to determine if the game is running medium.
/* A series of getter methods are speed, x, y axes, run and stop Getter Methods */this.getspeed=function () {return this.speed;} This.getx=function () {return this.x;} This.gety=function () {return this.y;} This.isrunning=function () {return this.running;} This.isstopped=function () {return this.stopped;}
Of course, if we want to "start the game again", we must create a method reset (), white, is to restore the game to start the state.
Reset (Initialize) this.reset=function () {this.nexttype=random (this.blockComplex.length); this.types=this.nexttype; This.position=0;this.board=[];this.elements=[];this.x=null;this.y=null;}
If this Russian method touches the bottom, then it's definitely going to trigger the start of the next Tetris. So we must have a method here, the content I do not think well, give a shelf it. I return true directly.
This.mayplace=function () {return true;}
The following is the most important method, which is our method of replacing the block. First to do a simple introduction, I do not know if I can speak well, we think in a coordinate system, if the box is falling, it must be y--, after all, the box is falling to the bottom, of course, we also need to have lines, assuming we have been stacking blocks, this line is bound to increase, And our block itself is a div, must be a drop div process, and these div, must be within the area range. Let's think about it, first of all, let's create an empty board, which is the panel, and then fill the panel with stuff.
Creates an empty object, which is all 0 objects, and returns the object This.createempty=function (x, y) {var elements=[];for (var y2=0;y2<y;y2++) {Elements.push ( New Array ()); for (Var x2=0;x2<x;x2++) {elements[y2].push (0);}} return elements;}
If we want to drop the element, we must know the coordinates of the beginning of the fall, of course, the Y axis is definitely the 0,x axis can be set according to their preferences. Of course, the falling div must belong to the sub-element below the area, so we'll have to get this appendchild in here. Here's the code:
/* Replace */this.place=function () {//Initialize var operate=this.blockcomplex[this.types];//area start x-axis position var areaxstartpos=parseint (this.area.x-operate[0].length)///region start y-axis position//var areaystartpos=parseint (this.area.y-operate[0]); var Areaystartpos=1; Because the position of the x-axis may change, and the y-axis always comes down from the top, so it is 1this.x=areaxstartpos; Assign the new position to the X;this.y=areaystartpos; Assign a new location to the y;//build an empty object and deposit Board/*y: line, x: Column *///alert (operate[0].length+ "" +operate.length); this.board=this.createempty (operate[0].length,operate.length);/* line, drop down, initialize */var Lines=0;var foundlines=false;//loop traversal, first traverse the row, each row again to traverse the column for (var yaxis=this.board.length-1;yaxis>=0;yaxis--) {for (Var xaxis=0;xaxis<=this.blockcomplex[yaxis].length;xaxis+ +) {if (This.blockcomplex[yaxis][xaxis]) {var el=document.createelement ("div"); el.classname= "Block" +this.types;// Determine the classname//of this element to determine the left margin and top margin el.style.left= (this.x+xaxis) *this.area.unit+ "px"; el.style.top= (This.y+yaxis) * this.area.unit+ "px"; This.area.el.appendChild (EL); This El went to append the main el. This.board[yaxis][xaxis]=el;this.elements.push (EL); Push into the elements}}/* Personal feeling this function should be the way to speed down the drop? Unknown sensation */if (lines) {yaxis--;} if (foundlines) {lines++;}}
It is important to note that when the next Tetris (random) is formed randomly, we need to define a random method. In fact, each drop is a reset cycle, but the game is not over yet.
Random number, generating 1~6 function random (i) {return Math.floor (Math.random () *i);}
Well, today only introduce a train of thought, of course, I did not write out this game, and so on the next article should be the game will have a big shelf, there are some code I am embarrassed to put out, write too bad. In fact, this Tetris is not entirely my own writing, I also refer to other people's things, but not plagiarism, I want to through their own efforts to do a game out, this is my dream for many years, efforts!
As for all the code I will not post, because has not finished, just for these days to write a summary of the code, the master can ignore the code I write.
Make Tetris with pure JS-Brief Introduction (1)