Problemática
Para desarrollar este juego, en primera instancia se antoja utilizar nuestra vieja amiga, la función "startDrag". Sin embargo, usted sabe que el flash no es muy exacto en colocar las piezas con esta función, y después de dos o tres jugadas, el cuadro parecerá una pintura de Picasso. Para evitar esto, necesitamos que el usuario haga un "click" en la ficha y esta de mueva, pues ya que solo se puede mover al espacio en blanco.
Funciones
Desarmando el rompecabezas, necesitamos desarrollar las siguientes funciones:
Mover una ficha:
Localiza la ficha seleccionada con el mouse
Busca Espacio Vacío
Mueve ficha
Sonido
Fin Mover una Ficha
Sin embargo, el inicio del juego presenta una serie de problemas, ya que si se mueven las fichas completamente en forma aleatoria, puede presentarse que no sea posible la solución del juego, para ello, el sistema deberá "jugar" en forma inversa para desordenar las fichas, pero con una solución posible.
La función de inicio deberá ser algo así:
Inicio
Ordena primero las fichas
Juega muchas veces
Buscar una ficha al azar
Busca espacio en Blanco
Mueve ficha
Fin Juega
Fin Inicio
Antes de entrar al detalle de cada rutina, debemos hablar sobre la metodología del juego. Sabemos que no vamos a usar la función "startDrag", en cambio utilizaremos "hitTest". Para ello, debemos establecer un ancho y largo fijos de las fichas, y jugaremos con estas distancias para saber si hay o no una ficha a lado de otra, o se tiene un espacio en blanco. En el ejemplo, esta distancia entre ficha y ficha es de 54 pixeles (usted puede jugar con el tamaño de ficha que desee).
Otra constante es el número de columnas y renglones en nuestro marco principal. Podemos iniciar con un juego de cuatro por cuatro, pero usted puede hacer una tabla más grande o más pequeña. Con estos datos, tendremos 15 fichas y un espacio en blanco, es decir, 16 casillas.
Las "fichas" serán gráficos con instancias con el nombre ficha1, ficha2,…, ficha15.
Ahora podemos codificar cada una de las rutinas Que vimos anteriormente:
Localizar ficha debajo del mouse
Desarmando el rompecabezas, necesitamos desarrollar las siguientes funciones:
Para saber cual ficha fue pulsada, las revisaremos una por una. Si hay una colisión de las coordenadas del mouse con una de nuestras fichas, ¡voila!, sabemos cual fue. La función es bastante sencilla. Si tiene dudas en el uso de la función hitTest o de las variables del mouse (_xmouse, :ymouse), puede consultar el libro de Colin Moock, o el manual de Macromedia. Note la importancia de utilizar "_root" antes para que se localice la ficha.
function fichaBajoelMouse ()
{
for (var i=1; i<=NUMFICHAS; i++)
{
if (_root["Ficha"+i].hitTest(_xmouse, _ymouse))
{
return (i);
}
}
}
Busca espacio en blanco
En esta rutina el parámetro es el número de ficha. Lo primero es copiar las coordenadas de la ficha seleccionada en variables de trabajo. Después se efectuara una validación para en cuatro sentidos: arriba, abajo, derecha e izquierda. No hay avances diagonales ni saltos.
En todos los casos, hay que verificar que la ficha seleccionada NO se encuentre en las orillas de la tabla, si no, obtendríamos un error. Esta validación se puede hacer de muchas maneras, como selecciones de colores, o por una matriz de unos y ceros, pero en este caso, lo haremos por medio de la variable anchoFicha.
Por ejemplo, si la coordenada de la ficha es mayor al ancho de la ficha, quiere decir que NO se encuentra a la orilla izquierda.
La siguiente validación es encontrar si existe una ficha en el lado izquierdo (en este caso), por lo cual restaremos el ancho de la ficha, y le enviamos la misma coordenada en las yes (ya que es una constante en el renglón). Si nos regresa que no hay ficha, entonces regresamos que el espacio vacío esta a la IZQUIERDA.
Esta rutina, como es obvio, se puede codificar de muchas formas, pero creemos que es mas clara si se regresa una cadena con la dirección en una cadena. Lo mismo aplica para las otras direcciones, solo cambia el sumarle o restarle a la coordenada correspondiente.
function buscaEspacioVacio (ficha) {
// Obtiene las coordenadas de la ficha
// Funciones llamadas
// verificaFicha, Busca la ficha
//Variables:
var fichax = _root[ficha]._x;
var fichay = _root[ficha]._y;
// Verifica espacio en blanco a la Izquierda
if (fichax > ANCHOFICHA) {
if (!verificaFicha(fichax-ANCHOFICHA, fichay)) {
return("IZQUIERDA");
}
}
// Verifica a la Derecha
if (fichax < ANCHOFICHA*NUMROW) {
if (!verificaFicha(fichax+ANCHOFICHA, fichay)) {
return("DERECHA");
}
}
// Verifica Arriba
if (fichay > ANCHOFICHA) {
if (!verificaFicha(fichax, fichay-ANCHOFICHA)) {
return("ARRIBA");
}
}
// Verifica abajo
if (fichay < ANCHOFICHA*NUMCOL) {
if (!verificaFicha(fichax, fichay+ANCHOFICHA)) {
return("ABAJO");
}
}
// Si no, regresa un NO
return("NO");
}
Verifica Ficha
Con las coordenadas ya calculadas, se verifica si alguna ficha coincide con ellas, por lo que se hace un ciclo que verifica a todas. Si ambas coordenadas coinciden, significan que SI existe una ficha con esas coordenadas. De lo contrarias se regresa un "false".
//Verifica si las coordenadas coinciden con alguna ficha
function verificaFicha (ficha_x,ficha_ y) {
// Busca en todas las 15 fichas
for (var i=1; i<=NUMFICHAS; i++) {
// Ve si la "x" es igual
if (_root["Ficha"+i]._x == ficha_x) {
// Ve si la "y" es igual
if (_root["Ficha"+i]._y == ficha_y) {
return true;
}
}
}
// Si no, regresa falso
return false;
}
En este punto ya tenemos el numero de ficha que fue pulsada, y tiene el espacio vacío a su lado. Ahora procede mover la ficha. Para ello, solo hay que cambiar una coordenada, y para ello solo hay que sumar o restar el ancho de la ficha, según sea la dirección:
A mover las fichas
// Mueve la ficha segun la direccion
function mueveFicha (ficha, direccion) {
//Mueve Arriba
if (direccion == "ARRIBA") {
_root[ficha]._y -= ANCHOFICHA;
// Mueve Abajo
} else if (direccion == "ABAJO") {
_root[ficha]._y += ANCHOFICHA;
// Mueve Izquierda
} else if (direccion == "IZQUIERDA") {
_root[ficha]._x -= ANCHOFICHA;
// Mueve Derecha
} else if (direccion == "DERECHA") {
_root[ficha]._x += ANCHOFICHA;
}
}
Por ultimo, si quiere un sonido cada vez que se mueva una ficha, debemos teclear una función con las clásicas tres instrucciones:
function sonidoFicha() {
sonido = new Sound();
sonido.attachSound("click");
sonido.start();
}
Las rutinas del inicio
Falta la rutina de inicio, donde debe "desordenar" las fichas. Esta parte puede ser un poco mas complicada
Lo primero es ordenar las fichas. Para ello utilizaremos dos simples ciclos. Esto hará que partamos de la forma clásica., de 1 al 15. Si desea otras formas mas complicadas, como la espiral, o por filas, necesitaría cambiar esta parte del código.
La siguiente parte, jugar al azar muchas tiradas (muchas = 100), es un tanto mas interesantes. Para ello seleccionamos una ficha al azar y analizamos si tiene o no el espacio en blanco a su lado.(utilizamos la función ya descrita). Si encuentra el espacio en blanco, mueve la ficha con la función ya también descrita (mueveFicha).
//Ordenas las fichas y luego las mueve al azar
function inicio () {
//Funciones llamadas
//buscaEspacioVacia, busca si esta vacio o no
//mueveFicha, mueve la fichas
// Variables:
var Fichanum = 0 //Indice
var Ficha = 0 //Tecla
var espacioVacio = "" //Espacio en blanco
// Inicia en forma consecutiva el juego
for (var x=1; x<=NUMROW; x++) {
for (var y=0; y<=(NUMCOL - 1); y++) {
ficha = x + y * NUMROW;
_root["Ficha"+ficha]._x = x * ANCHOFICHA;
_root["Ficha"+ficha]._y = y * ANCHOFICHA + ANCHOFICHA;
}
}
// Efectua 100 tiradas al azhar
for(var Fichanum=0; Fichanum<100; Fichanum++) {
do {
// Busca una ficha al azhar
ficha = "Ficha"+(random(NUMFICHAS)+1);
// Verifica si tiene a su lado el espacio en blanco
espacioVacio = buscaEspacioVacio(ficha);
// Si no tiene a su lado la ficha en blanco, continua
// buscando la ficha que se pueda mover
} while ( espacioVacio == "NO" );
// Mueve la ficha al espacio en blanco
_root.mueveFicha(ficha,buscaEspacioVacio(ficha));
}
}
Otras variaciones
Como se menciono, se puede variar este juego agregándole mas fichas, o buscando diferentes ordenes de las mismas. También se puede desarrollar una rutina que valide si se tiene o no el orden de las mismas, y cuando se finalice, activar alguna animación. Se le puede agregar un reloj para medir el tiempo, etc. Se pueden hacer tantos cambios como usted lo desee.
Flasheros del mundo, ¡unios!