rompecabezas dinamico tutorial

8
Rompecabezas Dinamico tutorial En este tutorial vamos a mirar a la construcción de un sistema para cortar una imagen en pedazos, mezclarlas alrededor, intercambiar las piezas y, finalmente, resolver el rompecabezas. Si bien esto puede sonar bastante complejo, el sistema no necesita mucho código y es muy ampliable. La premisa general para crear cada pieza de forma dinámica es utilizar una forma de la máscara para determinar el tamaño de la pieza y luego dibujar una sección específica de la imagen total. En cuanto a barajar y resolver el rompecabezas, vamos a utilizar un par de estructuras de datos para hacer todo el trabajo duro para nosotros. ¡Entremos en pleno! Construyendo el pedazo del rompecabezas Lo primero que tenemos que hacer es construir la funcionalidad pieza del rompecabezas, como todos los de nuestro otro código se afectan. Dado que queremos crear estas piezas de forma dinámica, vamos a querer mantener el tamaño y la forma separada de la imagen que estamos cortando. El fichero de trabajo suministrado viene con tres sprites, un pequeño rectángulo y un gran rectángulo que se utilizará como máscaras para crear la pieza y una imagen para el puzzle. Al construir los sprites de enmascaramiento, es importante asegurarse de que son un divisor del tamaño de la imagen del rompecabezas (como en los cortes de forma apropiada). Sólo necesitamos una sola pieza, por lo que hacemos un nuevo objeto y lo llamamos obj_PuzzlePiece. Cada pieza tendrá que dibujar su propia sección del rompecabezas total de lo que se hace fácilmente con la función draw_sprite_part. Antes de llegar a eso, sin embargo, tenemos que inicializar algunas variables. Creamos variables para: el sprite para mostrar, las coordenadas X e Y, y su anchura y altura. También estamos estableciendo una variable booleana de si se ha seleccionado o no la pieza. Todos los valores se ponen a cero ya que estaremos cambiando sobre la marcha después. Scr_Puzzle Piece Create 1 2 3 4 5 6 7 mySprite = 0 ; myX = 0 ; myY = 0 ; myWidth = 0 ; myHeight = 0 ; isSelected = false ;

Upload: merlin691

Post on 10-Jul-2016

215 views

Category:

Documents


0 download

DESCRIPTION

Como hacer un rompecabezas con Game Maker Studio

TRANSCRIPT

Page 1: Rompecabezas Dinamico Tutorial

Rompecabezas Dinamico tutorial

En este tutorial vamos a mirar a la construcción de un sistema para cortar una imagen en pedazos, mezclarlas alrededor, intercambiar las piezas y, finalmente, resolver el rompecabezas. Si bien esto puede sonar bastante complejo, el sistema no necesita mucho código y es muy ampliable. La premisa general para crear cada pieza de forma dinámica es utilizar una forma de la máscara para determinar el tamaño de la pieza y luego dibujar una sección específica de la imagen total. En cuanto a barajar y resolver el rompecabezas, vamos a utilizar un par de estructuras de datos para hacer todo el trabajo duro para nosotros. ¡Entremos en pleno!

Construyendo el pedazo del rompecabezasLo primero que tenemos que hacer es construir la funcionalidad pieza del rompecabezas, como todos los de nuestro otro código se afectan. Dado que queremos crear estas piezas de forma dinámica, vamos a querer mantener el tamaño y la forma separada de la imagen que estamos cortando. El fichero de trabajo suministrado viene con tres sprites, un pequeño rectángulo y un gran rectángulo que se utilizará como máscaras para crear la pieza y una imagen para el puzzle. Al construir los sprites de enmascaramiento, es importante asegurarse de que son un divisor del tamaño de la imagen del rompecabezas (como en los cortes de forma apropiada).

Sólo necesitamos una sola pieza, por lo que hacemos un nuevo objeto y lo llamamos obj_PuzzlePiece. Cada pieza tendrá que dibujar su propia sección del rompecabezas total de lo que se hace fácilmente con la función draw_sprite_part. Antes de llegar a eso, sin embargo, tenemos que inicializar algunas variables. Creamos variables para: el sprite para mostrar, las coordenadas X e Y, y su anchura y altura. También estamos estableciendo una variable booleana de si se ha seleccionado o no la pieza. Todos los valores se ponen a cero ya que estaremos cambiando sobre la marcha después.

Scr_Puzzle Piece Create

1234567

mySprite = 0 ; myX = 0 ; myY = 0 ; myWidth = 0 ; myHeight = 0 ;

isSelected = false ;

A continuación vamos a dibujar el sprite. Usando draw_sprite_part nos permite sacar sólo un área especificada de una imagen en lugar de dibujar la imagen entera. Los parámetros para esta función establecer la imagen que queremos mostrar, qué marco de la animación, establece las coordenadas y área de la imagen a dibujar, y, finalmente, dónde colocarla en la pantalla. De esta manera podemos tener una parte única de la imagen para cada instancia de obj_PuzzlePiece. Como se puede ver en el siguiente código, necesitamos un poco de comentarios de los usuarios de si la pieza ha sido seleccionada. Para simplificar las cosas, vamos a establecer el alfa en medio si es seleccionado. Recuerde que debe establecer el alfa de nuevo a su totalidad al final, de lo contrario todo se elaborará parcialmente transparente!

Page 2: Rompecabezas Dinamico Tutorial

Scr Puzzle Piece Draw

if (isSelected){ draw_set_alpha(0.5);}draw_sprite_part(mySprite,0, myX, myY, myWidth, myHeight, x, y);

draw_set_alpha(1.0);

Creación del rompecabezasAhora que hemos construido la pieza, podemos pasar a la creación de la propia rompecabezas. Queremos construir un sistema que tendrá una imagen, cortarla en trozos pequeños, a continuación, revolver todo y colóquelo en la pantalla. También vamos a querer guardar el orden de colocación correcta para más adelante para que podamos resolver el rompecabezas. Para esto vamos a crear un script, scr_PuzzleCreator que acepta algunos argumentos y hace todo lo que necesitamos.

Vamos a necesitar un montón de variables, la mayoría de los cuales son desechables. Pasaremos cuatro argumentos a esta secuencia de comandos: la imagen del rompecabezas, la máscara de recorte, y un desplazamiento en caso de que no queremos el rompecabezas a partir de la esquina superior izquierda de la sala. Luego creamos variables para la anchura y la altura de la imagen y la máscara. Podemos obtener los valores directamente de la fuente usando sprite_get_width y sprite_get_height. Por último, hemos creado las variables para el número de filas y columnas rompecabezas tendrá que obtenemos al dividir el tamaño de la imagen por el tamaño de la máscara.

Scr Puzzle Creator

var thePieceSprite = argument0;var thePieceMask = argument1;var puzzleOffsetX = argument2;var puzzleOffsetY = argument3;

var spriteWidth = sprite_get_width(thePieceSprite);var spriteHeight = sprite_get_height(thePieceSprite);var maskWidth = sprite_get_width(thePieceMask);var maskHeight = sprite_get_height(thePieceMask);

var puzzleRows = spriteWidth / maskWidth;var puzzleCols = spriteHeight / maskHeight;

Si eso parece un montón de variables, sólo tiene que esperar, tenemos un poco más! Queremos almacenar todas estas piezas en una estructura de datos que podemos utilizar más tarde y necesitamos algo que nos ayude a barajar el rompecabezas. Vamos a utilizar dos listas y una rejilla para esto. Una lista será mantener las piezas en su orden original, mientras que otro se utilizará para mezclar todo. La cuadrícula se utilizará para realizar un seguimiento de las coordenadas X e Y de cada pieza.Scr Puzzle creator continuaciónPuzzleCreator continued...for loop1 puzzleArray = ds_list_create ( ) ;

Page 3: Rompecabezas Dinamico Tutorial

23

puzzleShuffle = ds_list_create ( ) ; puzzleGrid = ds_grid_create ( 2 , ( puzzleRows * puzzleCols ) ) ;

Ahora estamos llegando a la parte divertida, la fabricación de todas las piezas! Vamos a necesitar dos bucles for para ir a través de cada fila y columna en el rompecabezas. Para cada sección de este rompecabezas se crea una instancia de obj_PuzzlePiece y colocarlo adecuadamente. A continuación, aplicamos el sprite y la máscara a la instancia, además establecemos las variables para las coordenadas X e Y y el tamaño que se dibuja en la pantalla. Finalmente, añadimos el id de cada pieza tanto a las listas y colocamos su posición X e Y en la red.

En este punto hemos creado todas las piezas y se almacena su información, lo único que queda por hacer es mezclar las piezas alrededor. Creamos una variable para la cantidad total de piezas del rompecabezas y luego baraja una de las listas en un orden aleatorio. A continuación, utilizamos un bucle más, pasando por la lista ahora barajado de arriba a abajo y nos movemos cada pieza una nueva ubicación en la parrilla de rompecabezas. (Para entender mejor lo que nuestra estructura de datos se parece, ver la imagen siguiente ejemplo) Por último, al final destruimos la lista arrastrando los pies, ya que ya no lo necesitamos y no queremos una pérdida de memoria.

scr_PuzzleCreator continued...shuffling

1234567891011121314151617

for ( var row = 0 ; row < puzzleRows ; row ++ ) {     for ( var col = 0 ; col < puzzleCols ; col ++ )     {         var thePiece = instance_create ( maskWidth * row , maskHeight * col , obj_PuzzlePiece ) ;         thePiece . mySprite = thePieceSprite ;         thePiece . mask_index = thePieceMask ;         thePiece . myX = maskWidth * row ;         thePiece . myY = maskHeight * col ;         thePiece . myWidth = maskWidth ;         thePiece . myHeight = maskHeight ;         ds_list_add ( puzzleArray , thePiece ) ;         ds_list_add ( puzzleShuffle , thePiece ) ;         ds_grid_set ( puzzleGrid , 0 , ds_list_size ( puzzleArray ) - 1 , thePiece . myX + puzzleOffsetX ) ;         ds_grid_set ( puzzleGrid , 1 , ds_list_size ( puzzleArray ) - 1 , thePiece . myY + puzzleOffsetY ) ;     } }

Page 4: Rompecabezas Dinamico Tutorial

123456789

totalPieces = ds_list_size ( puzzleArray ) ; ds_list_shuffle ( puzzleShuffle ) ; for ( i = 0 ; i < totalPieces ; i ++ ) {     thePiece = ds_list_find_value ( puzzleShuffle , i )     thePiece . x = ds_grid_get ( puzzleGrid , 0 , i ) ;     thePiece . y = ds_grid_get ( puzzleGrid , 1 , i ) ; } ds_list_destroy ( puzzleShuffle ) ;

Hablando de destruir nuestras estructuras de datos, debemos asegurarnos de que no nos olvidamos de nuestra red y otra lista. Debemos crear un script de limpieza que podemos llamar en algún momento si ya no necesitamos estos.

Scr C leanupscr_CleanUp

12

ds_list_destroy ( puzzleArray ) ; ds_grid_destroy ( puzzleGrid ) ;

Tenemos que probar nuestro creador rompecabezas así que vamos a crear un objeto obj_Overlord y lo utilizan para crear nuestro rompecabezas. Ya que tenemos dos máscaras entre los que elegir, ¿por qué no también aleatoriamente ella.

Scr Overlord Create

Page 5: Rompecabezas Dinamico Tutorial

2 randomMask = choose ( spr_PieceMask_Large , spr_PieceMask_Small ) ; scr_PuzzleCreator ( spr_Puzzle_Image , randomMask , 0 , 0 ) ;

Pruébelo y verá que la imagen se corta en varios trozos pequeños y en una orden clasificada. Ahora es el momento para que sea interactivo!

Antes de que realmente podemos resolver el puzzle, tenemos que ser capaces de mover las piezas alrededor. Para esto vamos a mantenerlo bastante simple y que sea un intercambio directo entre dos piezas hecho clic. Vamos a utilizar algunas variables globales para realizar un seguimiento de la primera pieza se hizo clic, que vamos a inicializar utilizando el Overlord en el inicio del juego. También utilizaremos la función Randomize para garantizar que las funciones aleatorias son verdaderamente aleatoria.

Sr Overlord Game Start

global . pieceSelected = false ; global . piece = 0 ; global . pieceX = 0 ; global . pieceY = 0 ; randomize ( ) ;

Al hacer clic en una pieza que necesitamos saber si es la primera o la segunda pieza seleccionada. Cuando es la primera pieza seleccionada, comprobamos para ver si se ha seleccionado previamente como la pieza. Esto es necesario para hacer lo que sin esta visita la primera pieza quedará seleccionado y se acaba de saltar de un lugar a otro. Si se trata de una nueva primera pieza, asignamos las variables globales para la instancia y coordenadas. También establecemos la variable local para isSelected, que utilizamos en la pieza del rompecabezas Dibuja evento para indicar la selección, y luego salir de este guión. Si la pieza pasa a ser la segunda selección, pasamos la primera pieza seleccionada a la segunda posición, y luego pasar la segunda a la primera posición. Reiniciamos las variables de selección en false y al final ejecutamos un evento definido por el usuario dentro del Overlord, antes de salir.

Puzzle Piece Lef Pressed12345678910111213

if ( ! global . pieceSelected ) {     if ( global . piece != self . id )     {         global . piece = self . id ;         global . pieceX = x ;         global . pieceY = y ;         global . pieceSelected = true ;         isSelected = true ;         exit ;     } } else {     global . piece . x = x ;     global . piece . y = y ;     x = global . pieceX ;     y = global . pieceY ;     global . piece . isSelected = false ;

Page 6: Rompecabezas Dinamico Tutorial

1415161718192021

     global . pieceSelected = false ;     with ( obj_Overlord ) { event_user ( 0 ) ; }     exit ; }

Ahora podemos mover las piezas alrededor, lo cual es bueno, pero todavía tenemos que resolver el rompecabezas. Para esto vamos a querer crear un script específicamente para esta tarea, scr_CheckForVictory. Vamos a ejecutar esta secuencia de comandos después de cada movimiento y volveremos si el enigma ha sido resuelto o no. La solución es bastante fácil de implementar como ya contiene todos los datos necesarios. Sólo tenemos que ejecutar un bucle que se ve en cada pieza, como se encuentra en la lista, y ver si las coordenadas X e Y son los mismos que los que se encuentran en la red. Si cualquier pieza se encuentra en el lugar equivocado, entonces el rompecabezas no ha sido resuelto. De lo contrario, se ha resuelto, y nos devolverá ese valor.

Check for Victory

cr_CheckForVictory

1234567891011

isVictory = false ; for ( i = 0 ; i < totalPieces ; i ++ ) {     thePiece = ds_list_find_value ( puzzleArray , i ) ;     if ( thePiece . x != ds_grid_get ( puzzleGrid , 0 , i ) || thePiece . y != ds_grid_get ( puzzleGrid , 1 , i ) )     {         return isVictory ;     } } isVictory = true ; return isVictory ;

Page 7: Rompecabezas Dinamico Tutorial

Todo lo que queda es ejecutar esta comprobación y luego hacer algo si se ha resuelto. Para este ejemplo todo lo que haremos a resolver el rompecabezas es destruir el rompecabezas, limpiar las estructuras de datos y luego crear un nuevo rompecabezas en su lugar. Vamos a ejecutar todo esto en el Overlord Otros | Definido por el usuario evento para que se pasa después de cada movimiento.

Overlord User Event

¡Allá vamos! Ahora tenemos un sistema donde podemos utilizar cualquier imagen, se trocean en pedazos cualquier tamaño que queremos, y lo mostrará en un orden aleatorio. Si un jugador reorganizar las piezas en el orden correcto, este sistema reconocerá que el éxito se ha logrado. Cubrimos cómo dibujar una parte de un sprite y se utilizó un par de diferentes estructuras de datos. Ahora es tu oportunidad de salir y construir sobre las lecciones aprendidas aquí. Quizás añadir algunos más máscaras para diferentes piezas de tamaño o cambiar cómo se mueven las piezas en el tablero. Espero poder verlo en sus juegos!

Además, he añadido un randomize línea (); a THS secuencia de comandos, de lo contrario el rompecabezas se genera siempre de la misma manera.

Hay una línea 36 en scr_PuzzleCreator que provoca el error. Dice "ds_list_copy (obj_ScreenOverlord.solveArray, puzzleShuffle);", simplemente elimine esta línea y todo funciona correctamente.