Julio 09, 2015, 06:42:49 PM Ultima modificación: Julio 10, 2015, 12:09:41 PM por solsticio
Hola, estoy comenzando a incursionar en game maker, y tengo interés en hacer un sencillo rompecabezas de 9 piezas, que cuando la pieza coincida con el lugar correcto esta queda fija en su lugar, con opción a cambiar las imágenes para hacerlo variado. He buscado afanosamente información en internet al respecto y los resultados han sido prácticamente nulos. Sí fuese posible realizarlo solo con códigos, seria genial, pues es de mi interés aprender a usar los script.
Desde ya les agradezco cualquier ayuda, tutorial y me encamine en esta tarea de programar juegos.
Gracias.

¿Qué forma tienen las piezas del rompecabezas? Si son cuadradas o rectangulares se podrían dividir usando surfaces, aunque lo mejor es dividirla desde antes y guardar todas las partes como sub-imágenes de un sprite. Si tienen forma repetitiva (como de "jigsaw") también se podrían recortar en surfaces usando unos srpites como máscaras de recorte, pero en este caso también es mejor recortarlas desde antes. Si tienen formas irregulares o aleatorias serían útiles las primitivas.

También falta saber cómo son los controles o la mecánica del juego. Las piezas se podrían mover entre rieles, o se podrían mover libremente, incluso rotar.

#2 Julio 10, 2015, 02:50:31 AM Ultima modificación: Julio 10, 2015, 12:08:38 PM por solsticio
Gracias por responder  y mostrar interés en ayudarme. Te explico entonces...ya tengo las piezas cortadas en photoshop , son formas de plantilla jigsaw, las tengo agrupadas en un solo sprite, con sub imágenes del 0 al 8.La room que quiero utilizar de de 1280 x 720, la razón es porque me gustaría que al inicio se mostrara la imagen completa y luego se dispersen de manera aleatoria en su entorno.Cada pieza tiene por dimension 307   x 234, haciendo un area de imagen de 793 x 580. La idea  es que al colocar la pieza en su lugar esta quede atrapada en su espacio y si no es correcta al soltarla se regresa a su lugar de origen.Es una mecánica sencilla para ser jugada por niños , de tal manera que lo que lo haría divertido serian los sonidos, y la posibilidad de poder cambiar las imágenes. Arrastrar y colocar.He leído en algunos recursos de game maker que se aplican las funciones de random y de crear una especie de cuadricula que indica el orden correcto de las piezas, pero como comprenderás, estoy empezando desde cero, y quiero entender la lógica y el procedimiento para poder utilizar el lenguaje de GML.

esta es una muestra de como son las piezas,cada pieza tiene una subimagen con efecto de sombra , para crear el efecto tridimensional cuando se agarre, se traslade y se suelte...si necesitas mas información , con gusto puedo ampliarla...y gracias nuevamente por tu solidaridad.

La versión que uso es el game maker studio

#5 Julio 10, 2015, 10:54:13 PM Ultima modificación: Julio 10, 2015, 10:57:35 PM por Clamud
Estas son mis sugerencias para el juego.

Lo primero es tener las piezas bien alineadas. Cada sub-imagen de los sprites debe tener una forma parecida a la imagen siguiente

el rectángulo interno es la forma básica de la pieza y el borde sirve para colocar las protuberancias (la mayor parte del borde queda vacía). El sprite debe tener dimensiones pares (alto y ancho), de esa forma el origen puede quedar exactamente al centro.

Al final se tendría un sprite con sub-imágenes como estas


Hay que ver qué separaciones se tienen en la rejilla (imaginaria) que contiene las piezas.

Las distancias deben ser iguales a las dimensiones del rectángulo base de las piezas, los bordes del sprite no se toman en cuenta porque se empalman.

Si hay nueve piezas, se posicionarán en nueve puntos ordenados como se muestra (el orden puede ser diferente).


Vamos a crear un nivel de prueba. Lo primero es mostrar el rompecabezas armado y después desordenarlo. Se deben crear 2 objetos; uno es el objeto pieza y el otro es el objeto controlador (los nombres quedan a tu elección).
El objeto controlador se va a encargar de crear y acomodar la piezas, en su evento Create puede ir este código
[gml]
//Inicializar variables
dx = //distancia horizontal
dy = //distancia vertical
imagen = //sprite que contiene las piezas

//Ciclos para crear las piezas
k = 0; //contador de sub-imagen
for( j=0; j<3; j++ ) //ciclo vertical
for( i=0; i<3; i++ ) //ciclo horizontal
{
    with instance_create( i*dx+x, j*dy+y, obj_pieza )
    {
        sprite_index = other.imagen;
        image_index  = other.k;
    }
    k ++;
}
[/gml]
[Pregunta si no entiendes el código]

Después se tienen que dispersar la piezas, eso puede suceder al terminar la cuenta de un temporizador, o se puede agregar un botón que disperse las piezas.
Se me ocurren dos formas de dispersar las piezas: alrededor del cuadro original o a un lado del cuadro original. Las posiciones finales pueden estar predefinidas o pueden ser aleatorias.

¿Cómo quieres hacer la dispersión?

Nos vemos luego.

Gracias Clamud por tus orientaciones, ahora con mas entusiasmo, voy a seguir de manera correcta el procedimiento,empezare nuevamente desde cero, pues tendré que ajustar las medidas para crear las dimensiones correctas, mañana tendré elaborado este primer paso, lo subiré y luego te agradecería me orientes hasta el final..nuevamente muchas gracias, pues personas como tu, nos llenas de muchas ganas de seguir adelante..
PD. Con respecto al código, J es equivalente a los puntos en dirección vertical, es decir las columnas p6,p3,p0 ; i es equivalente a las filas p0, p1,p2...
quiero interpretarlo bien para no hacer las cosas de manera mecánica y sentirme cómodo con lo que voy haciendo.Soy muy nuevo en esto y te pido comprensión y paciencia.
Saludos.

El ciclo i se repite tres veces y genera las piezas (P0,P1,P2). El ciclo j hace que el ciclo i se repita otras dos veces y entonces genera las piezas (P3,P4,P5) y después (P6,P7,P8), todas en orden.

ok, entendido, ahora estoy trabajando en el juego luego subo los primeros resultados...saludos

Hola, aquí estoy de nuevo, ya tengo el primer resultado, estoy contento pues ya salio la imagen, un poco desordenada, solo dos piezas estas juntas de manera correcta, voy a revisar el asunto de la alineación de las piezas. El detalle es que no se mueven a ningún lado, que sigue ahora, espero estar haciéndolo bien, Te adjunto imagen del resultado.Espero comentarios, gracias.

Me puse a hacer pruebas y ahora veo que obtener piezas bien alineadas es un proceso laborioso. Ahora te comento cómo lo he logrado, lo hice con GIMP, no estoy acostumbrado a usar Photoshop, seguramente se puede usar el mismo procedimiento:


  • Poner la imagen como fondo.
  • Agregar una capa con el patrón de rompecabezas, con relleno blanco y contornos negros.
  • Cambiar la mezcla de la capa a "multiplicar", así se ve la imagen de fondo y las líneas negras.
  • Después se aumenta el tamaño de lienzo para tener espacio transparente alrededor de la imagen.
  • Usar la herramienta de selección por color en la capa que tiene el dibujo de rompecabezas, y copiar la selección en una capa nueva, este paso se repite para todas las piezas.
  • Se define una rejilla cuyas líneas principales pasan por los bordes de las piezas y con líneas secundarias que pasan por el centro de las piezas
  • Con ayuda de la rejilla se recortan las capas, que contienen piezas individuales, en rectángulos del mismo tamaño.
  • Finalmente las capas se exportan como imágenes individuales.

Podemos continuar con el código para arrastrar las piezas. Se me ocurre este método: En el evento Create del controlador se declara la variable global.seleccion = noone;, esa variable contiene el id de la pieza que se arrastra. En el objeto pieza, en el evento Left Pressed se escribe lo siguiente
[gml]
global.seleccion = id;
rx = mouse_x - x;
ry = mouse_y - y;
[/gml]
Si hay varias piezas bajo el puntero, la variable global.seleccion tendrá el id de la que está encima, de esa forma se no se seleccionan varias piezas a la vez. Las variables rx,ry guardan la posición relativa de la pieza a la posición del puntero en el momento de hacer click.
En el evento Step se agrega
[gml]
if( global.seleccion == id )
{
    depth = 0;
    x = mouse_x - rx;
    y = mouse_y - ry;
}
[/gml]
Si la pieza está seleccionada la profundidad se hace cero para que esté encima de las demás piezas (su profundidad normal debería ser mayor a cero), la posición x,y se desplaza al mover el puntero.
En el evento Left Released la pieza regresa a su profundidad normal y la variable global.seleccion se reinicia
[gml]
depth = 1;
global.seleccion = noone;
[/gml]

Algo muy importante, es decidir la forma de la máscara de colisión, que sirve para detectar cuándo se hace click en la pieza. Las opciones: son usar colisión precisa, usar una elipse o usar un rectángulo. La primera no me gusta porque requiere mucho procesamiento (depende de qué tan grande sea el sprite), la segunda es mejor pero es más fácil que las máscaras se empalmen, y la tercera es la que me gusta ya que requiere el menor procesamiento y se ajusta de forma aceptable al sprite.

Lo anterior lo he agregado a un ejemplo (que está adjunto). El ejemplo también tiene un código que hace que la pieza se pegue ("snap") a la posición correcta cuando está cerca. Está en el evento Step
[gml]
else if( point_distance(x,y,xstart,ystart) < 64 )
{
    x = xstart;
    y = ystart;
}
[/gml]

Ok,gracias por tus aportes, ahora voy a la segunda parte, solo me queda una inquietud, cuando todas las piezas están colocadas, de que manera se puede avisar al usuario que las piezas están correctas e invitarlo a jugar otra vez pero con una imagen nueva y a lo mejor si se puede ampliar el desafío a 15 piezas...crees que se podría...es decir tener la opción de usar nuevas imágenes y plantillas con mas piezas. Ah, casi se me escapa...lo de desordenar las piezas con un botón que diga mezclar y las piezas se acomoden ya sea alrededor del marco en una zona especifica, todo ese movimiento para hacerlo atractivo se podría visualizar por el espectador...tal vez estoy pidiendo demasiado..pero es la emoción de mi primer juego.Te adjunto el archivo en photoshop de la imagen recortada y un enlace de como separar las piezas con photoshop.No pude enviar el archivo en Psd...solo el enlace
Saludos.
PD..luego te envío el resultado y los avances.

Hola Clamud, estoy mas que requete-contento, al fin logre mejorar la alineación de las piezas,seguí tu sugerencia, pero lo hice con photoshop ya que me es mas cómodo, y bien pues te muestro los resultados. Avance en el menú y el room del juego, con los botones sugeridos.La mecánica es mas o menos así. Cuando se entra al juego se inicia con el room del menú, donde se puede elegir la imagen y la cantidad de piezas del rompecabezas. La imagen del rompecabezas que aparece en el menú es el objeto del sprite, se me ocurre que a lo mejor si este sprite contiene varias subimagenes, con el botón se puedan cambiar. Con respecto al numero de piezas, si en vez de colocarlas ya cortadas, se pone una plantilla en negro y que el draw se encargue de crear cada segmento,...no se si estoy hablando cosas que no son , pero  a lo mejor si se lograra entonces se podrian poner varias plantillas con diferentes numero de piezas...no se si te estoy enredando.Pero la emoción que me esta dando al ver que las cosas van funcionando se me plantean un montón de posibilidades...pero que lamentablemente no tengo ni idea de como se hacen..pero bueno, retomando el caso.una vez hecha las elecciones se pincha el botón jugar que nos manda al room del juego, alli aparece ya la figura cortada, con la opcion de mezclar las veces que uno quiera las piezas del rompecabezas, hasta que se termina el juego y aparece el saludo y felicitaciones.
Un comentario mas ..como hago para que cuando calce la pieza haga plop...bueno no quiero aburrirte...
Saludos.

Todo lo que comentas es posible con GM. Los menús, los sonidos y las animaciones son relativamente fáciles de hacer, lo que es más complicado es recortar la imagen dentro del juego (sobre todo para ti que estás empezando), aunque a veces las cosas complicadas resultan sencillas al final, de todos modos necesitas estudiar un poco sobre primitivas y surfaces. Voy a pensar en un algoritmo sencillo que distribuya las piezas de forma vistosa.

Ok, gracias , estaré a la espera, para terminar el proyecto.
saludos.