JavaScript enables game process analysis and source code sharing on Tetris.

Source: Internet
Author: User

JavaScript enables game process analysis and source code sharing on Tetris.

Observe the beauty of programming: "Although the program is difficult to write, it is wonderful. To write a program well, you need to write basic knowledge, including programming languages, data structures, and algorithms. The program is well written and requires meticulous logic thinking and a good foundation for organizing the program, and is familiar with the programming environment and programming tools ."

After years of computer learning, do you fall in love with programming. In other words, I did not try to write a game on my own, so I do not love programming.

The sensation and economic value caused by Tetris can be said to be a major event in the game history. It seems simple but changeable and addictive. I believe that most of the students have been obsessed with it.

Game Rules

1. A plane Virtual Site for placing a small square. Its standard size is 10 rows in width and 20 columns in height, in the unit of each small square.

2. A group of Rule images composed of four small squares. The group is called Tetromino in English, and there are 7 types of squares in Chinese, they are named in the shape of S, Z, L, J, I, O, and T.

I: a maximum of four layers can be eliminated at a time.

J (left and right): eliminates a maximum of three layers, or eliminates two layers.

L: three layers can be eliminated at most, or two layers can be eliminated.

O: Eliminate Layer 1 to Layer 2

S (left and right): a maximum of two layers, which may easily cause holes

Z (left and right): a maximum of two layers, which may cause holes

T: a maximum of two layers

The square will slowly continue falling from the top of the area. Players can rotate the square in 90 degrees, move the square around in the unit of a grid, so that the square is accelerated. When the block is moved to the bottom of the area or the block cannot be moved to other blocks, it is fixed here, and the new block appears above the area and begins to fall. When a column in the area is filled with blocks, the column disappears and becomes the score of the player. The more columns are deleted, the higher the score index.

Analysis and Solution

When each block falls, we can:

1) rotate in the proper direction

2) horizontally move to a column

3) vertical drop to the bottom

First, you need to use a two-dimensional array, area [18] [10] represents the 18*10 game area. The value 0 in the array indicates null, and 1 indicates square.

There are 7 types of blocks, each of which has four directions. Define activeBlock [4]. The value of this array is predefined before compilation and used directly in the program.

Difficulties

1) border check.

// Check the left boundary and try to move one to the left to see if it is 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 boundary and bottom boundary need to be checked

2) The rotation requires mathematical logic. A point is rotated 90 degrees relative to another point.
3) Timing and listening to Keyboard Events allow 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;

Procedure

1) Click Start> to create an active image and set the timer.

// The square of the current activity. It can be moved left and right down and changed. When the base is reached, the area; var activeBlock; // produces the square shape, which has seven basic shapes. Function generateBlock () {activeBlock = null; activeBlock = new Array (4); // random generation of 0-6 arrays, representing 7 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 four small squares that have just been 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 ;}

2) After each downward movement, check whether the bottom is reached. If the bottom is reached, try to cancel the operation.

// Delete function deleteLine () {var lines = 0; for (var I = 0; I <18; I ++) {var j = 0; (; 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) create an activity chart and set the timer.


To be optimized

1) set the color of blocks of different shapes.

Idea: In the create block function, set activeBlockColor. The colors of the seven different forms of blocks vary. (In addition to modifying the generateBlock method, you also need to modify the paintarea method. Due to incomplete consideration at the beginning, after a row is eliminated, the color of the re-painted square is unified. Therefore, you can consider removing n rows in the table and then adding n rows at the top, to ensure the integrity of blocks is not eliminated ).

2) When the current square falls, you can view the next square in advance.

Idea: Split the generateBlock method into two parts. One part is used to randomly try the next square, and the other part is used to cache the square currently to be depicted. When the current square is fixed at the bottom, the next square begins to be depicted, and a new square is randomly generated again. This is repeated.

Complete HTML source code:

<! DOCTYPE> 

Complete tetris. js source code:

/*** JavaScript Tetris game v 1.0 * // indicates the table on the page. This table is the main panel var tbl to be displayed. // The Game status is 0: not started; 1 run; 2 stop; var status = 0; // timer, the moveDown operation var timer will be performed in the timer; // score var score = 0; // area is an array of 18*10 and corresponds to the table on the page. The value is 0 at first, and 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 ;}/// the currently active square, which can be moved left and right and changed. When the base is reached, the area; var activeBlock; // produces the square shape, which has seven basic shapes. Function generateBlock () {activeBlock = null; activeBlock = new Array (4); // random generation of 0-6 arrays, representing 7 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}; activeBlo Ck [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 that have just been 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 the function moveDown () {// check the bottom boundary. if (checkBottomBorder () {// if there is no bottoming, the current image is erased, erase (); // update the coordinates of the current image for (var I = 0; I <4; I ++) {activeBlock [I]. x = activeBlock [I]. x + 1 ;}/// redraw the current image paint () ;}/// bottoming, else {// stop the current timer, that is, stop moving down automatically. clearInterval (timer); // update the area array. updatearea (); // Delete line var lines = deleteLine (); // if there is a Delete line, if (li Nes! = 0) {// update score = score + lines * 10; updateScore (); // erase the entire panel erasearea (); // re-paint the Panel paintarea ();} // generate a new image and determine whether it can be placed in the initial position. if (! GenerateBlock () {alert ("Game over! "); Status = 2; return;} paint (); // timer, run moveDown timer = setInterval (moveDown, 1000) once every second )}} // move left function moveLeft () {if (checkLeftBorder () {erase (); for (var I = 0; I <4; I ++) {activeBlock [I]. y = activeBlock [I]. y-1 ;}paint () ;}// move the function moveRight () {if (checkRightBorder () {erase (); for (var I = 0; I <4; I ++) {activeBlock [I]. y = activeBlock [I]. y + 1 ;}paint () ;}// rotate, because after rotation, there may be squares to overwrite existing Square. // use a tmpBlock to copy the content of activeBlock to tmpBlock. // try to rotate the tmpBlock. If no square is found to conflict after rotation, then // give the value of the rotated tmpBlock 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;} // calculate the center of the four points, and the four points Rotate 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. this can be understood through decomposition. // Assume that the Source Vertex is rotated first. Then add the coordinates of the center. For (var I = 0; I <4; I ++) {tmpBlock [I]. x = cx + cy-activeBlock [I]. y; tmpBlock [I]. y = cy-cx + activeBlock [I]. x;} // check whether the box after rotation is valid. for (var I = 0; I <4; I ++) {if (! IsCellValid (tmpBlock [I]. x, tmpBlock [I]. y) {return ;}/// if valid, erase () is erased; // activeBlock is assigned a new value. for (var I = 0; I <4; I ++) {activeBlock [I]. x = tmpBlock [I]. x; activeBlock [I]. y = tmpBlock [I]. y;} // redraw. paint ();} // check the left boundary and try to move one to the left to see if it is 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 boundary 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 and try to move one to the bottom 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 whether the specified area already exists in the coordinate (x, y). If yes, the square is invalid. 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" ;}// function paint () {for (var I = 0; I <4; I ++) {tbl. rows [activeBlock [I]. x]. cells [activeBlock [I]. y]. style. backgroundColor = "# CC3333" ;}// update the area array Function updatearea () {for (var I = 0; I <4; I ++) {area [activeBlock [I]. x] [activeBlock [I]. y] = 1 ;}/// delete 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 the entire panel function erasearea () {for (var I = 0; I <18; I ++) {for (var j = 0; j <10; j ++) {tbl. rows [I]. cells [j]. style. backgroundColor = "white" ;}}// re-paint the 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"; }}}// Generate a blank line. function generateBlankLine () {var line = new Array (10); for (var I = 0; I <10; I ++) {line [I] = 0 ;} return line;} // update the Score function updateScore () {document. getElementById ("score "). innerText = "" + score;} // 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.