Tetris in Javascript : Game « Page Components « JavaScript DHTML

JavaScript DHTML
1. Ajax Layer
2. Data Type
3. Date Time
4. Development
5. Document
6. Event
7. Event onMethod
8. Form Control
9. GUI Components
10. HTML
11. Javascript Collections
12. Javascript Objects
13. Language Basics
14. Node Operation
15. Object Oriented
16. Page Components
17. Security
18. Style Layout
19. Table
20. Utilities
21. Window Browser
Microsoft Office Word 2007 Tutorial
Java
Java Tutorial
Java Source Code / Java Documentation
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
C# / C Sharp
C# / CSharp Tutorial
ASP.Net
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
PHP
Python
SQL Server / T-SQL
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
JavaScript DHTML » Page Components » Game 
Tetris in Javascript



<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
    <head>
        <title>Tetr&iacute;ssimus &copy; (by Joan Alba Maldonado)</title>
        <!-- (cTetrissimus - Programa realizado por Joan Alba Maldonado (granvino@granvino.com). Prohibido publicar, reproducir o modificar sin citar expresamente al autor original. 
  Tetrissimus
  by Joan Alba Maldonado (100% DHTML).
                granvino@granvino.com

  Prohibited to publish, reproduce or modify without maintain author's name.

  Approximate date: of March 2006 (fixes beyond 16 of August 2006).
  Dedicated to Yasmina Llaveria del Castillo.
        
        
        -->
        <script language="JavaScript1.2" type="text/javascript">
            <!--

                //(c) Tetrissimus - Programa realizado por Joan Alba Maldonado (granvino@granvino.com). Prohibido publicar, reproducir o modificar sin citar expresamente al autor original.

                //Variable que activa el mapa modo debug:
                var mostrar_mapa_debug = false;
                
                //Variable que guarda el primer evento del teclado, por razones de compatibilidad:
                var primer_evento = "";
                
                //Se dibuja el mapa en una varialbe tipo string:
                var mapa = "000000000000" +
                           "000000000000" +
                           "000000000000" +
                           "000000000000" +
                           "000000000000" +
                           "000000000000" +
                           "000000000000" +
                           "000000000000" +
                           "000000000000" +
                           "000000000000" +
                           "000000000000" +
                           "000000000000" +
                           "000000000000" +
                           "000000000000" +
                           "000000000000" +
                           "000000000000" +
                           "000000000000" +
                           "000000000000" +
                           "000000000000" +
                           "000000000000" +
                           "000000000000" +
                           "000000000000";
                           
                //Se declara la matriz para guardar el mapa:
                var mapa_matriz = new Array();
                
                //El numero de columnas del mapa:
                var numero_columnas = 12;
                //El numero de filas del mapa:
                var numero_filas = 22;
                
                //Variable que contiene el ancho de cada celda (tile o panel):
                var panel_width = 20;
                //Varialbe que contiene el alto de cada celda (tile o panel):
                var panel_height = 20;

                //Velocidad de caida de las piezas (entre menor, mas rapido):
                var velocidad_inicial = 1500//Velocidad inicial.
                var velocidad = velocidad_inicial; //Velocidad que ira incrementandose (al decrementar la variable).
                
                //Pizels de desplazamiento en la caida de las piezas:
                var desplazamiento_inicial = panel_height * 1//Desplazamiento inicial.
                var desplazamiento = desplazamiento_inicial; //Desplazamiento que ira incrementandose.
        
                //Se realiza un bucle para guardar el mapa en la matriz:
                for (x=0; x<mapa.length; x++) { mapa_matriz[x= mapa.substring(x, x+1)}

                //Variable que guarda el numero de la pieza actual:
                var numero_pieza = 0;
                //Variable que guarda el numero de la pieza siguiente:
                var numero_pieza_siguiente = 0;
                
                //Matriz que contiene la coleccion de piezas, con su ancho, alto y color:
                var pieza = new Array();
                
                //Varialbe para saber si una pieza se ha elevado verticalmente al ser rotada:
                var al_rotar_se_ha_elevado = false;

                //Variable donde se guardara el Interval del movimiento de la pieza cayendo:
                var movimiento_pieza = setInterval(""1);

                //Variable donde se guardara el Timeout que hara que el mensaje del centro de la pantalla se oculte:
                var ocultar_mensaje = setTimeout(""1);

                //Variable donde se guarda el numero de piezas:
                var numero_piezas = 0;

                //Variable que indica si se ha acabado el juego o todavia no:
                var game_over = false//Todavia no se ha acabado el juego.

                //Variable que define las lineas necesarias para cambiar de nivel:
                var lineas_necesarias = 6;
                
                //Variable que cuenta cuantas lineas se han realizado en el nivel actual:
                var lineas_nivel_actual = 0;
                
                //Variable donde se guarda la puntuacion:
                var puntuacion = 0;
                
                //Variable donde se guada el nivel:
                var nivel = 1;
                
                //Contador de niveles, que cuando llega a 10 se sube el desplazamiento de las piezas (se desplazan mas espcio hacia abajo, para hacerlo mas dificil):
                var contador_niveles_desplazamiento = 0;
                
                //Variable que impide el Game Over, cuando ya ha ocurrido:
                var impedir_game_over = false;

                //Matriz vacia que se utilizara para cuando se llame a mostrar_mapa:
                var guardar_mapa_anterior = new Array();

                //Funcion que crea las piezas, con su ancho, alto y color:
                function crear_piezas()
                 {
                    //Pieza 1:
                    pieza[1new Array();
                    pieza[1]["forma""1" +
                                        "1" +
                                        "1" +
                                        "1";
                    pieza[1]["width"1;
                    pieza[1]["height"4;
                    pieza[1]["color""#aaffdd";

                    //Pieza 2:
                    pieza[2new Array();
                    pieza[2]["forma""22" +
                                        "22";
                    pieza[2]["width"2;
                    pieza[2]["height"2;
                    pieza[2]["color""#ffffdd";

                    //Pieza 3:
                    pieza[3new Array();
                    pieza[3]["forma""33" +
                                        "03" +
                                        "03";
                    pieza[3]["width"2;
                    pieza[3]["height"3;
                    pieza[3]["color""#ddaaff";

                    //Pieza 4:
                    pieza[4new Array();
                    pieza[4]["forma""44" +
                                        "40" +
                                        "40";
                    pieza[4]["width"2;
                    pieza[4]["height"3;
                    pieza[4]["color""#ffaadd";

                    //Pieza 5:
                    pieza[5new Array();
                    pieza[5]["forma""055" +
                                        "550";
                    pieza[5]["width"3;
                    pieza[5]["height"2;
                    pieza[5]["color""#ffddff";

                    //Pieza 6:
                    pieza[6new Array();
                    pieza[6]["forma""660" +
                                        "066";
                    pieza[6]["width"3;
                    pieza[6]["height"2;
                    pieza[6]["color""#aaddff";

                    //Pieza 7:
                    pieza[7new Array();
                    pieza[7]["forma""070" +
                                        "777";
                    pieza[7]["width"3;
                    pieza[7]["height"2;
                    pieza[7]["color""#ffddaa";

                    //Pieza 8:
//                    pieza[8] = new Array();
  //                  pieza[8]["forma"] = "808" +
//                                        "080" +
//                                        "080";
    //                pieza[8]["width"] = 3;
      //              pieza[8]["height"] = 3;
        //            pieza[8]["color"] = "orange";

                    //Se guarda el numero de piezas:
                    numero_piezas = pieza.length - 1;

                 }
                
                
                //Funcion que inicia el juego:
                function iniciar_juego()
                 {
                    //Se setea que aun no se ha acabado el juego:
                    game_over = false;

                    //Desbloquea el impedir game over:
                    impedir_game_over = false;

                    //Se crean las piezas:
                    crear_piezas();
                    
                    //Se setea la velocidad a la inicial:
                    velocidad = velocidad_inicial;
                    //Se setea el desplazamiento al inicial:
                    desplazamiento = desplazamiento_inicial;
                    
                    //Se deifne el contador de niveles que incrementa el desplazamiento, a 0:
                    contador_niveles_desplazamiento = 0;
                    
                    //Se definen las lineas del nivel actual a 0;
                    lineas_nivel_actual = 0;
                    
                    //Se define el marcador de puntuacio a 0:
                    puntuacion = 0;
                    
                    //Se define el nivel a 1:
                    nivel = 1;

                    //Se define el numero de pieza actual a 0 (ninguno):
                    var numero_pieza = 0;
                    //Se define el numero de pieza siguiente a 0 (ninguno):
                    var numero_pieza_siguiente = 0;

                    //Vaciar mapa (recorre la matriz, cambiando todo por 0):
                    for (x=0; x<mapa_matriz.length; x++) { mapa_matriz[x"0"}
                    

                    //Se recoge el mapa en una matriz, para calcular las diferencias con este y el posterior:
                    mapa_matriz_anterior = guardar_mapa_anterior;
                    
                    //Se muestra el mapa:
                    mostrar_mapa(mapa_matriz, mapa_matriz_anterior);

                    //Se actualiza el marcador:
                    actualizar_marcador();
                    
                    //Se muestra el mensaje de "Comienza el juego":
                    mostrar_mensaje("The game begins");
                    
                    //Sacamos una pieza:
                    sacar_pieza();
                 }

                //Funcion que actualiza la matriz del mapa:
                function actualizar_mapa(numero_pieza)
                 {
                    //Si se ha enviado como pieza el cero, es que no hay piezas:
                    if (numero_pieza == 0)
                     {
                        //Recorre la matriz, cambiando todo lo que no sea 0 ni X por 0:
                        for (x=0; x<mapa_matriz.length; x++)
                         {
                            //Si no es 0 ni X, lo cambia a 0:
                            if (mapa_matriz[x!= "0" && mapa_matriz[x!= "X") { mapa_matriz[x"0"}
                         }
                     }

                    //Pero si se ha enviado otro numero, mayor que cero:
                    else if (numero_pieza > 0)
                     {
                        //Se borra la pieza del mapa:
                        actualizar_mapa(0);
                        
                        //Se calcula en que posicion de la matriz comienza la pieza:
                        matriz_posicion_x = numero_columnas - (parseInt(document.getElementById("pieza").style.left/ panel_width);
                        matriz_posicion_y = parseInt(document.getElementById("pieza").style.top/ panel_height + 1;
                        //Esta es la posicion inicial (la clave de la matriz) donde comienza la pieza:
                        matriz_posicion_inicial = (numero_columnas * matriz_posicion_y- matriz_posicion_x;
                        //Se actualiza la matriz pintando la pieza en ella, segun la posicion:
//                        for (x=0; x<mapa_matriz.length; x++)
                        for (x=matriz_posicion_inicial; x<matriz_posicion_inicial+pieza[numero_pieza]["forma"].length; x++)
                         {
                            //Si estamos en el indice donde comienza la pieza:
                            if (x == matriz_posicion_inicial)
                             {
                                //El contador de columnas:
                                contador_columnas = 0;
                                //La variable que se suma para saltar una fila:
                                saltar_fila = 0;
                                for (y=0; y<pieza[numero_pieza]["forma"].length; y++)
                                 {
                                    //Se toma como posicion de la matriz la posicion inicial y se le suma la variable que hace saltar filas:
                                    posicion_matriz_actual = x + saltar_fila;
                                    //Si la posicion actual de la pieza no es un cero, se graba en la matriz:
                                    if (pieza[numero_pieza]["forma"].substring(y, y+1!= "0") {mapa_matriz[posicion_matriz_actual= pieza[numero_pieza]["forma"].substring(y, y+1)//Se pinta la pieza.
                                    //Se incrementa el contador de columnas:
                                    contador_columnas++;
                                    //Se incrementa la variable para saltar filas:
                                    saltar_fila++;
                                    //Si el contador de columnas es mayor al ancho de la pieza, se salta una fila:
                                    if (contador_columnas >= pieza[numero_pieza]["width"]) { contador_columnas = 0; saltar_fila += numero_columnas - pieza[numero_pieza]["width"]}
                                 }
                             }
                         }
                     }
                 }                

                //Funcion que activa/desactiva la visualizacion del mapa en modo debug:
                function activar_desactivar_mapa_debug(modo)
                 {
                    //Si no se ha enviado alternar, no se alterna el estado:
                    if (modo != "alternar") { var alternar_estado = mostrar_mapa_debug; }
                    //...pero si se ha enviado alternar, se alterna:
                    else var alternar_estado = mostrar_mapa_debug ? falsetrue}
                    
                    //Si se ha desactivado, setea para que no se muestre el mapa y esconde el mapa:
                    if (!alternar_estado) { mostrar_mapa_debug = false; document.getElementById("mapa_debug").style.visibility = "hidden"; document.formulario.casilla.checked = false}
                    //Si no (se ha activado), lo vuelve a activar y a hacer visible:
                    else mostrar_mapa_debug = true; document.getElementById("mapa_debug").style.visibility = "visible"; document.formulario.casilla.checked = true; mapa_matriz_anterior = guardar_mapa_anterior; mostrar_mapa(mapa_matriz, mapa_matriz_anterior)}
                 }

                //Funcion que muestra el mapa en modo debug:
                function mostrar_mapa(mapa_matriz, mapa_matriz_anterior)
                 {

                    //Si se ha enviado la misma matriz actual que la anterior, sale de la funcion (no hay nada que actualizar):
                    if (mapa_matriz == mapa_matriz_anterior) { return}

                    //Se setea el contador de columnas a cero:
                    var columnas_contador = 0;
                    //Se setea el contador de filas a cero:
                    var filas_contador = 0;

                    //Variable que guardara el color a utilizar en cada celda (tile o panel):
                    var color_panel;

                    //Se borra el mapa:
//                    document.getElementById("mapa").innerHTML = "";
//                    if (mostrar_mapa_debug) { document.getElementById("mapa_debug").innerHTML = ""; } //Si esta en modo debug, tambien se borra el mapa debug.
                    //Se crean las variables que guardaran la informacion del mapa:
                    var mapa_bucle_temp = "";
                    var mapa_debug_bucle_temp = "";

                    //Se realiza un bucle para mostrar el contenido de la matriz en el espacio de debug:
                     for (x=0; x<mapa_matriz.length; x++)
                      {
                         //Se calcula que color utilizar, segun el caracter de celda (tile o panel):
                         if (mapa_matriz[x== "X") { color_panel = "#555555"//Color gris oscuro (caracter X, piezas ya colocadas).
                         else if (mapa_matriz[x!= 0) { color_panel = pieza[mapa_matriz[x]]["color"]//Color de la pieza segun su numero.
                        
                         //Calcular la posicion de la celda (tile o panel):
                         panel_x = columnas_contador * panel_width; //Posicion horizontal.
                         panel_y = filas_contador * panel_height; //Posicion vertical.

                         //Se muestra la imagen en la celda, siempre que no este vacia (0) y que haya habido un cambio desde la anterior:
                         if (mapa_matriz[x!= && mapa_matriz[x!= mapa_matriz_anterior[x]) { mapa_bucle_temp += '<div style="background:'+color_panel+'; top:'+panel_y+'px; left:'+panel_x+'px; width:'+panel_width+'px; height:'+panel_height+'px; position:absolute; padding:0px; font-size:1px; filter:alpha(opacity=80); opacity:0.8; -moz-opacity:0.8; z-index:5000;"></div>'; }

                         //Si esta activado el mapa debug, se escribe en el:
                         if (mostrar_mapa_debug) { mapa_debug_bucle_temp += mapa_matriz[x]}

                         //Se incrementa el contador de columnas:
                         columnas_contador++;

                         //Si se alcanza el numero maximo de columnas, se baja una fila y se setea otra vez el contador a cero y se incrementa el contador de filas (si esta el mapa en modo debug, se baja una linea en este):
                         if (columnas_contador == numero_columnas) { columnas_contador = 0; filas_contador++; if (mostrar_mapa_debug) { mapa_debug_bucle_temp += "<br>"} }
                      }
                     
                     //Se vuelcan las variables en el mapa:
                     document.getElementById("mapa").innerHTML = mapa_bucle_temp;
                     if (mostrar_mapa_debug) { document.getElementById("mapa_debug").innerHTML = mapa_debug_bucle_temp; //Si esta en modo debug, tambien se vuelca el mapa en modo debug.
                 }

                //Funcion que saca una pieza al escenario:
                function sacar_pieza()
                 {
                    //Si ya ha habido game over, se sale de la funcion:
                    if (impedir_game_over) { return}
                    
                    //Si aun no seh a escogido ninguna pieza, se escoge una aleatoriamente:
                    if (numero_pieza == 0) { numero_pieza = elegir_pieza()}
                    //Si antes ya se habia escogido alguna, se setea la actual como la siguiente:
                    else numero_pieza = numero_pieza_siguiente; }
                    //Ponemos el numero de la pieza siguiente, escogido aleatoriamente, en una variable:
                    numero_pieza_siguiente = elegir_pieza();
                    
                    //Se muestra la pieza siguiente:
                    mostrar_pieza_siguiente(numero_pieza_siguiente);

                    //Setear conforme todavia no se ha elevado verticalmente la pieza al ser rotada:
                    al_rotar_se_ha_elevado = false;

                    //Borrar esto:
                    //numero_pieza = 1;

                    //Devolver las piezas a su estado inicial:
                    crear_piezas();

                    //Se recoge el mapa en una matriz, para calcular las diferencias con este y el posterior:
                    mapa_matriz_anterior = guardar_mapa_anterior;

                    //Calcular ancho y alto de la pieza, segun el numero enviado:
                    pieza_width = pieza[numero_pieza]["width"];
                    pieza_height = pieza[numero_pieza]["height"];
                    
                    //Se situa horizontalmente en el centro:
                    //document.getElementById("pieza").style.left = parseInt( (numero_columnas * panel_width) / 2 - pieza_width * panel_width) + "px";
                    document.getElementById("pieza").style.left = "0px";
                    //Se situa verticalmente arriba:
                    document.getElementById("pieza").style.top = "0px";

                    mover_pieza(00);

                    //Se actualiza el mapa:
                    //actualizar_mapa(numero_pieza);mostrar_mapa_debug(mapa_matriz);
                    
                    //Se muestra el mapa:
                    mostrar_mapa(mapa_matriz, mapa_matriz_anterior);


                    //E