Comunidad Game Maker

Ayuda => Preguntas y respuestas => Mensaje iniciado por: empardopo en Diciembre 05, 2014, 10:52:54 AM

Título: Elemento complejo
Publicado por: empardopo en Diciembre 05, 2014, 10:52:54 AM
Buenas.
Resulta que quiero crear un "elemento complejo" dotado de gráfico y barra de energía todo en uno.

Me he creado el objeto obj_enemigo al cual le he metido en principio un sprite (luego llevará más de uno y de forma aleatoria aparecería una imagen distinta) y le he puesto el valor de la energía y que se pinte en pantalla.

Me he creado un script llamado scr_creaEnemigo que contiene lo siguiente
x = argument0;
y = argument1;
numImagenObjeto = argument2;
idObjeto = instance_create(x,y,obj_enemigo);
idObjeto.index_imagen = numImagenObjeto;


Luego me he creado un objeto manejador que he llamado obj_manegador que es el único que he metido en la room y es el que se encarga de ir creando los objetos enemigos cada x tiempo.

El problema es que el primero me lo pinta bien pero a partir del segundo empiezan a aparecer cosas raras en pantalla; la barra de energía muy grande o en vertical, etc, etc.
Os dejo el ejemplo para ver si me podéis ayudar ...

Muchas gracias
Título: Re:Elemento complejo
Publicado por: empardopo en Diciembre 10, 2014, 11:24:53 AM
He dado una vueltecilla al código pero no sé donde tengo el error; supongo que será mi ignorancia con Game Maker.
¿Alguna ayudilla please del motivo por el que empieza a pintar con distintos tamaños y orientación la barra de energía?

Muchas gracias
Título: Re:Elemento complejo
Publicado por: penumbra en Diciembre 10, 2014, 12:16:27 PM
Cita de: empardopo en Diciembre 10, 2014, 11:24:53 AM
¿Alguna ayudilla please del motivo por el que empieza a pintar con distintos tamaños y orientación la barra de energía?
Eso pasa porque esa es la instrucción en DRAW del objeto enemigo:
[gml]
draw_healthbar(obj_enemigo.x,obj_enemigo.y,x+43,y-5,myHealth,c_black,c_red,c_green,0,true,true);
[/gml]
Los dos primeros parámetros dependen de x e y del enemigo, pero cuando se crea el objeto enemigo, el script le da valores aleatorios a esas variables:
script_execute(scr_creaEnemigo,xRand,yRand,numImagen);

Por eso cambia el tamaño y posición de la barra de vida. Otra cosa es que en el script tienes
idObjeto.index_imagen = numImagenObjeto;
pero creo que debería ser image_index. Me parece que por pura casualidad te funciona, porque tienes únicamente un sprite en el proyecto, y justamente a numImagen le das valor de 1, que es el índice del único sprite (internamente el índice de los sprites que maneja GM comienza en 1, si no recuerdo mal).

Por último, si en el juego va a haber más de un enemigo en pantalla (a la vez), no es recomendable usar obj_enemigo.x y obj_enemigo.y, la solución es usar
[gml]
draw_healthbar(x, y,x+43,y-5,myHealth,c_black,c_red,c_green,0,true,true);
[/gml]

(http://sia1.subirimagenes.net/img/2014/12/10/141210122451467779.gif)
Título: Re:Elemento complejo
Publicado por: empardopo en Diciembre 11, 2014, 01:33:02 PM
Penumbra, muchísimas gracias por contestar. Espero ir aprendiendo poco a poco y como siempre al pie del cañón...
Abusando nuevamente de tu generosidad una vez resuelto el primer paso he intentado avanzar un poco más...

He visto una forma de desintegrar un sprite así que he creado dos scripts
scr_desintegrarse
desintegrarse=argument0
for(i=0; i<=sprite_width; i=i+1*size)
{
for(j=0; j<=sprite_height; j=j+1*size)
{
draw_sprite_part(sprite_index,image_index,i,j,size,size,x+px[i,j],y+py[i,j])

if desintegrarse=true
{
px[i,j]-=cos(degtorad(point_direction(x+i,y+j,x+sprite_width/2,y+sprite_height/2)))*(5+random(10))
py[i,j]+=sin(degtorad(point_direction(x+i,y+j,x+sprite_width/2,y+sprite_height/2)))*(5+random(10))
}

}
}

y scr_creaCuadriculaDesintegrarse
size = argument0
for(i=0; i<=sprite_width; i=i+1*size)
{
for(j=0; j<=sprite_height; j=j+1*size)
{
px[i,j]=i
py[i,j]=j
}
}


EL nuevo objetivo es que se cree mi enemigo en pantalla (sprite + barra de energía) y que cuando pulse una tecla se desintegre.
El problema que obtengo es que cuando pulso la tecla se desintegran todos; se me ha ocurrido y además era el objetivo final hacer que cuando pulse con el botón izquierdo del ratón sobre uno de los objetos sea cuando se desintegre.
Así que me he añadido un evento mouse - Left Button a mi objeto enemigo pero no consigo que haga nada.
¿Cómo podría hacerlo?

Adjunto mi proyecto y nuevamente muchas gracias.
Título: Re:Elemento complejo
Publicado por: penumbra en Diciembre 11, 2014, 11:32:40 PM
Cita de: empardopo en Diciembre 11, 2014, 01:33:02 PM
El problema que obtengo es que cuando pulso la tecla se desintegran todos; se me ha ocurrido y además era el objetivo final hacer que cuando pulse con el botón izquierdo del ratón sobre uno de los objetos sea cuando se desintegre.
Así que me he añadido un evento mouse - Left Button a mi objeto enemigo pero no consigo que haga nada.

Lo que sucede es que en el objeto enemigo, tienes un evento de tecla Q en donde haces bom = true. Como esto está definido en el objeto enemigo, y además, en el evento DRAW se hace la explosión cuando bom == true, todas las instancias enemigas que haya en la habitación van a reaccionar a la tecla Q y dibujarán la explosión.

La solución es crear un método para seleccionar una sola instancia del objeto enemigo y aplicarle individualmente la desintegración. Está bien que hallas elegido el objeto controlador para hacer eso, pero Mouse Left Button se ejecuta constantemente mientras hagas click con el ratón, entonces, el código de ese evento se podría repetir varias veces mientras no se suelte el botón izquierdo, lo mejor es usar Mouse Left Pressed para que sólo se ejecute una vez por click

En ese evento tienes "bom = true", pero fíjate que la variable bom pertenece al objeto enemigo, así que para referirte a bom del enemigo desde el objeto controlador, la instrucción debería ser obj_enemigo.bom = true. PEEERO, este código va a ocasionar lo mismo que ya pasa, se aplica generalmente a todas las instancias del objeto enemigo. Lo que hay que hacer es obtener el identificador de la instancia donde se hace click y usar eso para ajustar la bom de esa instancia

[LEFT PRESSED] Objeto controlador
[gml]
inst = instance_place(mouse_x, mouse_y, obj_enemigo);      //Guardar el id de la instancia enemiga que coincida con la posición del mouse
if (inst != noone)
     inst.bom = true                                                          //Si la posición no estaba vacía (había instancia), cambiar bom de esa instancia a true
[/gml]
Título: Re:Elemento complejo
Publicado por: empardopo en Diciembre 12, 2014, 10:45:41 AM
Penumbra, sé que al final me mandarás al carajo pero no consigo hacer que funcione.

He probado a poner el código tanto en el objeto controlador como en el objeto enemigo y no hace nada; no sé dónde puede estar el problema.

Por probar, tengo el objeto mono al que también le he metido el evento Left pressed y cuando clico sobre él se desintegra pero tengo un problema; sólo me lo hace cuando prsiono en el centro. He cambiado las coordenadas y las he puesto como 0 0 en la edición del sprite. ¿Esto tengo que hacerlo así?

Muchas gracias

Título: Re:Elemento complejo
Publicado por: penumbra en Diciembre 12, 2014, 10:02:32 PM
Jeje, no hay problema, mas que nada, yo la he liado  :'(

No funciona porque me equivoque en esta funcion: instance_place Debería ser sustituída por instance_position(). Luego, el evento del controlador [LEFT PRESSED] está mal, debe ser GLOBAL LEFT PRESSED

Y bueno, con eso funciona, pero hay otra manera más fácil. olvídate de las funciones de arriba en el controlador, y de global left pressed. En el objeto enemigo, en lugar del evento Q PRESSED sólo tienes que cambiarlo por

[MOUSE LEFT PRESSED]
bom = true

Esto es porque los eventos left y right (no globales) funcionan en base a la máscara de colisión del objeto. Es decir, se detecta que hay un click sobre el objeto o instancia sólo si el puntero del mouse está dentro de la zona de la máscara, si se hace fuera, el evento no se lanza nunca, por lo que no hay necesidad de usar un identificador de instancia. Si se hace click en una instancia, sólo se modificará bom de esa instancia y no en los otros enemigos.  :-[

Aquí dejo las modificaciones:
http://www.mediafire.com/download/i5xx55h0nync854/ObjetoComplejo_vb.gmz (http://www.mediafire.com/download/i5xx55h0nync854/ObjetoComplejo_vb.gmz)

Lo que queda pendiente es destruír la instancia que se desintegró. Yo sólo hice que dejara de dibujarse el sprite del enemigo (el script de desintegración de MegaG dibuja un sprite adicional al sprite del enemigo). El enemigo no se debe destruír cuando bom == 0, porque el efecto de desintegración desaparecería de inmediato y no se vería, así que creo que necesitas una alarma para después de la desintegración, destruír esa instancia