En este tutorial, aprenderá cómo crear un laberíntico sistema de navegación, que se podría aplicar a “apuntar y hacer clic”, juegos de aventuras gráficas, y los géneros más innovadores también. Este sistema fue utilizado en mi juego me mnemotécnico, un juego de memoria acción HTML5 para Android, dispositivos de Firefox OS y web. Al final de este tutorial, usted será capaz de crear cualquier estructura de laberinto, con sólo unas pocas líneas de códigos, y navegar a través de él con las flechas del teclado, clic del ratón o táctiles.

Tabla de contenidos

Requisitos

Se debe estar familiarizado con HTML, CSS, JavaScript y conceptos básicos orientados a objetos. Me va a utilizar limeJS, que es la mayoría de los marcos de juegos usados. Consulte la documentación de su
sitio web e instalarlo.

¿Qué esperar

Puede descargar los archivos del juego aquí. La carpeta raíz contiene los ficheros no compilado, que se puede abrir y leer. Tendrá que limeJS instalados si desea ejecutar ellos. También se compila la versión, en la carpeta “compilado”, que se puede ejecutar independiente en su navegador web ( “compilado” en los limeJS lingo realmente significa “minified” para que todas las dependencias están en un solo archivo JavaScript). Ahora vamos a navegar a través de los archivos y voy a explicar cómo funciona todo esto.

¿Cómo funciona?

Aquí está la lista de los archivos que vamos a utilizar:


  • direction.js
  • Level.js
  • Level_1.js
  • maze.css
  • maze.html
  • maze.js
  • Room.js

    y una breve explicación:


    1. maze.html es una vista en juego, ejecutar esto para ver el laberinto en la acción
    2. maze.js es el punto de partida del juego, algo así como el controlador principal. No, vamos a crear el Director, que la función es gestionar las pantallas del juego. Se carga la pantalla de nuestro laberinto.
    3. La pantalla laberinto es creado por la clase maze.Level_1. Todo lo que tiene que hacer es rellenar los this.rooms matriz, en el constructor, con objetos maze.Room.
    4. El resto se hará por él es la clase padre maze.Level. Sobre la base de la lista de salas, en las this.rooms matriz, se creará un laberinto y configurar navegación eventos / controles.

      Eso es todo.

      Go Let más profundo

      maze.js
      maze.start = function () {// crear director de juego para gestionar el director pantallas var = new lime.Director (document.getElementById ( ‘laberinto’), maze.size.width, maze.size.height); // crear laberinto primer nivel nivel var = new maze.Level_1 (); // en el constructor se configura el laberinto habitaciones, véase maze.Level_1 level.create clase (); // empezamos el motor para construir el laberinto director.replaceScene (nivel); // ¡enséñalo! director.setDisplayFPS (falso);} 123456789maze.start = function () {// crear director de juego para gestionar screensvardirector = newlime.Director (document.getElementById ( ‘laberinto’), maze.size.width, maze.size.height) ; // crear laberinto primera levelvarlevel = newmaze.Level_1 (); // en el constructor de configurar las salas de laberinto, ver maze.Level_1 classlevel.create (); // empezamos el motor para construir el mazedirector.replaceScene (nivel) ; // mostrar que director.setDisplayFPS (falso);!.}

      No hay nada especial aquí, sólo crear y mostrar el laberinto

      maze.Level_1.js
      / ** * @constructor * @extends {maze.Level} * / maze.Level_1 = function () {goog.base (this); this.rooms = [nuevo maze.Room ([maze.direction.UP, maze.direction.RIGHT], [0, 0]), nuevo maze.Room ([maze.direction.RIGHT, maze.direction.LEFT], [0, 1]), nuevo maze.Room ([maze.direction.LEFT], [0, 2]), nuevo maze.Room ([maze.direction.UP, maze.direction.DOWN], [1, 0 ]), nuevo maze.Room ([maze.direction.RIGHT, maze.direction.DOWN], [2, 0]), nuevo maze.Room ([maze.direction.UP, maze.direction.LEFT], [2 , 1]), nuevo maze.Room ([maze.direction.RIGHT, maze.direction.DOWN], [3, 1]), nuevo maze.Room ([maze.direction.UP, maze.direction.LEFT], [3, 2]), nuevo maze.Room ([maze.direction.UP, maze.direction.DOWN], [4, 2]), nuevo maze.Room ([maze.direction.RIGHT], [5, 0 ]), nuevo maze.Room ([maze.direction.RIGHT, maze.direction.LEFT], [5, 1]), nuevo maze.Room ([maze.direction.DOWN, maze.direction.LEFT], [5 , 2])];} 123456789101112131415161718192021 / ** * @constructor * @extends {maze.Level} * / maze.Level_1 = function () {goog.base (este); this.rooms = [newmaze.Room ([laberinto .direction.UP, maze.direction.RIGHT], [0,0]), newmaze.Room ([maze.direction.RIGH T, maze.direction.LEFT], [0,1]), newmaze.Room ([maze.direction.LEFT], [0,2]), newmaze.Room ([maze.direction.UP, maze.direction. DOWN], [1,0]), newmaze.Room ([maze.direction.RIGHT, maze.direction.DOWN], [2,0]), newmaze.Room ([maze.direction.UP, maze.direction. LEFT], [2,1]), newmaze.Room ([maze.direction.RIGHT, maze.direction.DOWN], [3,1]), newmaze.Room ([maze.direction.UP, maze.direction. LEFT], [3,2]), newmaze.Room ([maze.direction.UP, maze.direction.DOWN], [4,2]), newmaze.Room ([maze.direction.RIGHT], [5, 0]), newmaze.Room ([maze.direction.RIGHT, maze.direction.LEFT], [5,1]), newmaze.Room ([maze.direction.DOWN, maze.direction.LEFT], [5, 2])];}

      Esta es la configuración laberinto. El laberinto es un conjunto de “habitaciones”, donde vemos un solo en el momento (ver demo). Cada objeto maze.Room tiene que saber dónde está la salida (para arriba, derecha, abajo, izquierda) a otras habitaciones (primer parámetro de matriz) y su posición en el laberinto (segunda matriz de parámetros).

      direcciones Room

      Para la dirección, utilizamos enumeración maze.direction
      / ** * * Constantes para la dirección @enum {cadena} * / maze.direction = {UP: ‘arriba’, DERECHA: ‘derecho’, ABAJO: ‘abajo’, IZQUIERDA: ‘izquierda’} 12345678910 / ** * Constantes para la dirección @enum * {cadena} * / maze.direction = {UP: ‘arriba’, dERECHA: ‘derecho’, aBAJO: ‘abajo’, iZQUIERDA: ‘izquierda’}

      para que esto funcione, tener que utilizar las direcciones siempre en el mismo orden: arriba, derecha, abajo o izquierda. Así [maze.direction.LEFT, maze.direction.DOWN] no va a trabajar, pero [maze.direction.DOWN, maze.direction.LEFT] está bien. Me gusta usar enumeraciones como éste porque entonces hacer menos errores al escribir.

      Habitaciones posiciones

      Aquí está el mapa del laberinto, la letra Z:

      mapa

      Para crear esta estructura en el código, se utiliza una matriz con 2 dimensiones para la posición de habitación – el primer índice es para la fila, y el segundo para la columna. Es como que estamos construyendo la tabla con filas y columnas, de abajo hacia arriba:


      • [0, 0] medios primera fila, primera columna,
      • [0, 1] medios primera fila, segunda columna,
      • [0, 2] medios primera fila, tercera columna,
      • [1, 0] medios segunda fila, primera columna,

      • Direcciones y posiciones

        Poniendo todo junto:
        nuevo maze.Room ([maze.direction.UP, maze.direction.RIGHT], [0, 0]) significa que esta habitación tiene 2 direcciones, a arriba ya la derecha, y su posición es primera fila, primera columna. Esta es la sala laberinto de partida, la sala de abajo a la izquierda. Por defecto, la sala de partida es siempre el primer elemento de this.rooms matriz.

        El motor

        Clase maze.Level será, sobre la base de que la subclase maze.Level_1, crear el laberinto. maze.Level_1 es sólo una instalación o configuración, pero maze.Level es el motor. Vamos a ver algunos de los métodos:
        / ** * Crear laberinto. * / Maze.Level.prototype.create = function () {/ ** @type {maze.Room} * / habitación var; for (var i = 0; i & lt; this.rooms.length; i ++) {Estar = this.rooms [i]; // set imagen habitación y movimiento fuera de la habitación de la room.setFill pantalla (() room.getImage) setPosition (-1000, 0) .setSize (480, 320) .setAnchorPoint (0, 0).; si (i == 0) {// set primera habitación como productos de partida room.setPosition punto (0, 0); maze.Level.currentRoom = ambiente; } // set vecinos de habitación, por lo que podemos saber que la habitación para mostrar basa en room.setNeighbours de dirección (this.getNeighbours (habitación, i)); this.appendChild (habitación); } // Añadir this.setTouchNav de navegación clic / toque ();} 12345678910111213141516171819202122 / ** * Crear laberinto. * / Maze.Level.prototype.create = function () {/ ** @type {maze.Room} * / varroom; para (vari = 0; i & lt; this.rooms.length; i ++) {Estar = this.rooms [i]; // imagen sala de conjunto y fuera de la habitación jugada del screenroom.setFill (room.getImage ()) setPosition (-1000,0) .setSize (480320) .setAnchorPoint (0,0);. ​​si (i = = 0) {// set primera sala como iniciar pointroom.setPosition (0,0); maze.Level.currentRoom = habitación;} // set vecinos de habitación, por lo que podemos saber que la habitación para mostrar basado en directionroom.setNeighbours (esto .getNeighbours (habitación, i)); this.appendChild (habitación);} // Agregar Haga clic / tocar navigationthis.setTouchNav ();}

        Este es el lugar donde se crea laberinto. Se realiza un bucle a través de todas las habitaciones y añadirlos a la pantalla.
        / ** * Una bandera que indica si la animación habitación está en curso. * Necesitamos este movimiento para no interrumpir a otra habitación. * @Type {} bool * / maze.Level.moving = false; / ** * Mover a otra habitación en base a la dirección. * @Param {maze.direction} dirección * / maze.Level.prototype.move = función (dirección) {// cheque si la habitación tiene esta dirección y si la animación está en progreso si (goog.array.contains (maze.Level. currentRoom.directions, dirección) === false || maze.Level.moving === true) {return; } Var nextRoom = maze.Level.currentRoom.neighbours [dirección]; / ** @type {goog.math.Coordinate} * / var coordenadas; // basado en dirección, situado junto sala de posición y las coordenadas de partida donde debería interruptor de fin de animación (dirección) {case maze.direction.LEFT: nextRoom.setPosition (-maze.size.width, 0); coordinar = new goog.math.Coordinate (maze.size.width, 0); descanso; caso maze.direction.RIGHT: nextRoom.setPosition (maze.size.width, 0); coordinar = new goog.math.Coordinate (-maze.size.width, 0); descanso; caso maze.direction.UP: nextRoom.setPosition (0, -maze.size.height); coordinar = new goog.math.Coordinate (0, maze.size.height); descanso; caso maze.direction.DOWN: nextRoom.setPosition (0, maze.size.height); coordinar = new goog.math.Coordinate (0, -maze.size.height); descanso; } // mover tanto, la próxima y corriente, habitaciones // podemos ver actual de la habitación se va y la habitación de al lado está llegando moveAction var = new lime.animation.MoveBy (coordenadas) .setDuration (0,5); moveAction.addTarget (maze.Level.currentRoom); moveAction.addTarget (nextRoom); moveAction.play (); // no queremos interrumpir animación actual maze.Level.moving = true; // conjunto de eventos para saber cuando la animación está terminado // por lo que podemos definir habitación contigua a la actual y que la animación es maze.Level.moving goog.events.listen terminado (moveAction, lime.animation.Event.STOP, function () { maze.Level.moving = false; maze.Level.currentRoom = nextRoom;});} 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455 / ** * Una bandera que indica si la animación habitación está en curso. * Necesitamos este movimiento para no interrumpir a otra habitación. * @Type {} bool * / maze.Level.moving = false; / ** * Mover a otra habitación en base a la dirección. * @Param {maze.direction} dirección * / maze.Level.prototype.move = función (dirección) {// cheque si la habitación tiene esta dirección y si la animación es en progressif (goog.array.contains (maze.Level.currentRoom .directions, dirección) === false || maze.Level.moving === true) {return;} varnextRoom = maze.Level.currentRoom.neighbours [dirección]; / ** @type {goog.math.Coordinate} * / varcoordinate; // basado en dirección, situado junto sala de posición y coordenadas donde debe animación endswitch (dirección) {casemaze.direction.LEFT de partida: nextRoom.setPosition (-maze.size.width, 0); coordinar = newgoog.math .Coordinate (maze.size.width, 0); break; casemaze.direction.RIGHT: nextRoom.setPosition (maze.size.width, 0); coordinar = newgoog.math.Coordinate (-maze.size.width, 0) ; break; casemaze.direction.UP: nextRoom.setPosition (0, -maze.size.height); coordinar = newgoog.math.Coordinate (0, maze.size.height); break; casemaze.direction.DOWN: nextRoom. setPosition (0, maze.size.height); coordinar = newgoog.math.Coordinate (0, -maze.size.height); break;} // mover tanto, próximos y actuales, habitaciones // podemos ver ambiente actual va a desaparecer y la habitación de al lado es comingvarmoveAction = newlime.animation.MoveBy (coordenadas) .setDuration (0,5); moveAction.addTarget (maze.Level.currentRoom); moveAction.addTarget ( nextRoom); moveAction.play (); // no queremos interrumpir animationmaze.Level.moving actual = true; // conjunto de eventos para saber cuando la animación está terminado // por lo que podemos definir habitación contigua a la corriente y laberinto. Level.moving que la animación se finishedgoog.events.listen (moveAction, lime.animation.Event.STOP, function () {maze.Level.moving = false; maze.Level.currentRoom = nextRoom;});}

        Esta método es responsable de la animación en movimiento. Sobre la base de los vecinos de las habitaciones, se establecerá habitación de al lado y se mueven junto con la actual, por lo que tenemos una tala que nos estamos moviendo a través del laberinto.

        ¿Dónde ir ahora?

        Ahora se puede tratar de hacer su propio laberinto. Crear y poblar maze.Level_2 this.rooms matriz con maze.Room. Ok, está bien, ahora sabemos cómo crear laberinto, pero esto aún no es un juego. Nos estamos perdiendo la lógica del juego. Tal vez en un futuro, podemos añadir algunos tipos malos, monstruos o cualquier otro obstáculo para el ritmo y el juego.

        Si usted tiene alguna pregunta, puede ponerse en contacto conmigo en Twitter: @bmilakovic

        Otros LimeJS tutoriales en la Academia GameDev:

        Mensajes relacionados

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *