Vous êtes sur la page 1sur 7

Rompecabezas Dinamico tutorial

En este tutorial vamos a mirar a la construccin 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
cdigo y es muy ampliable. La premisa general para crear cada pieza de forma dinmica es
utilizar una forma de la mscara para determinar el tamao de la pieza y luego dibujar una
seccin especfica 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 cdigo se afectan. Dado que queremos crear estas piezas de
forma dinmica, vamos a querer mantener el tamao y la forma separada de la imagen que
estamos cortando. El fichero de trabajo suministrado viene con tres sprites, un pequeo
rectngulo y un gran rectngulo que se utilizar como mscaras 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 tamao de la imagen del rompecabezas (como en los
cortes de forma apropiada).
Slo necesitamos una sola pieza, por lo que hacemos un nuevo objeto y lo
llamamos obj_PuzzlePiece. Cada pieza tendr que dibujar su propia seccin del
rompecabezas total de lo que se hace fcilmente con la funcin 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. Tambin 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 despus.
Scr_Puzzle Piece Create
1
2
3
4
5
6
7

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

A continuacin vamos a dibujar el sprite. Usando draw_sprite_part nos permite sacar slo un rea especificada de u
dibujar la imagen entera. Los parmetros para esta funcin establecer la imagen que queremos mostrar, qu marco
las coordenadas y rea de la imagen a dibujar, y, finalmente, dnde colocarla en la pantalla. De esta manera podem
la imagen para cada instancia de obj_PuzzlePiece. Como se puede ver en el siguiente cdigo, necesitamos un poco
usuarios de si la pieza ha sido seleccionada. Para simplificar las cosas, vamos a establecer el alfa en medio si es sel
debe establecer el alfa de nuevo a su totalidad al final, de lo contrario todo se elaborar parcialmente transparente

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);

Creacin del rompecabezas


Ahora que hemos construido la pieza, podemos pasar a la creacin de la propia rompecabezas. Queremos construir
imagen, cortarla en trozos pequeos, a continuacin, revolver todo y colquelo en la pantalla. Tambin vamos a que
colocacin correcta para ms adelante para que podamos resolver el rompecabezas. Para esto vamos a crear un sc
acepta algunos argumentos y hace todo lo que necesitamos.

Vamos a necesitar un montn de variables, la mayora de los cuales son desechables. Pasaremos cuatro argumento
comandos: la imagen del rompecabezas, la mscara de recorte, y un desplazamiento en caso de que no queremos
la esquina superior izquierda de la sala. Luego creamos variables para la anchura y la altura de la imagen y la msc
valores directamente de la fuente usando sprite_get_width y sprite_get_height. Por ltimo, hemos creado las variab
columnas rompecabezas tendr que obtenemos al dividir el tamao de la imagen por el tamao de la mscara.
Scr Puzzle Creator
var
var
var
var

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

var
var
var
var

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

var puzzleRows = spriteWidth / maskWidth;


var puzzleCols = spriteHeight / maskHeight;

Si eso parece un montn de variables, slo tiene que esperar, tenemos un poco ms! Queremos almacenar todas e
de datos que podemos utilizar ms tarde y necesitamos algo que nos ayude a barajar el rompecabezas. Vamos a ut
para esto. Una lista ser mantener las piezas en su orden original, mientras que otro se utilizar para mezclar todo.
para realizar un seguimiento de las coordenadas X e Y de cada pieza.
Scr Puzzle creator continuacin

PuzzleCreator continued...for loop


1 puzzleArray = ds_list_create ( ) ;

1
2
3
4
5
6
7
8
9
1
0
1
1
1
2
1
3
1
4
1
5
1
6
1
7

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

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 ) ;
}
}

Ahora estamos lle


fabricacin de tod
necesitar dos buc
cada fila y column
cada seccin de e
una instancia de o
adecuadamente.
sprite y la mscar
establecemos las
coordenadas X e Y
en la pantalla. Fin
cada pieza tanto a
posicin X e Y en

En este punto hem


se almacena su informacin, lo nico que queda por hacer es mezclar las piezas alrededor. Creamos una variable p
piezas del rompecabezas y luego baraja una de las listas en un orden aleatorio. A continuacin, utilizamos un bucle
ahora barajado de arriba a abajo y nos movemos cada pieza una nueva ubicacin en la parrilla de rompecabezas. (P
nuestra estructura de datos se parece, ver la imagen siguiente ejemplo) Por ltimo, al final destruimos la lista arras
lo necesitamos y no queremos una prdida de memoria.

scr_PuzzleCreator continued...shuffling

1
2
3
4
5
6
7
8
9

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
un script de limpieza que podemos llamar en algn momento si ya no necesitamos estos.
Scr C leanup

scr_CleanUp

ds_list_destroy ( puzzleArray ) ;
ds_grid_destroy ( puzzleGrid ) ;

1 Tenemos que probar nuestro creador rompecabezas as que vamos a crear un objeto obj_Overlord y lo utilizan pa
2 rompecabezas. Ya que tenemos dos mscaras entre los que elegir, por qu no tambin aleatoriamente ella.
Scr Overlord Create
randomMask = choose ( spr_PieceMask_Large , spr_PieceMask_Small ) ;
2
scr_PuzzleCreator ( spr_Puzzle_Image , randomMask , 0 , 0 ) ;

Prubelo y ver que la imagen se corta en varios trozos pequeos 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.
Tambin utilizaremos la funcin 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.
Tambin establecemos la variable local para isSelected, que utilizamos en la pieza del
rompecabezas Dibuja evento para indicar la seleccin, y luego salir de este guin. Si la pieza
pasa a ser la segunda seleccin, pasamos la primera pieza seleccionada a la segunda posicin,
y luego pasar la segunda a la primera posicin. Reiniciamos las variables de seleccin en false
y al final ejecutamos un evento definido por el usuario dentro del Overlord, antes de salir.
Puzzle Piece Lef Pressed
1
2
3
4
5
6 if ( ! global . pieceSelected )
7 {
8
if ( global . piece != self . id )
9
{
1
global . piece = self . id ;
0
global . pieceX = x ;
1
global . pieceY = y ;
1
global . pieceSelected = true ;
1
isSelected = true ;
2
exit ;
1
}
3 } else {
1
global . piece . x = x ;
4
global . piece . y = y ;
1
x = global . pieceX ;
5
y = global . pieceY ;
1
global . piece . isSelected = false ;
6
global . pieceSelected = false ;
1
with ( obj_Overlord ) { event_user ( 0 ) ; }
7
exit ;
1 }
8
1
9
2
0
2
1

Ahora podemos mover las piezas alrededor, lo cual es bueno, pero todava
tenemos que resolver el rompecabezas. Para esto vamos a querer crear un
script especficamente para esta tarea, scr_CheckForVictory. Vamos a ejecutar

esta secuencia de comandos despus de cada movimiento y volveremos si el


enigma ha sido resuelto o no. La solucin es bastante fcil de implementar
como ya contiene todos los datos necesarios. Slo 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

1
2
3
4
5
6
7
8
9
1
0
1
1

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 ;

Todo lo que queda es ejecutar esta comprobacin 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 despus de cada
movimiento.

Overlord User Event

All vamos! Ahora tenemos un sistema donde podemos utilizar cualquier


imagen, se trocean en pedazos cualquier tamao 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 cmo 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.
Quizs aadir algunos ms mscaras para diferentes piezas de tamao o
cambiar cmo se mueven las piezas en el tablero. Espero poder verlo en sus
juegos!

Adems, he aadido un randomize lnea (); a THS secuencia de comandos, de


lo contrario el rompecabezas se genera siempre de la misma manera.

Hay una lnea 36 en scr_PuzzleCreator que provoca el error. Dice "ds_list_copy


(obj_ScreenOverlord.solveArray, puzzleShuffle);", simplemente elimine esta
lnea y todo funciona correctamente.

Vous aimerez peut-être aussi