Use pure JS for Tetris-Brief Introduction (1)

Source: Internet
Author: User

Use pure JS for Tetris-Brief Introduction (1)
Everyone knows that Tetris is a popular game. I played it when I was very young. It is 25 years old. It can be said that Tetris has a long history, it was my idea to create Tetris last week. Maybe it's because you have never written such a thing. Only a small part of the code is completed, about 1/5. Today, I decided to write some ideas first. As for Tetris, there are many difficulties. If JavaScript code is used to write data, we need to consider collision, boundary, whereabouts, and other issues. Most of these issues will not be taken into account in this article, I just provided some ideas and started to talk about it, because I haven't finished writing this game yet, but I want to write a blog record, so I got this series of blogs. Back to the topic, let's first think about what Tetris needs? I will make a simple induction. If I put it simply, it is a Tetris object, what is in this object? We can imagine that there is a plane Cartesian coordinate system, which has a X axis, a Y axis, and a unit ), tetris is a "Grid", which begins to fall from a place and stops falling somewhere, therefore, we define the "drop Area" of Tetris ). However, dropping is an action, so we also need a class (defined as operate) to control the action falling. Now, let's introduce it here. Let's make a summary of the nature of the Code, which means to make a summary of the above Code. /* Class */function Tetris () {var self = this; // itself this. area = null; // area this. operate = null; // operation/* initialize X, Y, unit: 5 or 20 */this. x = 5; this. y = 5; this. unit = 20; this. running = null; // whether the object is running // The Russian square object ID this. id = "tempid"; // start the game this. start = function () {this. area = new getArea (this. x, this. y, this. unit, "tempid"); // obtain the Area object, where TEMPID is the Object ID of the Russian square this. operate = new OperateTetris (this. area, self); // whether to replace Tetris if (this. bytes Ate. mayPlace () {// alert (1); this. operate. place () ;}// starts the game document. getElementById ("startGame "). onclick = function () {self. start () };}then, when we click StartGame, start the game, that is, run the start () method. Well, now let's start to consider what is actually needed in the Area object. function getArea (x, y, unit, id) needs to be included in four parameters. The first three parameters have just been mentioned, the fourth parameter is the Area ID. We need the object "area", so we can use HTML code to set the ID. Everyone who has played tetris knows that each touch bottom will add a new element, and the new element is "random, every time a row is full (the color is not considered here), a row will be deleted. Of course, when we form a square that can be eliminated by multiple rows, then we can delete multiple rows. The code below is a small summary of the above text, and the code is not completed yet. // Obtain the horizontal and vertical coordinates of the Region. function getArea (x, y, unit, id) {this. x = x; this. y = y; this. unit = unit; // the size of each unit, in pixels. this. el = document. getElementById (id); // obtain the ID object this. board = []; // panel, that is, the element within the region range (Tetris) // Add the element this. addElement = function () {// obtain the X start coordinate of the starting element and the Y start coordinate (incorrect) // obtain the number of times the X coordinate falls, and the number of times the Y axis 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; // determine the position of the element} // delete all rows this. removeFullLines = function () {var lines = 0; for (var I = this. y-1; y> 0; y --) {if (this. linesRelated (y) {lines ++; this. y ++ ;}}// linear correlation (determines whether it is full) this. linesRelated = function (y) {for (var x = this. x; x> 0; x --) {this. removeLines (y); if (this. board [y] [x]) {return false;} // unknown} return true;}; // remove 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 --) {/* temporarily written here today */}};} one thing to note is that Tetris is of a two-dimensional nature, so I defined a two-dimensional array of the board type here, that is, the board [row] [column] (board [y] [x]). well, we also need a class here. This class is the "Action" class that controls the element's whereabouts. So what should there be in this fall "action" class? We need to consider the boundary, so we have a (region). We need to consider that tetris has a tetris object because of the different types of squares, there are various shapes, so we must consider the category of the Square (types), and the next category (NEXTTYPE), because the square has the next prompt; we need to consider the position of the square in the AREA, so we need to determine whether the game is paused and then running. Of course, the SPEED of the square's whereabouts must also be taken into account, if the GAME is OVER, it is necessary to determine whether the GAME has stopped PED. Of course, blocks are one element, so we need to consider elements. Of course, the most important thing is falldown ). the following is the defined code: var self = this; // The current object this. area = area; this. tetris = tetris; this. types = null; // The type of the block; this. nextType = null; // The next type // Initialize X and Ythis. x = null; this. y = null; this. position = 0; // initial position this. board = []; // this is used to fill in HTML elements. elements = []; this. running = null; // whether this. stopped = null; // whether to stop this. fallDownId = null; // this. speed = null; // The speed is a little dizzy. Let's choose a starting point. Our starting point is how to construct a square. You should know several shapes of the Russian square, such as T-shaped, L-shaped, and mouth-shaped. Then we can imagine that the Russian square is defined as a two-dimensional array, then there is 1 where the element is located, and 0 where no element is located to construct the shape. The following code:/* combination of squares, combined with arrays (two-dimensional array) use 0, 1 to indicate whether a Square exists. If it is 0: No, and 1: Yes, the following logic can be very clear. */This. blockComplex = [[0, 0, 1], [, 1], [, 0] // _ |], [[, 0], [, 1], [, 0] // L], [[, 0], [, 1], [, 0] // T], [[, 0], [, 1], [, 0] // --], [[, 0], [, 1], [, 1] // port], [[, 1], [, 0], [, 0] // Z]; after the shape is constructed, of course we need to consider the performance of the program, so I created the following GETTER method to determine whether the game is running moderately. /* A series of GETTER methods are speed, X, Y axis, 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 establish a method reset (). To put it bluntly, it is to restore the game's initial 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 hits the bottom, it will certainly trigger the start of the next tetris. So we must have a method here. I haven't thought about the content yet, just give it a shelf. I directly return TRUE. This. mayPlace = function () {return true;} below is the most important method, that is, our method of replacing blocks. Let's give a brief introduction. I don't know if I can tell you well. In a coordinate system, if the square falls, it must be Y. After all, the square falls down to the bottom, of course, we still need wired lines. If we keep stacking blocks, this line will definitely increase, and our square itself is a DIV, which must be a process of dropping the DIV, these divs must be in the AREA range. Let's think about it. The first step is to create an empty BOARD, that is, a panel, and then fill it with stuff? // Create an empty object, that is, all the objects whose values are 0, and return 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 starting whereabouts. Of course, the Y axis must be 0, the X axis can be set based on your preferences. Of course, the fallen DIV must belong to the child element under this AREA, so we will definitely put this APPENDCHILD here. The following is the code:/* replace */this. place = function () {// initialize var operate = this. blockComplex [this. types]; // The Position of the Start X axis of the region var AreaXStartPos = parseInt (this. area. x-operate [0]. length); // The Position of the Start Y axis of the region. // 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, it is 1 this. x = AreaXStartPos; // assign the new position to X; this. y = AreaYStartPos; // assign the new location to y; // construct an empty object and save it to BOARD/* y: Row, x: column * // alert (operate [0]. length + "" + Operate. length); this. board = this. createEmpty (operate [0]. length, operate. length);/* line, falling down, initializing */var lines = 0; var foundLines = false; // looping, traversing the line first, 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 // 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 goes to the main EL of APPEND. This. board [yAxis] [xAxis] = el; this. elements. push (el); // push to elements}/* Do I personally think this function should be a way to accelerate downloading? Not clearly aware */if (lines) {yAxis --;} if (foundLines) {lines ++;} note that when the next Tetris (random) so we need to define a RANDOM method. In fact, every fall is a RESET loop, but the game is not over yet. // Random number, generating 1 ~ Function random (I) {return Math. floor (Math. random () * I) ;}well, I only want to introduce one idea today. Of course, I didn't write this game. when the next one came out, the game would have a big shelf, I am embarrassed to release some other code, which is too poorly written. In fact, this Tetris is not completely written by myself. I also referred to other people's things, but it is not plagiarism. I want to make a game through my own efforts, this is my dream for many years! As for all the code, I will not post it, because I have not finished writing it, just a Summary of the code I have written over the past few days. Experts can ignore the code I have written.

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.