JavaScript implementation of Tetris game process analysis and source sharing _javascript skills

Source: Internet
Author: User
Tags setinterval

Look at the beauty of programming: The program, though difficult to write, is wonderful. To write a program well, you need to write some basic knowledge, including programming language, data structure and algorithm. The program writes well, needs the careful logical thinking ability and the good carding Foundation, but also is familiar with the programming environment and the programming tool. ”

Learn a few years of computer, you have no love programming. In other words, no attempt to write a game of their own, is not a love of programming.

Tetris has created a sensation and economic value can be said to be a game in the history of a major event, it seems simple but endless, addictive. Believe that most of the students, once for it is obsessed with tea do not think rice do not want.

Rules of the game

1. A flat virtual space for placing small squares, its standard size: ruled 10, Liegau 20, with each small square as the unit.

2, a group of 4 small squares composed of regular graphics, English known as Tetromino, Zeng Wentong called the square a total of 7, respectively, S, Z, L, J, I, O, t this 7-letter shape named.

I: Remove up to four floors at a time

J (left): Up to three floors removed or two layers eliminated

L: Eliminate up to three layers, or eliminate two layers

O: Eliminate one to two layers

S (left): up to two layers, easily resulting in holes

Z (left): up to two layers, easy to create holes

T: up to two floors

The box starts slowly from above the area and continues to fall. The player can rotate the square in 90 degrees, and move the square to the square to make the box accelerate to fall. When the square moves to the bottom of the area or to the ground to the other squares, it is fixed there, and the new box appears above the area and begins to fall. When a column in a range is filled by squares, the column disappears and becomes the player's score. The more columns that were deleted at the same time, the score index rose.

Analysis and Solution

Each block falls in the process that we can do:

1) Rotate to the right direction

2) horizontal move to a column

3) Vertical drop to bottom

First, you need to use a two-dimensional array, area[18][10] to represent the game area of the 18*10. Where the value in the array is 0 for null, and 1 for blocks.

There are 7 kinds of squares, each of which has 4 different directions. Definition activeblock[4], the value of this array is predetermined before compiling and is used directly in the program.

Difficulties

1) Border inspection.

 Check the left edge and try to move one to the left to see if it's legal.
function Checkleftborder () {for 
  (var i=0; i<activeblock.length; i++) { 
    if (activeblock[i].y==0) 
      { return false; 
    } 
    if (!iscellvalid (activeblock[i].x, activeblock[i].y-1)) {return 
      false; 
    } 
  } 
  return true; 
} Similarly, the right and bottom boundaries need to be detected

2 rotation, the need for mathematical logic, a point relative to another point of rotation 90 degrees of the problem.
3 Timing and Monitoring keyboard event mechanism allows the game to run automatically.

Start 
function begin (e) { 
  e.disabled = true; 
  status = 1; 
  TBL = document.getElementById ("area"); 
  if (!generateblock ()) { 
    alert ("Game over!"); 
    status = 2; 
    return; 
  } 
  Paint (); 
  Timer = setinterval (movedown,1000); 
} 
Document.onkeydown=keycontrol;

Program Process

1 The user point starts-> constructs an active graph, sets the timer.

The currently active square that can be moved left and right, and the variant. When it touches the bottom, the area will be updated; 
var Activeblock; 
The Production box shape has 7 basic shapes. 
function Generateblock () { 
  activeblock = null; 
  Activeblock = new Array (4); 
  0-6 arrays are randomly generated, representing 7 different forms.
  var t = (Math.floor (math.random () *20) +1)%7; 
  Switch (t) {case 
    0:{ 
      activeblock[0] = {x:0, y:4}; 
      Activeblock[1] = {x:1, y:4}; 
      Activeblock[2] = {x:0, y:5}; 
      Activeblock[3] = {x:1, y:5}; 

      break; 
    Omit part of the code ........
    ............ Case 6:{ 
      Activeblock[0] = {x:0, y:5}; 
      Activeblock[1] = {x:1, y:4}; 
      Activeblock[2] = {x:1, y:5}; 
      Activeblock[3] = {x:1, y:6}; 
      break; 
    } 
  } 
  Check whether the newly produced four squares can be placed in the initialization position. 
  For (Var i=0. i<4; i++) { 
    if (!iscellvalid (activeblock[i].x, activeblock[i].y)) {return 
        false; 
      } 
    } return 
  true; 
}

2 after each move down, check whether to touch the bottom, if the bottom, then try to eliminate the line.

Elimination 
Function Deleteline () { 
  var lines = 0; 
  for (var i=0; i<18; i++) { 
    var j=0; 
    for (; j<10; j + +) { 
      if (area[i][j]==0) {break 
        ; 
    } 
  } 
  if (j==10) { 
    lines++; 
    if (i!=0) {for 
      (var k=i-1; k>=0; k--) { 
        area[k+1] = area[k]; 
      } 
    Area[0] = Generateblankline (); 
    } 
  } 
  return lines; 
}

3 After the end of the construction of an active graphics, and then set the timer.


Effect chart

needs to be optimized

1 set the color of different shape squares.

Idea: In the creation square function, sets the activeblockcolor color, seven kinds of different form squares color dissimilarity (in addition to modifies Generateblock method, also needs to modify Paintarea method. Because the first consideration is not complete, the elimination of a row, redrawing the box at the same time will be unified color, so you can consider to remove the table n rows, and then add n rows at the top to ensure that the integrity of the box is not eliminated.

2 When the current box is falling, you can view the next square in advance.

Idea: Split the Generateblock method into two parts, one for random attempts at the next, and one for caching the squares that are currently being depicted. When the current box hits the bottom and is fixed, the next box begins to be depicted, and the new box is randomly generated again. So repeatedly.

Full HTML Source:

<! 
	doctype>  

Full Tetris.js Source:

/** * js Tetris Game v 1.0 *//represents the table in the page, this table is going to show the game's main panel var tbl; Game Status 0: not started; 1 running; 
2 stops; 
var status = 0; 
Timer, the timer will do movedown operation var timer; 

Score var score = 0; Area is an array of 18*10 and corresponds to the table of the page. 
The initial time is 0, if occupied then 1 var area = new Array (18); 
for (Var i=0;i<18;i++) {Area[i] = new Array (10); 
	for (Var i=0;i<18;i++) {for (Var j=0 j<10; J + +) {Area[i][j] = 0; }//Current active box, it can move left and right, variant. 
When it touches the bottom, the area will be updated; 
var Activeblock; 
The Production box shape has 7 basic shapes. 
	function Generateblock () {activeblock = null; 
	Activeblock = new Array (4);
	0-6 arrays are randomly generated, representing 7 different forms. 
	var t = (Math.floor (math.random () *20) +1)%7; 
			Switch (t) {case 0:{activeblock[0] = {x:0, y:4}; 
			Activeblock[1] = {x:1, y:4}; 
			Activeblock[2] = {x:0, y:5}; 

			Activeblock[3] = {x:1, y:5}; 
		Break 
			Case 1:{Activeblock[0] = {x:0, y:3}; 
			Activeblock[1] = {x:0, y:4}; 
			Activeblock[2] = {x:0, y:5}; 
			Activeblock[3] = {x:0, y:6}; 
		Break Case 2:{Activeblock[0] = {x:0, y:5};
			Activeblock[1] = {x:1, y:4}; 
			Activeblock[2] = {x:1, y:5}; 
			Activeblock[3] = {x:2, y:4}; 
		Break 
			Case 3:{Activeblock[0] = {x:0, y:4}; 
			Activeblock[1] = {x:1, y:4}; 
			Activeblock[2] = {x:1, y:5}; 
			Activeblock[3] = {x:2, y:5}; 
		Break 
			Case 4:{Activeblock[0] = {x:0, y:4}; 
			Activeblock[1] = {x:1, y:4}; 
			Activeblock[2] = {x:1, y:5}; 
			Activeblock[3] = {x:1, y:6}; 
		Break 
			Case 5:{Activeblock[0] = {x:0, y:4}; 
			Activeblock[1] = {x:1, y:4}; 
			Activeblock[2] = {x:2, y:4}; 
			Activeblock[3] = {x:2, y:5}; 
		Break 
			Case 6:{Activeblock[0] = {x:0, y:5}; 
			Activeblock[1] = {x:1, y:4}; 
			Activeblock[2] = {x:1, y:5}; 
			Activeblock[3] = {x:1, y:6}; 
		Break 
	Check whether the four small squares you just produced can be placed in the initialization position. 
			for (var i=0; i<4; i++) {if (!iscellvalid (activeblock[i].x, activeblock[i].y)) {return false; 
} return true; 
	///Move Down function MoveDown () {//Check bottom boundary. if (Checkbottomborder ()) {//No bottoming, Erases the current graph, erase (); 
		Updates the current graphics coordinates for (var i=0; i<4; i++) {activeblock[i].x = activeblock[i].x + 1; 
	//repaint current graphics paint (); 
		//Bottom, else{//Stop the current timer, that is, stop the automatic downward movement. 
		Clearinterval (timer); 
		Updates an area array. 
		Updatearea (); 
		Elimination of var lines = Deleteline (); 
			If there is a elimination line, then if (lines!=0) {//update score score = score + lines*10; 
			Updatescore (); 
			Erase the entire panel erasearea (); 
		Redraw panel Paintarea (); 
		//Generate a new graphic and determine if it can be placed in the original position. 
			if (!generateblock ()) {alert ("Game over!"); 
			status = 2; 
		Return 
		} paint ();  
		Timer, run every second movedown timer = setinterval (movedown,1000)}}//Left Move function moveLeft () {if (Checkleftborder ()) { 
		Erase (); 
		for (var i=0; i<4; i++) {activeblock[i].y = activeblock[i].y-1; 
		} paint (); 
		}//Right Move function moveright () {if (Checkrightborder ()) {erase ()); 
		for (var i=0; i<4; i++) {activeblock[i].y = activeblock[i].y + 1; 
	} paint (); 
}//rotate, because there may be squares covering the existing squares after the rotation. First Use aA tmpblock, the contents of the Activeblock are copied to the Tmpblock,//to the Tmpblock attempt to rotate, if after the rotation detection found no square conflict, then//the rotation of the Tmpblock value to Activeblock. 
	function rotate () {var tmpblock = new Array (4); 
	for (var i=0 i<4; i++) {Tmpblock[i] = {x:0, y:0}; 
		for (var i=0 i<4; i++) {tmpblock[i].x = activeblock[i].x; 
	Tmpblock[i].y = ACTIVEBLOCK[I].Y; 
	///The center point of the four point first, the four points are rotated 90 degrees around the center. 
	var cx = Math.Round ((tmpblock[0].x + tmpblock[1].x + tmpblock[2].x + tmpblock[3].x)/4); 
	var cy = Math.Round ((tmpblock[0].y + tmpblock[1].y + tmpblock[2].y + tmpblock[3].y)/4); The main algorithm of rotation. 
	It can be broken down to understand. Let's assume that you rotate around the source point. 

	And then add the coordinates of the center point. 
		for (var i=0; i<4; i++) {tmpblock[i].x = Cx+cy-activeblock[i].y; 
	Tmpblock[i].y = cy-cx+activeblock[i].x; 
	Check to see if the square is legal after rotation. 
	For (Var i=0. i<4; i++) {if (!iscellvalid (TMPBLOCK[I].X,TMPBLOCK[I].Y)) {return; 
}//If legal, erase erase (); 
Re-assign a value to the Activeblock. 
	for (var i=0; i<4; i++) {activeblock[i].x = tmpblock[i].x; 
Activeblock[i].y = TMPBLOCK[I].Y; 
//repaint. 
Paint (); Check the left edge and tryMove one on the left to see if it's legal. 
		function Checkleftborder () {for (Var i=0. i<activeblock.length; i++) {if (activeblock[i].y==0) {return false; 
		} if (!iscellvalid (activeblock[i].x, activeblock[i].y-1)) {return false; 
} return true;
Check the right edge and try to move one to the right to see if it is legal. 
		function Checkrightborder () {for (Var i=0. i<activeblock.length; i++) {if (activeblock[i].y==9) {return false; 
		} if (!iscellvalid (activeblock[i].x, activeblock[i].y+1)) {return false; 
} return true;
//Check the bottom boundary, try to move one below to see if it is legal.  
		function Checkbottomborder () {for (Var i=0. i<activeblock.length; i++) {if (activeblock[i].x==17) {return false; 
		} if (!iscellvalid (activeblock[i].x+1, activeblock[i].y)) {return false; 
} return true;
}//Check coordinates for (x,y) whether in the area species already exist, the existence of the lattice is not legal. function Iscellvalid (x, y) {if (x>17| | x<0| | y>9| | 
	Y<0) {return false; 
	} if (Area[x][y]==1) {return false; 
return true; }//Erase function Erase () {for (var i=0; i<4; i++) {tbl.rows[activeblock[i].x].cells[activeblock[i].y].style.backgroundcolor= "white"; }//Draw active Graphics function paint () {for (var i=0; i<4; i++) {Tbl.rows[activeblock[i].x].cells[activeblock[i].y].style. 
	Backgroundcolor= "#CC3333"; 
	}//Update area Array function Updatearea () {for (var i=0; i<4; i++) {area[activeblock[i].x][activeblock[i].y]=1; 
	}//elimination function Deleteline () {var lines = 0; 
		for (var i=0; i<18; i++) {var j=0; 
		for (; j<10; j + +) {if (area[i][j]==0) {break; 
		} if (j==10) {lines++; 
			if (i!=0) {for (var k=i-1; k>=0; k--) {area[k+1] = area[k]; 
		} Area[0] = Generateblankline (); 
} return lines; /Erase entire panel function Erasearea () {for (var i=0; i<18; i++) {for (Var j=0; j<10; J + +) {Tbl.rows[i].cells[j].s 
		Tyle.backgroundcolor = "White"; ()}//Redraw entire panel function Paintarea () {for (Var i=0;i<18;i++) {for (Var j=0 j<10; J + +) {if (area[i][j]==1) {TBL.ROWS[I].CELLS[J].STyle.backgroundcolor = "#CC3333"; 
}}//produces a blank line. 
	function Generateblankline () {var line = new Array (10); 
	for (var i=0; i<10; i++) {line[i] = 0; 
return line; 
//Update score function Updatescore () {document.getElementById ("score"). innertext= "" + score; 
	}//Keyboard control function Keycontrol () {if (status!=1) {return; 
	var code = Event.keycode; 
			Switch (code) {case 37:{moveLeft (); 
		Break 
			Case 38:{rotate (); 
		Break 
			Case 39:{MoveRight (); 
		Break 
			Case 40:{MoveDown (); 
		Break 
	}}//Start function begin (e) {e.disabled = true; 
	status = 1; 
	TBL = document.getElementById ("area"); 
		if (!generateblock ()) {alert ("Game over!"); 
		status = 2; 
	Return 
	} paint (); 
Timer = setinterval (movedown,1000);  } Document.onkeydown=keycontrol;
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.