culebrita


Introducción

El "juego de la serpiente" (tiene varios nombres) es uno de los conceptos más simple juego de la historia, y al igual que Tetris es muy adictivo. Hay muchas variaciones de este juego escrito en Flash, y este tutorial se explica una forma de crear. Es un juego relativamente fácil de código, pero no llegan a asegurarse de que cuando se pulsan las teclas en rápida sucesión que están registrados. Esto es necesario si desea tener un control total de la serpiente en todo momento.
Voy a suponer que usted sabe por lo menos algunos de ActionScript. Si usted es un principiante algunas técnicas son probablemente nueva. En este tutorial se incluyen el almacenamiento de información en una matriz de dos dimensiones , el concepto de una cola , utilizando un detector de claves , fijar los clips de película en tiempo de ejecución y algunas otras cosas como la muy útiloperador módulo (%).

El Juego

Probablemente la versión más común del juego es la de arriba. Su objetivo es mover la serpiente y comer la mayor cantidad de "comida" bloques como sea posible. Hay sólo una cuadra de alimentos en un momento dado. Cuando el alimento se come, la serpiente crece en longitud. Si usted golpea una pared o la propia serpiente del juego ha terminado. Otras variaciones incluyen varios bloques de alimentos visibles al mismo tiempo y la capacidad de moverse a través de las paredes y aparecen de la pared de enfrente. Ambas variaciones se explican también.
Descargar snakeTutorialMX.zip (zip FLA de Flash MX, 7 Kb)
Descargar snakeGameWithHighscore.zip (archivos zip, 33 Kb)

Aplicación

¡Entremos en la aplicación del juego. Está escrito en Flash MX. El código se encuentra en el cuadro 1 (la línea de tiempo principal sólo es un fotograma). Los números de línea en el texto se refiere a los números de línea en los fragmentos de código en esta página, no en el archivo FLA..
Lo primero que debe hacer es definir algunas variables:
. 01 bloque = 8;   / / el ancho del bloque / altura en número de píxeles
. 02 gameHeight = 30; / / la altura del juego en el número de bloques
. 03 gameWidth = 45; / / el ancho de juego en el número de bloques de
04. SNAKE_BLOCK = 1; / / tiene el número que se usa para marcar bloques de serpiente en el mapa
El juego está dividido en bloques, o un patrón de cuadrícula. El tamaño de bloque variable tiene el tamaño de un bloque de píxeles. En este caso el tamaño del bloque es de 8, lo que significa que los bloques de construcción de la serpiente y la comida debe ser de 8x8 píxeles, si queremos que cada uno cubre una cuadra (en mi ejemplo y la comida bloques de 7x7 píxeles serpiente son lo que crea un borde fino alrededor de cada bloque. Se ve mejor creo).
El gameWidth y gameHeight variables tienen la dimensión del área de juego. Dado que el juego es de tamaño 45x30 bloques y cada bloque es de 8x8 píxeles, el área de juego de toda la toma (45 * 8) x (30 * 8) = 360x240 píxeles. El SNAKE_BLOCK variable se utiliza para marcar una posición en el área de juego como ocupada por la serpiente. El uso de SNAKE_BLOCK en lugar de una directa es puramente para hacer el código más legible.
La siguiente parte es la keyListener objeto. Tiene una onKeyDown método definido, que se llama cada vez que el usuario presiona una tecla:
01. keyListener = nuevos  objetos (); / / oyente clave
02. keyListener. onKeyDown = función () {
03.         var keyCode = clave . getCode (); / / obtener el código clave
04. 
05.         si (keyCode> 36 & & keyCode <41) { / / presiona las teclas de flecha (37 = izquierda, 38 =, 39 = derecha, 40 = hacia abajo) ... 06.                 si (juego. onEnterFrame ! = undefined) { / / sólo permiten movimientos si el juego está en marcha, y no se detuvo 07.                 		 si (keyCode-37! turnQueue = [0]) { / / ... y es diferente de la última tecla presionada 08.                   		 	     turnQueue. unshift (keyCode-37); / / guardar la clave (o más bien la dirección) en el turnQueue 09.               		 }
10.		     }
11.        } más  si (keyCode == 32) { / / inicio el juego si no está iniciado (32 = SPACE) 12.                 si (gameRunning!) {
13.                        startGame ();
14.                }
15.        } más  si (keyCode == 80) { / pausa / / Reanudar (80 = 'P ») 16.                 si (gameRunning) {
17.                         si (juego. onEnterFrame ) { / / hacer una pausa de 18 años.                                 eliminar juego. onEnterFrame ; o quitar principal 19 de bucle. /                                . textMC gotoAndStop (" pausa ");
20.                        } más { / / modo de pausa de la salida 21.                                juego. onEnterFrame = principal; / / inicio del bucle principal 22.                                textMC. gotoAndStop (" ocultar ");
23.                        }
24.                }
25.        }
26. };
27. clave . addListener (keyListener);
Llegamos pasado el código de la llave y guardarla en la variable local llamada keyCode (línea 3). Luego comprobamos si el código es de 37, 38, 39 o 40 (línea 5). Esa es la clave para los códigos de las teclas de flecha hacia la izquierda, arriba, derecha y hacia abajo. Si una tecla de dirección se ha presionado insertamos la prensa clave resta un 37 al principio de la matriz turnQueue . De esta manera 0-3 representa las curvas diferentes. Antes de que se añade a la cola nos aseguramos de que el cambio no está ya al principio de la cola (línea 7). No tiene sentido tener varias vueltas a la misma clase, uno tras otro en la cola.
Como se verá más adelante, una vez se tomó cada imagen desde el final de la turnQueue y que a su vez se realiza. De esta manera podemos salvar a todos los giros de este "tapón" si el jugador hace que gira más rápido que la velocidad de fotogramas. Digamos que la cola contiene: 0, 1 y 3 para agregar: 3, 0, 1. El siguiente cuadro vamos a subir (1), el marco después de que gire a la izquierda (0) y después hacia abajo (3). Si insertamos los nuevos valores en la parte delantera (unshift), entonces debemos elegir entre la parte posterior (pop). Podríamos introducirlos hasta el final (push) y luego recogerlos desde el frente (de cambio). La idea es que los valores de salir de la cola en el mismo orden en que entraron (a diferencia de una fila de personas en el pub donde algunos cortes bastardo borracho en frente de ustedes ...).
Las siguientes dos partes en el método onKeyDown por encima de asegurarse de que el juego comienza cuando el jugador presiona <espacio> y hace una pausa / reanuda cuando "P" se pulsa la tecla.
Un mouseListener objeto se define a iniciar también el juego cuando el usuario hace clic, si el juego no está funcionando. Un juego no está en ejecución desde el principio o cuando el juego sobre el texto en la pantalla.
01. mouseListener = nuevos  objetos ();
. 02 . mouseListener onMouseDown = función () {
03.         si (gameRunning!) { / / queremos ser capaces de iniciar el juego haciendo clic en
04.                startGame ();
. 05        }
06 . };
. 07 del ratón . addListener (mouseListener);
La siguiente función es la inicialización del juego. Esto se llama una vez para iniciar un nuevo juego:
. 01 función startGame () {
02.        x = int (gameWidth / 2); / / posición inicial x en el medio
03.        y = gameHeight-2;     / / a la posición inicial en la parte inferior
. 04 
. 05        xVelocity = [- 1, 0, 1, 0]; / / x la velocidad cuando se mueve la izquierda, arriba, derecha, abajo
. 06        yVelocity = [0, -1, 0, 1]; / / velocidad y cuando se mueve la izquierda, arriba, derecha, abajo
07. 
08.        map = nuevo  array (); / / crear una matriz para almacenar los alimentos y la serpiente
09.         de ( var n = 0; <gameWidth n, n + +) { / / realizar un mapa tridimensional de matriz 2
10.                mapa n [ ] = nuevo  array ();
11.        }
12. 
13.        turnQueue = nuevo  array (); / / una cola para almacenar pulsaciones de teclas (de modo que x número de pulsaciones de teclas en un fotograma se distribuyen en x número de cuadros)
14. 
15.        juego. createEmptyMovieClip (" alimentos ", 1); / / crear MC para almacenar los alimentos
16.        juego. createEmptyMovieClip (" s ", 2); / / crear MC para almacenar la serpiente
17.        scoreTextField. texto = " Puntuación : 0 "; / / tipo de salida de información puntuación de
18. 
. 19        foodCounter = 0; / / realiza un seguimiento del número de clips de película de alimentos
20.        snakeBlockCounter = 0; / / realiza un seguimiento de los bloques de la serpiente, el aumento en cada fotograma
21.        currentDirection = 1; / / tiene la dirección del movimiento (0 = izquierda, 1 = a, 2 = derecho, 3 = abajo)
22.        snakeEraseCounter = -1; / / incrementado en cada cuadro, se borra la cola de serpiente (ajuste de este a -3 se traducirá en un bloque de tres larga serpiente al principio)
23.        puntuación = 0; / / realiza un seguimiento de la puntuación de
24. 
25.        placeFood (" nuevo "); / / lugar de un bloque nuevo alimento
26. 
27.        textMC . gotoAndStop (" ocultar "); / / asegurarse de que ningún texto es visible (como el "game over")
28.        juego. onEnterFrame = principal; / / iniciar el bucle principal
29.        gameRunning = cierto ; / / bandera de decir si el juego se está ejecutando. Si es cierto que no significa necesariamente que el principal se llama (el juego podría ser una pausa)
30. }
Se define la posición de partida (la línea 2, 3) de la serpiente, y luego definir cómo la serpiente se mueve dependiendo de la dirección (línea 5, 6). Los números -1, 0, 1, 0 de la matriz xVelocity son los pasos para mover la serpiente horizontal cuando se mueve a la izquierda, arriba, derecha y abajo, respectivamente. El yVelocity define los pasos verticalmente. Puede cambiar -1 y 1 a -2 y 2 en xVelocity y yVelocity para crear un resultado interesante. La serpiente se mueve dos pasos cada fotograma, lo que da lugar a la serpiente que parece una línea de puntos.
Creamos un array llamado mapa en el que cada elemento contiene otro array (línea 11.8). Esto se conoce como una matriz de dos dimensiones. También definimos / restaurar algunas otras variables como la puntuación y establecer la dirección de movimiento a un (a).
En la línea 25 creamos un clip de la nueva película de los alimentos y colocarlo en un lugar al azar. Usted puede llamar a esto más de una vez si desea tener varios bloques de alimentos visibles al mismo tiempo.
En la línea 28 en startGame () de comenzar el bucle. La función principal será llamado una vez cada cuadro, mientras que el juego dura. Para poner fin a un juego (pausa) que dejen de llamar principal retirando el onEnterFrame evento.
El siguiente bloque de código es el núcleo del juego:
01. función main () { / / llamada en cada cuadro, si el juego se ejecuta y no es una pausa
02.         si (turnQueue. longitud > 0) { / / si tenemos un turno para llevar a cabo ...
03.                 var dir = turnQueue. pop (); / / ... escoger el siguiente turno en la cola ...
04.                 si (% dir 2 2! currentDirection =%) { / / no un giro de 180 grados (molesto para ser capaz de convertirse en la serpiente con una sola tecla)
05.                        currentDirection = dir; / / cambiar de dirección actual hasta el nuevo valor
06.                }
07.        }
08. 
09.        x + = xVelocity [currentDirection]; / / mover la posición de la serpiente en x
10.        y + = yVelocity [currentDirection]; / / mover la posición de la serpiente en y
11. 
12.         si x] (mapa [[y] gameHeight! = SNAKE_BLOCK & & x> -1 y x <y gameWidth & y> -1 & & <y & ) { / / asegurarse de que no están golpeando a la serpiente o salir del área de juego de
13.                game.s. attachMovie (" snakeMC ", snakeBlockCounter, snakeBlockCounter, { _x : x bloque *, _y : * tamaño de bloque y}); / / adjuntar un clip de bloque de películas de serpiente
14.                snakeBlockCounter + +; / / incrementar el contador de la serpiente
. 15 
16.                 si ( typeof (mapa [x] [y]) == "movieclip" ) { / / si es un no es un bloque vacío a continuación, no es un bloque de alimentación en la posición
17.                        puntuación + = 10; / / añadir puntos a la puntuación de
18.                        scoreTextField. texto = " Resultado: "+ puntaje; / / tipo de información puntuación de
19.                        snakeEraseCounter -= 5; / / hacer el serpiente no quitar la cola durante cinco bucles
20.                        placeFood (mapa [x] [y]); / / colocar el clip de película de alimentos que se hace referencia en el mapa mapa [x] [y]
21.                }
22. 
23.                [mapa x] [y] = SNAKE_BLOCK; / / posición actual del conjunto de ocupados
24. 
25.                 var = tailMC game.s] snakeEraseCounter [; / / obtiene el "último" MC según snakeEraseCounter (no existe)
26.                 si (tailMC) { / / si el bloque serpiente existe
. 27                         eliminar mapa [. tailMC _x / de bloque] [tailMC. _y / de bloque]; / / eliminar el valor de la matriz m
28.                        tailMC. removeMovieClip (); / / eliminar el MC
29 .                }
30.                snakeEraseCounter + +; / / Incremento borrar serpiente contra
31.        } más { / / GAME OVER si está en un bloque de serpiente o fuera del mapa
32.                gameOver ();
33.        }
34. }
El código anterior es probablemente la parte más compleja. Lo primero que hacemos cada fotograma es comprobar si hay alguna gira guarda en la cola (línea 2). Si la hay, tomamos el último (línea 3). Pero sólo el cambio de dirección si el cambio no es un giro de 180 grados. Es decir, no queremos ser capaces de mover mover hacia la izquierda y luego, si la derecha se presiona a la derecha directamente y por lo tanto chocan con la cola de serpiente. Por lo tanto, si la dirección actual es a la izquierda (0) queremos ser capaces de subir (1) o hacia abajo (3). Si nos estamos moviendo hacia arriba (1), queremos ser capaces de girar a la izquierda (0) o derecha (2). Como puede ver, la regla es que si la dirección actual y la nueva dirección son los dos números pares o impares, tanto entonces que es un giro de 180 grados.
El operador% calcula el saldo de un número dividido por otro número. Por lo tanto, un número par 2% devolverá 0 y un 2% número impar devolverá 1. Si % dir 2 es diferente de 2% currentDirectionentonces uno de ellos es par y el otro es impar, y que a su vez está permitido.
Después nos trasladamos a la serpiente a una nueva posición (línea 90-10). Para llegar a la nueva posición se añade un número que es -1, 0 ó 1. Que añadir depende de la dirección de serpiente.
Una vez que se han mudado a una nueva posición, nos aseguramos de que la nueva posición no contiene un bloque de serpiente y que no es fuera del área de juego (línea 12). Si esta prueba falla que llamamos gameOver (). Si es verdad, que añaden un bloque de nuevo a la serpiente "de clip de película s" en el "juego de clip de película" (línea 13-14). Nos mueve el clip de película asociado a la posición de la derecha que pasa directamente por un objeto con el derecho y los valores _x _y a la attachMovie método.
Una variación de las reglas es para hacer el movimiento de serpiente en el lado opuesto cuando está a punto de salir del área de juego. Podemos lograr esto añadiendo el siguiente código entre la línea 10 y 12:
si (x <0) { / / Mover a través de paredes
        x + = gameWidth;} más  si (x> = gameWidth) {x gameWidth -=;}
si (y <0) {y + = gameHeight;} más  si (y > = gameHeight) {y gameHeight -=;}
Si usamos el código a continuación, sólo tenemos que buscar bloques de serpiente en la sentencia if en la línea 12 ya que la única forma de perder el juego es golpear a la serpiente.
Después de haber conectado la serpiente nuevo bloque que comprobar para ver si hay una referencia a bloque los alimentos guardados en la matriz del mapa en la nueva posición (línea 16). Si lo hay, se añade 10 a la puntuación (línea 17) e imprimir la partitura en la instancia de campo de texto llamado scoreTextField (línea 18). A continuación, disminuir la snakeEraseCounter por 5, que tendrá el resultado de que la cola de serpiente no se borre los siguientes 5 marcos, lo que hará es crecer a 5 cuadras de longitud. La última cosa que hacer si un bloque se come es moverlo a una nueva posición (línea 20).
Se podría añadir estas 3 líneas después de la línea 20 para generar un bloque nuevo alimento decir que cada 300 puntos:
si (puntuación de 300% == 0) {placeFood (" nuevo "); / / lugar de un bloque nuevo alimento
 }
Después de haber comprobado la comida en la nueva posición, se debe marcar la nueva posición que hoy ocupa la serpiente (línea 23).
La última parte es para eliminar la cola con un bloque de cada cuadro (a menos que se supone que debe crecer a causa de los alimentos que consumen). Elegimos el "último" clip de película de cola (línea 25). No es siempre el último, porque digamos que el bloque de la serpiente del último número 50, y un alimento ha sido comido. Luego snakeEraseCounter será tal vez de 50 - 5 = 45 y no hay un bloque se retira. Pero si el bloque existía (línea 26) que lo quite del mapa (línea 27) y, finalmente, retire el clip de película en sí (línea 28). El snakeEraseCounter es siempre mayor en 1 (línea 30).
Dado que queremos añadir un bloque de serpiente en la parte delantera de la serpiente y quitar el de la parte de atrás, ¿por qué uno se adhieren al frente y luego quitar el uno en la parte trasera en lugar de mover el bloque de la cola al frente? Claro, usted podría hacer eso, pero cuando hice el juego de la serpiente en 1Kb llegué a la conclusión de que esta forma requiere la menor cantidad de código, y si se mueve el bloque de la cola hacia el frente que todavía tienen que adjuntar los clips de película para hacer la serpiente crecer. Con esta solución se obtiene el crecimiento de la serpiente de forma automática, con sólo compensar el snakeEraseCounter. Esta solución resuelve el problema cuando un bloque se come, mientras que la serpiente está creciendo. Digamos que comemos un bloque de alimentación y la serpiente se supone un crecimiento del 5 de longitud por cada bloque de los alimentos. Después de dos marcos, cuando la serpiente ha crecido dos bloques de 5, otro bloque que comemos alimentos. Esto debería dar lugar a la serpiente no está creciendo en los próximos 5 marcos, pero en lugar los próximos 8 marcos.
El gameOver () de abajo sólo muestra el "game over" del texto y se detiene el bucle principal:
. 01 función gameOver () {
02.        textMC. gotoAndStop (" gameOver "); / / mostrar el resultado de "game over" texto
03.         eliminar juego. onEnterFrame ; / / quit bucle principal función
. 04        gameRunning = falso ; / / el juego es ya no se ejecuta
05. }
gameOver () sólo se le llama en main () cuando llegamos a la serpiente o salir del área de juego.
La última función coloca un bloque nuevo alimento en un lugar al azar si "nuevo" se le pasa, o se mueve un bloque de alimentos existentes, si es una referencia de clip de película se pasa a la misma:
. 01 función placeFood (foodMC) {
. 02         hacer {
03.                 var = xFood al azar (gameWidth);
. 04                 var = yFood al azar (gameHeight);
05.        } mientras que (Ver mapa [xFood] [yFood]); / / mantener recoger un lugar hasta que una vacante (que no quiere poner la comida en una posición ocupada por la serpiente)
06. 
07.         si (foodMC == " nuevo ") { / / crear un clip de la nueva película de los alimentos
08.                foodMC = game.food. attachMovie (" foodMC ", foodCounter, foodCounter);
. 09                foodCounter + +;
10.        }
11. 
. 12        . foodMC _x = * xFood bloque; / / coloque los alimentos
13.        foodMC. _y = * yFood bloque; / / coloque los alimentos
14. 
15.        mapa [xFood] [yFood] = foodMC; / / guardar una referencia a este clip de película de alimentos en el mapa
16. }
Lo primero que debe hacer es encontrar una plaza libre para colocar la comida en. Esto se hace usando un do ... while (línea 2-5). Simplemente escoja una al azar coordenada x y una al azar y coordinar en el área de juego y, a continuación seguir haciéndolo siempre y cuando el lugar elegido contiene un bloque de alimentación o de la propia serpiente. De esta manera vamos a terminar con una coordenada que no está ocupada, donde podemos colocar los alimentos.
Si el "nuevo" se pasa como argumento a la función, le damos un clip de la nueva película de los alimentos en el clip de película llamada "comida".
Luego mover el clip de película de alimentos (ya sea el que crea o el que se hace referencia fue aprobada) en la ubicación que fue escogida al azar. Luego guardar una referencia a este clip de película de alimentos en la matriz del mapa.

Adición de muros a la zona de juego

Es posible que desee agregar paredes de la zona de juego. En ese caso, puede utilizar esta función:
función placeWall (x, y, tipo ) {wallMC = game.wall. attachMovie ( tipo , wallCounter, wallCounter); wallCounter + +;. wallMC _x = x * tamaño de bloque;. wallMC _y = y * tamaño de bloque; mapa [x] [y] = 1;}
Sólo tienes que pegar el código anterior en el fla.. Los argumentos de la función son: una columna de bloques, una hilera de bloques y un tipo de bloque. El tipo es una cadena, y se adjuntará el clip de película de la biblioteca con el nombre de vinculación idéntica a la del tipo.
También es necesario crear un contenedor de clip de película para las paredes y un par de cuadras de la pared. En la función startGame, agregue estas líneas:
juego. createEmptyMovieClip (" pared ", 3); / / crear MC para almacenar las paredes
 wallCounter = 0; placeWall (10, 10, " wallMC "); placeWall (11, 10," wallMC "); placeWall (12, 10 " wallMC ");
Aquí me acaba de añadir a tres cuadras de la pared. Asegúrese de que tiene un clip de película en la biblioteca con una vinculación id "wallMC" (clic derecho sobre el símbolo y seleccione Propiedades). O usted puede utilizar "snakeMC".

Agregar un gráfico diferente para la cabeza de serpiente

Hay una adición muy simples que usted puede hacer para tener la serpiente "cabeza" un aspecto diferente. En el snakeMC, agregar un nuevo marco, de modo que consta de dos marcos. En el cuadro 1 se coloca el gráfico que desea utilizar para la cabeza. En el marco 2, colocar los gráficos utilizados para el resto de la serpiente. También, coloque una acción stop () en el fotograma 2, de lo contrario la serpiente toda parpadeará.
Eso es todo. Como usted probablemente ha notado, el juego de ejemplo en la parte superior de esta página tiene una tabla de mejores puntuaciones. He decidido no incluirla en este tutorial por la razón que se requiere un script del lado del servidor escrita en asp, php o similares. Hay un montón de libros de visita libre / puntuación más alta (básicamente la misma cosa al codificar) las secuencias de comandos en otros lugares y la información disponibles sobre la manera de usarlos con Flash.
Fin Del Tutorial