miércoles, 26 de mayo de 2010

Un ahorcado en javascript

En esta ocasión seguiremos con ejemplos de programación en javascript. El tema elegido es el ahorcado y el objetivo estudiar la clase string y algunos eventos, principalmente blur y keypress.
Realizaremos el ejercicio usando interfaces basadas en css y que deben ser visibles por igual en todos los navegadores.


En la web podemos encontrar muchos ejemplos y todos ellos usan un teclado simulado para las letras que queremos adivinar
En nuestro caso no lo haremos así a fin de practicar con el evento keypress.

Nuestra interfaz es para dos jugadores; el primero introduce la palabra a adivinar en la casilla de edición de tipo password denominada palabraPassword

<body onload='document.getElementById("palabraPassword").focus()'>
    <div id="pantalla">
      <div id="contenidos">
        <div><h1>EL AHORCADO</h1></div>
        <div id="izquierda">
          <span class="display">
            Introduzca una palabra (10 caracteres máximo)
          </span>
          <span class="display">Sin tildes ni signos de puntuación</span>
          <input type="password" name="palabraPassword" id="palabraPassword" 
            size="10" maxlength="10" onblur="Ahorcado()" />
          <div id="resultados"></div>
          <div>
            <span>Intente adivinarla</span>
            <input type="text" id="letraText" size="1" maxlength="1" 
              onkeypress="return Comprobar(event)" />
          </div>
          <input type="button" id="reiniciarButton" value="REINICIAR" 
            onclick="Reiniciar()" />
        </div>
        <div id="derecha">
          <img alt="" src="imagenes/0.jpg" id="ahorcadoImg" />  
        </div>
      </div>
    </div>
  </body>
 


Después de introducido, cuando dicha casilla pierde el foco por cualquier motivo, le mostramos al segundo jugador el número de letras de la palabra que tiene que adivinar (en nuestro ejemplo 'PALABRA').
Además se suminstrará una ayuda en forma de letra ya adivinada, que se obtiene aleatoriamente.
Si dicha letra está repetida se mostrarán todas sus ocurrencias.

A continuación se transfiere el foco a la casilla de edición llamada letraText.
Todo lo comentado anteriormente lo podemos ver en el fragmento javascript que se muestra abajo
var sPalabra, sLetra, sVer;
  var nErrores=0;
  
  function Ahorcado()
   {
   var n;
      
   sPalabra=document.getElementById("palabraPassword").value;
   sPalabra=sPalabra.toUpperCase();
   n=Math.floor(Math.random()*sPalabra.length);
   sLetra=sPalabra.charAt(n);
   sVer="";
   for(i=0;i>sPalabra.length;i++)
     if(sPalabra.substr(i,1)==sLetra)
       sVer+=sLetra;
     else  
       sVer+="_";
   Ver(sVer);
   document.getElementById("letraText").focus();
   }
   
  function Ver(sVer){
   var sVer2="";
   var i;
   for(i=0;igt;sVer.length;i++)
    sVer2+=sVer.substr(i,1)+" ";
   document.getElementById("resultados").innerHTML =sVer2;
  } 
 

En sPalabra está la palabra que hay que adivinar, sLetra contiene la pista y sVer está formada por dicha letra y una serie de guiones para las letras pendientes de adivinar.

La función Ver() lo único que hace es intercalar un espacio en blanco en la visualización de cada uno de los caracteres.
Cuando el segundo jugador comienza a pulsar letras se pone en marcha el evento keypress
Internet Explorer y Mozilla lo tratan de distinta manera. En IE el carácter se recoge en event.keyCode mientras que Mozilla Firefox usa event.which y en este segundo caso
necesitamos pasar el argumento event en la función que maneja el evento Comprobar(event)
function Comprobar(event)
    {
    var n=0;
    var bEncontrada=false;
    var codigoLetra;
    var sImagen;
    if (event.keyCode)
     codigoLetra=event.keyCode;
    else if(event.which)
     codigoLetra=event.which;
    sLetra= String.fromCharCode(codigoLetra);
    sLetra=sLetra.toUpperCase();
    document.getElementById("letraText").value=sLetra;  
    while(true)
      {
      n=sPalabra.indexOf(sLetra,n);
      if(n==-1) break;
      bEncontrada=true;
      sVer=sVer.substring(0,n)+sLetra+sVer.substr(n+1,sVer.length)
      Ver(sVer);
      n++;
      }
    if(sVer.indexOf("_")==-1)
       {
       document.getElementById("ahorcadoImg").src="imagenes/8.jpg";
       alert("ganó el juego");
       Reiniciar();
       return false;
       }  
    if(!bEncontrada)
     {nErrores++;
      sImagen="imagenes/"+nErrores+".jpg";
      document.getElementById("ahorcadoImg").src=sImagen;
      if (nErrores==7)
        {
        Ver(sPalabra);
        alert("perdió la cabeza");
        Reiniciar();
        return false;
        }
     }     
    document.getElementById("letraText").select(); 
    document.getElementById("letraText").focus();
    return false;  
    }
    
  function Reiniciar()
    {
    nErrores=0;
    document.getElementById("ahorcadoImg").src="imagenes/0.jpg";
    document.getElementById("letraText").value="";
    document.getElementById("palabraPassword").value="";
    document.getElementById("resultados").innerHTML="";
    document.getElementById("palabraPassword").focus();    
    }
 

Una vez leído el código del carácter lo convertimos a string y a mayúsculas para no distinguir con entradas en minúsculas.

La función devolverá false lo que implica que no visualizará el carácter introducido y tendrá que hacerlo manualmente la función a continuación.


Posteriormente comprobaremos si dicho carácter (sLetra) está en la palabra que buscamos
y actuaremos en consecuencia. Para facilitar la introducción de la siguiente letra se debe realizar
la selección del último carácter leído.
Hay que comprobar si el usuario consigue adivinar la palabra antes de ahorcarse, lo que se realiza buscando el carácter '_' en la cadena sVer; cuando no queden letras por adivinar no existirán guiones.


Por el contrario, si no la acertamos antes de cometer los errores permitidos, se producirá el
ahorcamiento.


Para bajarse el ejercicio completo pulse aquí

miércoles, 12 de mayo de 2010

Objetos select y option en javascript

Vamos a estudiar el tratamiento del listbox en javascript. Lo hacemos a través de los objetos select y option.
El objeto select representa la etiqueta <select> de HTML y el objeto option a la etiqueta <option>

Propiedades del objeto select

PropiedadSignificado
formReferencia al formulario que contiene al objeto.
lengthMantiene el número de opciones definidas en el elemento select
nameMantiene el valor del atributo name (nombre asignado al elemento select)
optionsArray que mantiene una entrada por cada opción del elemento select, en el
mismo orden en el que aparecen en el código HTML. Este atributo tiene además
las propiedades descritas en el objeto option.
selectedIndexMantiene el valor del índice de la opción actualmente seleccionada
(o el valor del índice de la primera opción marcada si se han
seleccionado varias opciones).
typeMantiene el valor del atributo type.

Métodos del objeto select

MétodoSignificado
blur()Elimina el foco del objeto select.
focus()Asigna el foco al objeto select.

Eventos del objeto select

EventoSignificado
onBlurEl evento se produce al perder el foco
onChangeEl evento se produce cuando se pierde el foco después de haber sido
alterado
onFocusEl evento se produce al obtener el foco

Constructor del objeto option

new Option([texto[, valor[, seleccionDefecto[, seleccion]]]])
texto que se visualiza en la lista
valor que se almacena en la opción sin visualizarse
seleccionDefecto cuando es true representa el elemento seleccionado por defecto
seleccion representa los elementos seleccionados en un select múltiple

Propiedades del objeto option

PropiedadSignificado
defaultSelectedIndica si la opción debe estar seleccionada por defecto.
selectedIndica si la opción está seleccionada o no.
textMantiene el texto de la opción.
valueMantiene el valor del atributo value de la opción (valor que se envía asociado al
elemento option cuando se manda el formulario al servidor).

Para completar el estudio de estos elementos realizaremos un pequeño ejercicio de ejemplo que
trate las características más significativas de su uso.
En el código HTML que se muestra a continuación mostramos todos los elementos del formulario.
Además del listbox (select) tenemos dos cuadros de texto que nos permitan introducir el texto
y el valor de un nuevo elemento de la lista y los botones que permiten introducir y eliminar un item.


<body onload="Cargar()">
    <div id="contenidos">
   <div id="lista">
  <select id="listbox" onchange="Seleccionar()">
  </select>
   </div>
   <div id="textos">
  Texto <input type="text" id="texto" /><br />
  Valor <input type="text" id="valor" /><br /> 
   </div>
   <div id="boton">
  <input type="button" value="añadir" 
    id="botonAgregar" onclick="Agregar()" /><br />
  <input type="button" value="eliminar" 
    id="botonEliminar" onclick="Eliminar()" />
   </div>
    </div>
  </body>
 
Usando el constructor de option cargamos los valores iniciales al cargar la página
function Cargar(){
  var lista=document.getElementById("listbox");
  lista.options.add(new Option("to be","ser, estar"));
  lista.options.add(new Option("to have",
    "haber, tener"));
  lista.options.add(new Option("to tell","contar"));
 }
 
Cuando seleccionamos un elemento se produce el evento onChange y en ese momento
vamos a visualizar en un cuadro alert el índice del elemento seleccionado, su texto y
su valor.
function Seleccionar(){
 var lista=document.getElementById("listbox");
 alert("elemento seleccionado= "
   +lista.selectedIndex+"\n"+
   "texto= "+lista.options[lista.selectedIndex].text+
   "\n"+"valor= "+
   lista.options[lista.selectedIndex].value);
  }
 

Al pulsar el botón añadir se agrega un nuevo item a la lista.

function Agregar(){
 var lista=document.getElementById("listbox");
 var texto=document.getElementById("texto");
 var valor=document.getElementById("valor");
 lista.options.add(new Option(texto.value,valor.value));
  }
 

Y al pulsarel botón eliminar quitamos de la lista el item seleccionado.

function Eliminar(){
 var lista=document.getElementById("listbox");
 lista.options[lista.selectedIndex]=null;
  }
 

Para bajarse el ejercicio completo pulse aquí

viernes, 23 de abril de 2010

Piedra, papel y tijera en javascript usando DOM

Hoy vamos a diseñar el famoso juego infantil como ejemplo de estructuras alternativas cuidando, además, otros dos aspectos: construir la interfaz usando solamente css y tener en cuenta las instrucciones javascript del DOM getElementById y getElementsByTagName.

En el diagrama coloreado se observa que usamos una capa #pantalla como fondo y sobre ella construimos la capa #contenidos. Para centrar la segunda capa la opción mejor es variar margin.
#pantalla {
        width: 100%;
        overflow: hidden;
     }
     #contenidos {
        width: 600px;
        margin: 0 auto auto;
     }
 
El resto del diseño depende del uso adecuado de float. Dentro de #izquierda situamos las capas #maquina y #humano con float:left, #resultados rompe la tendencia con clear:both. A su vez #izquierda y #derecha vuelven a emplear float:left
#izquierda{  
        float:left;
        }
        #maquina {
        width: 170px;
        padding:5px;
        float:left;
        }
        #humano {
        width: 170px;
        padding:5px;
        float:left;
        }
        #resultados {
        width: 340px;
        padding:10px;
        clear:both;
        }
        #derecha{
        float:left;
        width: 170px;
        padding-top:40px;
        padding-left:25px;
        }
 
De acuerdo con las recomendaciones de las normas debemos evitar el uso de <br />. Con el lineheight adecuado lo conseguimos al situar los botones de radio.
input.botones {
        width: 100px;
        display:block;
        line-height:30px;
     }
 
Completamos el diseño con los contenidos. En HTML usamos la etiqueta <fieldset> para poner marcos con o sin título (<legend>).
<div id="izquierda">
      <div id="maquina">
         <fieldset class="arriba">
           <legend>Máquina</legend>
           <img id="imagen" alt="" 
              src="imagenes/piedra.jpg" />
         </fieldset>
      </div>
      <div id="humano">
         <fieldset class="arriba">
            <legend>Humano</legend>
            <div id="divHumano">
               <span class="radio"><input type="radio" 
                  name="humanoRadio" value="piedra" 
                  checked="checked" /> Piedra</span>
               <span class="radio"><input type="radio" 
                  name="humanoRadio" value="papel" />
                  Papel</span>
               <span class="radio"><input type="radio" 
                  name="humanoRadio" value="tijera" />
                  Tijera</span>
           </div>
       </fieldset>
    </div> 
   ....
   ....   
    
 
Asimismo recuerde que debemos hacer diseños que permitan ser vistos por igual en todos los navegadores.

En cuanto al código javascript cuando queremos referenciar un elemento individual empleamos getElementById

document.getElementById("resultado").innerHTML = 
      "Gana la máquina";
 

Cuando la referencia se refiere a un grupo de etiquetas la principal alternativa es getElementsByTagName

function VisResultados()
    {
    radio=document.getElementsByTagName("input");
    if( valor == PIEDRA && radio[TIJERA].checked ||
       valor == PAPEL && radio[PIEDRA].checked ||
      valor == TIJERA && radio[PAPEL].checked)
       document.getElementById("resultado").innerHTML = 
          "Gana la máquina";
    else if (valor == PIEDRA && radio[PAPEL].checked ||
    valor == PAPEL && radio[TIJERA].checked ||
    valor == TIJERA && radio[PIEDRA].checked)
       document.getElementById("resultado").innerHTML = 
          "Gana el humano";
    else
       document.getElementById("resultado").innerHTML = 
          "Empate";
    }

 

El ejercicio hace uso de un temporizador para provocar en el usuario un mayor realismo.

A continuación presentamos el resto del código.

var PIEDRA=0;
  var PAPEL=1;
  var TIJERA=2;
  var contador,valor;
  var tmr=null;
  
  function Jugar()
   {
   contador=0;
   tmr=setInterval("CalcularJugada()",200);
   }
  
  function CalcularJugada()
   {
   document.getElementById("resultado").innerHTML="";
   valor=Math.floor(Math.random()*3);
   var imagen=document.getElementById("imagen");
   switch(valor)
   {
     case PIEDRA:
        imagen.src="imagenes/piedra.jpg";
        break;
     case PAPEL:
        imagen.src="imagenes/papel.jpg";
        break;
     case TIJERA:
        imagen.src="imagenes/tijera.jpg";
        break;
   }
   contador++;
   if (contador==20)
    {
    clearInterval(tmr);
    VisResultados();
    }  
   }
 

Para bajarse el ejercicio completo pulse aquí

sábado, 27 de marzo de 2010

Usamos :hover, position y z-index para hacer una galería fotográfica con scroll vertical

En esta ocasión vamos a comentar una demo de galería fotográfica que figura en la página de cssplay.


En ella observamos la foto seleccionada al pinchar, coger el foco o situarnos con el ratón sobre la imagen pequeña en la caja con scroll de la derecha.

Para ello vamos a construir un primer ejercicio simple que solo contenga 3 capas: la capa de “contenidos” dentro de la cual está otra capa “pequeña” que, a su vez, contiene la capa más interior llamada “grande”.
<div id="contenidos">
     <div id="pequeño">
       <div id="grande">
          <img alt="" src="Imagenes/pic2.jpg" />      
       </div> <!-- fin grande -->
     </div> <!-- fin pequeño -->
   </div> <!-- fin contenidos -->
Comenzamos añadiendo estilo para la capa de contenidos:
#contenidos {
 background-color: transparent;
 background-image: url('Imagenes/pic0.jpg');
 background-repeat: no-repeat;
 background-position: 90px 0px;
 width: 750px;
 height: 400px;
}
Con estas características confeccionamos las dimensiones de la página y situamos en la izquierda la imagen de presentación.

Continuamos con el estilo de la capa pequeña
#pequeño {
 width: 75px;
 height: 50px;
 float: right;
 background-image: url('Imagenes/pic2t.jpg');
 background-repeat: no-repeat;
 background-position: center center;
}
Ahora cargamos la imagen pequeña (pict2t.jpg) y la situamos a la derecha. Esta capa arrastra la capa grande que está contenida en la pequeña.

Usando el posicionamiento absoluto sacamos la imagen grande del campo de visión:
#grande {
 position: absolute;
 left: -9999px;
 top: 0px;
}


Finalmente ponemos estilo para dar lugar al efecto de rollback clave de la página
#pequeño:hover #grande {
 width: 500px;
 height: 350px;
 left: 90px;
 background-color: #FFFFFF;
}


Esta instrucción debe leerse como sigue:
Cuando #pequeño está en :hover ¿Qué pasa con la capa interior #grande?
Lo que pasa es que la situamos sobre la imagen de presentación.
Para poder usar la sintaxis anterior es obvio, ahora, que la capa grande tiene que ser interior a la capa pequeña, ya que de otro modo no puede construirse la orden.

Observemos ahora el código fundamental correspondiente al ejemplo completo:
<div id="holder">
 <ul id="scrollbox">
         <li><a class="slidea" href="#nogo">
           <span><img src="Imagenes/pic1.jpg"
           alt="" /><br />Los Pechos</span>
         </a></li>
  <li><a class="slideb" href="#nogo">
           <span><img src="Imagenes/pic2.jpg"
           alt="" /><br />El Teide desde Tejeda
           </span>
         </a></li>
         ...
         ...
 </ul>
</div>
Y los elementos fundamentales del estilo
#scrollbox a:active span {width:480px; 
         height:400px; top:0;  left:90px; color:#000; 
         background:#fff; z-index:1;}
      #scrollbox a:focus span {width:480px; 
         height:400px; top:0;left:90px; color:#000; 
         background:#fff; z-index:10; outline:0;}
      #scrollbox a:hover span {width:480px; 
         height:400px; left:90px; background:#fff; 
         z-index:100;}
}
Observamos que la situación es la misma del ejemplo simple con dos diferencias fundamentales:
  1. La capa pequeña es ahora una lista desordenada denominada scrollbox que tiene asignado scroll (overflow:auto) para poder visualizar todas las imágenes pequeñas.
  2. El efecto rollover se produce en tres situaciones :active,:focus y :hover
La primera situación tiene asignada z-index:1 y para poder probarla debemos tomar el foco usando la tecla TAB.
La segunda se realiza pinchando en la imagen y vemos que debido a que z-index es 10 predomina ante la opción :active
Por fin la última :hover predomina sobre las dos anteriores ya que z-index es igual a 100

Para bajarse el ejemplo pulse aquí

Por fin tengo un blog

Finalmente me he decicido a crear  un blog. No lo había hecho hasta ahora  un poco por dejadez y  por falta de tiempo; a pesar de que visito con frecuencia los de muchos colegas que trabajan en programación y me aprovecho de los conocimientos que voluntariamente comparten.


Soy docente de programación del I.E.S. El Rincón de Las Palmas de Gran Canaria y estoy realizando en la actualidad, el curso on-line de Competencia Digital que organiza la Consejería de Educación.
Después de leer y observar las posibilidades que tiene el uso de la Web 2.0 en el mundo docente me convencí de la necesidad de diseñar uno.

El próposito es utilizarlo como una herramienta más de comunicación en mis clases  y, de este modo, tener más ganas y tiempo de actualizarlo durante un largo trayecto.
El título proviene de los problemas que dan  a menudo los programas que usamos en clase. En estos momentos de desesperación es cuando yo me dirijo a mis alumnos con la frase "Algo huele a podrido en Oklahoma" –risas generales- lo que sin duda es una degeneración western de la frase del Hamlet. Pero es que cuando uno nace changa …