Wednesday, February 9, 2011

Classic Javascript(Tetris Game)

This post I'm going to explain classic javascript. Because in next posts I'm going to describe JQuery and for JQuery we have to know classic javascript as well.
Tetris Game:
In this game, computer offers you some blocks and moves them in specified speed and you should finally place them in some places to built a smooth surface. After building it you will have 1 score for every row and these rows will be damaged automatically.
the game is available in above.
The game logic is available here:




  1.  init: In this method we should initiate the game. First we create the scene (1) then we select a shape to start game (2) then key events should be handled (12)
  2. createScene: In this method severity combo table of game and label of scores should be created.
  3. showNextShape: In this method the score should be calculated(4) then a random shape with random position and random angel and color should be created. Then we play the shape(7)
  4. calcScore: In this method we are going to check if a row is completed or not or if the game can continue or not. we start in a loop from bottom to up. we check the current row by this complicated codes:
            // a row is completed
            var rowCompleted = true;
            // fix cells is visited
            var endCheck = true;
            for (var j = 0; j <= maxY; j++) {
                if (tbl.rows[i].cells[j].fix)
                    endCheck = false;
                else {
                    rowCompleted = false;
                }
            }
            if (endCheck)
                break;
            if (rowCompleted) {
                // shifting top rows of current row to this row
                for (var k = i - 1; k >= 0; k--) {
                    var jmp = true;
                    for (var j = 0; j <= maxY; j ++) {
                        if (tbl.rows[k].cells[j].fix)
                            jmp = false;
                        tbl.rows[k + 1].cells[j].fix = tbl.rows[k].cells[j].fix;
                        tbl.rows[k + 1].cells[j].style.backgroundColor = tbl.rows[k].cells[j].style.backgroundColor;
                    }
                    if (jmp)
                        break;
                }
                addScore();
                // because of shifting the current row is changed so should be checked again
                i++;
            }
    Every things will be handled by two flags: "rowCompleted" will check if a row is completed or not. if "fix" flag of all of current row cells is true, it means that the current row is completed. "endCheck" will check if the check loop(the loop we are in) should continue or not. if one of the current row cells has "fix" flag with value of true, it means we have a shape body on the current row and so the current row should be checked. if we meet no cells with true value of "fix" flag, it means the current row is empty and it doesn't need to continue the upper rows. because we don't have the following state in this game:

    to prevent the above state, if the current row is completed, we should shift upper rows to the current row. In inner loop we handle this.
    In our checking loop if current row is the first row, it means the game is over(5).
  5. gameOver: In this method we should create game over div and recolor it every seconds.
  6. addScore: In this method we should add up the score and show it in its label
  7. playShape: This method is working just during the "endGame" flag is false. this method will move the shape to the next step. In this method we should check if we can change the position of the shape or not(8) if yes, we add up "currentPosX " flag and then create the shape (9) then recall "playShape" method in the time which severity combo determines (if we are in exteraTimer state the exteraTimer has priority. exteraTimer is set whenever bottom arrow key is pressed). else we should set the fix shape(11) then we should show next shape(3).
  8. canChangePos: In this method we should check if the current shape can have new X position and new Y position and new Degree. If yes, it returns true else false. So we should check any shapes separately. any shapes has its own specifics so we should check the edges of it. the shape should not pass right and left side of the containing table and old shapes.
  9. createShape: In this shape we should first clear the table(10) then we should create current shape with current degree. the cell of the shape "shape" flag should be true.
  10. clearTable: This method clears the old shapes. It checks all cells and if current cells is not fix(by "fix" flag of it) and is shape(by "shape" flag of it) it make the shape flag of the current cell false and clear background color of it.
  11. setFixShape: This method makes current shape cells "fix" flag true.
  12. movePlayer: This method is triggered whenever key down happens. if current key is left arrow key, we should check if we can change the position or not(8) then decrease the "currentPosY" flag and then create the shape(9). for right arrow key we do so but increase of "currentPosY" should be happens. for enter key we should rotate the current shape to the next degree by left direction. but first we should check it if is allowed or not(8). next degree is specified by "incRedDegree" method(8). we also do this for space key but the direction is right. for down arrow key we should set "exteraTimer" to increase the shape velocity.
  13. incRedDegree: In this method we increase or decrease the degree. the allowed degrees are 0(0 degree), 1(90 degree), 2(180 degree), 3(270 degree).
  14. rotateRight: Increases "currentDegree" flag (13).
  15. rotateLeft: Decreases "currentDegree" flag (13).
We do all of them by javascript. now we are going to explain some javascript syntax and also DOM(document object model).
  1. var: the declaration of variable in java script. It doesn't need the data type. data type will be determined by its value. for example: var speedValue = 20;
  2. function: the declaration of methods in java script. the pattern is: function mthodName(method params ...){}. for example:

    function incRedDegree(degree, op) {
        if (op) {
            degree ++;
            degree = degree % 4;
        } else {
            degree --;
            degree = (degree < 0) ? 3 : degree;
            degree = degree % 4;
        }
        return degree;
    }

  3. setTimeout: this method has two parametes. first: the function to be called after specified milliseconds. second: the time in milliseconds to call the specified function. the specified function is called in other thread. so it is useful for multy agent programs. for example:

    setTimeout(function() {
                    showNextShape();
                }, exteraTimer ? exteraTimer : severitySelect.value);
  4. Array: for array we should create Array for a variable. we can push a value in array of pop it and access to its item by arVar[index]. for example:

    var team = new Array();
    team.push("Mostafa");
    team.push("John");

    team.push("Jack");
    alert(team[2]);
    alert(team.pop());
  5. alert: It blocks the current thread and alert a message like above sample.
  6. confirm: It blocks the current the thread and confirm a message with "ok" and "cancel" buttons then returns true or false for any button. For example:

    <input type="submit" value="delete" onclick='return confirm("would you like to delete?")'/>
  7. for and if: It is just like java
DOM:
  1. document: It is main object of DOM. It has useful methods and Object.
    1. createElement: it creates a html element dynamically. for example:

          var severitySelect = document.createElement("select");
          document.forms[0].appendChild(severitySelect);
          var easy = document.createElement("option");
          easy.innerHTML = "easy";
          easy.value = 250;

          var medium = document.createElement("option");
          medium.innerHTML = "medium";
          medium.value = 150;

          var hard = document.createElement("option");
          hard.innerHTML = "hard";
          hard.value = 50;

          severitySelect.appendChild(easy);
          severitySelect.appendChild(medium);
          severitySelect.appendChild(hard);
    2. getElementById: It gets the html element of the current document by specified Id.
  2. appendChild: appends element param to parent element. for example:

    severitySelect.appendChild(easy);
  3. style: the style object of html element. It contains all stylesheet fields like: "borderColor", "borderWidth", "borderStyle", "backgroundColor", "fontSize", ...
  4. rows: An array of table rows.
  5. cells: An array of table rows cells.
  6. events: You are able to handle events by assigning a function to it. for example:

        document.onkeyup = function keyUp(event) {
            var event = document.all ? window.event : event;
            if (event.keyCode == 40) { //down key
                exteraTimer = null;
            }
        }
  7. custom field: you can have you custom field just use it. for example:

    tbl.rows[i].cells[j].shape = true;
there are much more features in DOM. We can not explain all of them in this post. but the major ones have been passed in this post. you can learn other experiences just by trying yourselves and searching for samples in the Internet. It the method which I have learned. I use advance classic javascript in my future posts. All needed javascript knowledge of this game is explained. you can download the source code here.



all rights reserved by Mostafa Rastgar and prgassist weblog

No comments: