inmensia |
Juegos: Arkanoid v1.0
Juan Mellado, 15 Noviembre, 2005 - 17:33
Este artículo comenta en detalle el código fuente de un remake del clásico Arkanoid, también conocido como Breakout, escrito totalmente en JavaScript. Este tutorial tiene un doble objetivo. El primer objetivo es servir de introducción a Javascript, pero no creando una guía detallada del lenguaje, sino estudiando algunas de las características del mismo y viendo las posibilidades que le ofrecen los navegadores a la hora de crear y modificar dinámicamente el contenido de una página web. El segundo objetivo es mostrar como se puede hacer de una forma rápida un juego simple como el conocido Arkanoid, explicando en detalle todo el código fuente escrito para implementarlo.
Actualización: Existe una nueva y mejorada versión 1.2
Código fuenteAl ser un programa escrito completamente en JavaScript, todo el código fuente se encuentra embebido dentro de la propia página HTML desde la que se ejecuta el juego, por lo que para acceder al mismo basta con seleccionar la opción "ver código fuente de la página" del navegador. Clases en JavaScriptEl programa utiliza una nomenclatura para las funciones de JavaScript que permite escribirlas de forma que su comportamiento se asemeje al de las clases que se utilizan en otros lenguajes de programación orientados a objetos como pueden ser Java o C++. function Class() {En este código de ejemplo, la función Class se puede interpretar como una clase que se compone de dos atributos y dos métodos. Atributos y métodos que pueden referenciarse desde fuera del ámbito de la función en la que se encuentran declarados gracias a que JavaScript utiliza variables libres en la definición de las funciones. Variables libres que se instancian dependiendo del contexto en el que se invocan. Es decir, la variable this apunta al objeto concreto desde el que se produce la llamada cuando se realiza una llamada al mismo. En lo sucesivo, en vez de hablar constantemente de funciones JavaScript, se hablará de clases, atributos y métodos con el significado habitual utilizado en los lenguajes de programación orientados a objetos. DOMEl programa utiliza DOM para cambiar dinámicamente el contenido de la página. DOM es el acrónimo de Document Object Model, y es una especificación implementada por muchos navegadores web para permitir a las funciones de JavaScript interactuar con los elementos de la página HTML en la que se encuentran. Lo que hace esta especificación es definir una forma de representar la página diviéndola en una jerarquía en forma de árbol, tomando el documento como un todo en la raíz y creando sub-árboles para cada uno de los elementos contenidos dentro de él. Gracias a este proceso de indexación se puede referenciar desde el código fuente a cualquier elemento concreto dentro de una página. DOM permite trabajar con los elementos definidos estáticamente en la página HTML en tiempo de diseño o crear nuevos elementos de forma dinámica en tiempo de ejecución. Por ejemplo, para crear un nuevo elemento de tipo div habría que escribir el siguiente código: div = document.createElement("div");Y a esta nueva división se le podría asignar los atributos que normalmente se definen en tiempo de diseño, como su id por ejemplo: div.id = "id";De forma que posteriormente se podría volver a encontrar con la siguiente función: div = document.getElementById("id");El programa utiliza el atributo innerHTML para modificar dinámicamente las páginas. innerHTML permite especificar la definición y el contenido de cualquier elemento HTML. Por ejemplo, para cambiar el texto de una división se puede utilizar el siguiente código: div.innerHTML = "text";Otras tareas en cambio el programa las realiza utilizando directamente los atributos de estilo. Ya que, por ejemplo, para establecer el ancho de un determinado elemento HTML se puede escribir simplemente: div.style.width = "20px";ProtocoloComo parte del diseño general del programa se ha adoptado el siguiente protocolo (secuencia) de llamadas a funciones:
init: Función llamada cuando se inicializa el juego
start: Función llamada cuando se inicia una partida stop: Función llamada cuando se termina una partida El objetivo de este protocolo es permitir que cada objeto realice las tareas concretas que debe realizar dependiendo del evento que provoca la llamada, y servir como base para futuras ampliaciones mediante la incorporación de nuevos eventos y funciones. ClasesEl programa se compone de las siguientes clases:
Help
Score Brick Stick Ball Board Game En el resto de secciones de este artículo se explica en detalle el código fuente de cada una de ellas. El orden en que se presentan las clases se ha elegido de forma que resulte fácil de entender el conjunto evitando tener que saltar continuamente de una clase a otra. HelpLa clase Help representa la línea de texto de la parte inferior de la ventana en la que se muestran los mensajes de ayuda. Esta clase aparece explicada en primer lugar porque en ella puede verse facilmente y de una forma práctica la implementación del protocolo que se explicó anteriormente. function Help() {El único atributo que contiene la clase es una referencia al elemento HTML que la representa. Debe ser claro que definida de esta forma sólo tiene sentido tener una instancia de esta clase, ya que si se creara más de una instancia todas ellas apuntarían al mismo elemento HTML y se sobreescribirán los mensajes las unas a las otras. this.init = function() {El método init se llama cuando se crea una instancia de la clase, y se limita a mostrar un mensaje en el que se indica que se pulse "espacio" para empezar a jugar. this.start = function() {El método start se llama cuando se inicia una partida, y se limita a mostrar un mensaje indicando que la paleta se mueve con las teclas del cursor. this.stop = function() {El método stop se llama cuando se termina la partida, y se limita a mostrar el típico mensaje de juego terminado. this.display = function(text, className) {El único método propio del que consta esta clase, aparte de los del protocolo, es display. Muestra el texto pasado como primer parámetro en la línea de mensajes. El segundo parámetro contiene una cadena con el nombre de la clase CSS con el que se debe mostrar el texto. Si el nombre de la clase se omite se toma uno por defecto. Notar que se usa el operador "||" para tomar el nombre de la clase CSS dada o un nombre por defecto. Esto es posible gracias a que en JavaScript todos los parámetros son opcionales. Los parámetros que figuran en la declaración de una función y que luego se omiten en las llamadas a la misma toman un valor undefined. Los valores undefined, al ser JavaScript un lenguaje debilmente tipado, se interpretan en función del contexto en el que aparecen, y en este caso concreto hacen que la expresión se interprete como "toma el valor dado si está definido o el valor constante opcional si no lo está". ScoreLa clase Score representa la puntuación de la partida en curso y la máxima puntuación alcanzada hasta la fecha que aparecen en la parte superior de la ventana. function Score() {La clase contiene dos atributos en los que se guardan referencias a los elementos HTML en los que se escriben las puntuaciones, y otros dos atributos en los que se guardan los valores numéricos de dichas puntuaciones. this.init = function() {Los métodos del protocolo init y start contienen el mismo código porque se tienen que realizar las mismas tareas cuando se inicializa la clase y cuando se inicia una nueva partida. Inicializan a cero el valor de la puntuación actual, cargan el valor de la puntuación máxima guardada en una cookie y muestran ambos valores por pantalla. this.stop = function() {El método stop del protocolo comprueba al finalizar una partida si la puntuación alcanzada durante la partida es mayor que la máxima puntuación actual, si lo es la actualiza y la guarda en una cookie. this.addToScore = function(points) {El método addToScore existe para que pueda ser llamado desde fuera de la clase con objeto de actualizar la puntuación de la partida en curso. this.display = function() {El método display es el encargado de mostrar la puntuación por pantalla. Realiza una llamada a displayScore, que muestra la puntuación de la partida en curso, y displayHiScore, que muestra la máxima puntuación alcanzada hasta la fecha. Los valores numéricos se formatean con el método formatScore en cadenas de texto con seis dígitos de longitud. this.saveHiScore = function() {Los métodos saveHiScore y loadHiScore se utilizan para guardar y recuperar de una cookie la máxima puntuación alcanzada hasta la fecha. Las cookies son ficheros de texto, normalmente de muy reducido tamaño, en los que se pueden guardar valores cuando un usuario visita una página con el objeto de volver a recuperarlos posteriormente cuando el usuario vuelve a visitar la misma página web. En la práctica, el contenido de una cookie no es más que una cadena de texto que contiene una lista de valores separados por el carácter ";" y a la que se puede acceder desde JavaScript a través de document.cookie. El método saveHiScore guarda en document.cookie una lista con dos valores. El primer valor es la puntuación "hiscore" y el segundo valor es la fecha de expiración de la cookie "expires". El segundo valor es necesario ya que por defecto las cookies expiran cuando se cierra la sesión del navegador con la que se está consultando la página web, y para evitarlo se cambia a un año contando desde la fecha actual. El método loadHiScore se limita a recuperar la puntuación guardada previamente en la cookie con saveHiScore. this.formatScore = function(points) {El último método de la clase es formatScore, que se encarga de convertir a texto la puntuación dada completando con ceros por la izquierda hasta tener una longitud de seis dígitos.
|