Comunidad Game Maker

Ayuda => Preguntas y respuestas => Mensaje iniciado por: venus en Septiembre 12, 2015, 05:11:16 PM

Título: Detectar una colision de dos objetos desde un tercero
Publicado por: venus en Septiembre 12, 2015, 05:11:16 PM
Pues aquí viene otro rompecabezas de colisiones. Malditas colisiones, me amargan el día.
Necesito saber si objetoA y objetoB están en contacto desde objetoC.
He probado objetoA.place_meeting(x,y,objetoB); pero nada. Me dice "variable name expected".
Me da error porque eso solo sirve para modificar variables. Puede que haya alguna forma de hacer una variable con place_meeting. Pero no la encuentro  :P
Título: Re:Detectar una colision de dos objetos desde un tercero
Publicado por: Guacusio en Septiembre 12, 2015, 09:03:57 PM
Prueba esto en el objetoC:

var contacto;
contacto=false;
with objetoA
    {
    if place_meeting(x,y,objetoB)
        contacto=true;
    }


La variable contacto indicará si hay colisión o no.
Título: Re:Detectar una colision de dos objetos desde un tercero
Publicado por: venus en Septiembre 13, 2015, 05:59:27 PM
Pues no me funciona  :(
De todas maneras voy a ser un poco mas concreto. Necesito saber si está haciendo contacto con cualquiera de sus copias. Es decir, saber si objetoB está colisionando con cualquier objetoA.
Título: Re:Detectar una colision de dos objetos desde un tercero
Publicado por: Guacusio en Septiembre 13, 2015, 06:21:45 PM
Cita de: venus en Septiembre 13, 2015, 05:59:27 PM
Pues no me funciona  :(
De todas maneras voy a ser un poco mas concreto. Necesito saber si está haciendo contacto con cualquiera de sus copias. Es decir, saber si objetoB está colisionando con cualquier objetoA.

Podrías ser aún más concreto: ¿por qué no te funciona? ¿el código reporta que hay/no hay una colisión cuando no la hay/si la hay, o te sale un error? ¿Necesitas saber si una instancia del objetoB específica hace contacto con cualquier instancia de objetoA, o te sirve cualquier instancia de objetoB?
Título: Re:Detectar una colision de dos objetos desde un tercero
Publicado por: kostra en Septiembre 13, 2015, 06:22:51 PM
Te han dado la respuesta perfecta xD copia lo que hiciste porque debería funcionar
Título: Re:Detectar una colision de dos objetos desde un tercero
Publicado por: venus en Septiembre 13, 2015, 07:36:39 PM
Es un código para saber que objetos han sido clickados. Si pinchas en uno se selecciona, y si pinchas donde no hay objetos todos se deseleccionan.


Esto es lo que tengo en objetoA.
if(mouse_check_button(mb_left)) {
  if(place_meeting(x,y,objetoB)) {
    seleccionado = true;
  } else {
    seleccionado = false;
  }
}

El problema de esto es que cuando pincho otro objeto, el que anteriormente estaba seleccionado se deselecciona.



Con lo que me ha dicho Guacusio debería de quedar así:
if(mouse_check_button(mb_left)) {
  with (objetoB) {
    if (place_meeting(x,y,objetoA)) {
      contacto=true;
    } else {
      contacto=false;
    }
  }
  if(contacto==true) {
    seleccionado = true;
  } else {
    seleccionado = false;
  }
}





Pero parece que no funciona. No me da error, simplemente el código dentro de with no parece ejecutarse. La variable contacto se queda como la he puesto en el ev. create.
Título: Re:Detectar una colision de dos objetos desde un tercero
Publicado por: kostra en Septiembre 13, 2015, 07:41:21 PM
un detalle, sabes que mouse_check_button es un GLOBAL click? :P
Título: Re:Detectar una colision de dos objetos desde un tercero
Publicado por: venus en Septiembre 13, 2015, 08:30:52 PM
No entiendo lo que intentas decirme.
Título: Re:Detectar una colision de dos objetos desde un tercero
Publicado por: kostra en Septiembre 13, 2015, 08:33:23 PM
ya me estoy liando... cuentame... cual es el objetoA, cual el objetoB, cual el objetoC, DONDE hay que clicar para que pase una cosa y DONDE para otra, dime que quieres exactamente y te lo escribo todo ahora (o resta el editable mas rapido xD)
Título: Re:Detectar una colision de dos objetos desde un tercero
Publicado por: Guacusio en Septiembre 13, 2015, 09:31:10 PM
Cita de: venus en Septiembre 13, 2015, 07:36:39 PM
Es un código para saber que objetos han sido clickados. Si pinchas en uno se selecciona, y si pinchas donde no hay objetos todos se deseleccionan.


Esto es lo que tengo en objetoA.
if(mouse_check_button(mb_left)) {
  if(place_meeting(x,y,objetoB)) {
    seleccionado = true;
  } else {
    seleccionado = false;
  }
}

El problema de esto es que cuando pincho otro objeto, el que anteriormente estaba seleccionado se deselecciona.



Con lo que me ha dicho Guacusio debería de quedar así:
if(mouse_check_button(mb_left)) {
  with (objetoB) {
    if (place_meeting(x,y,objetoA)) {
      contacto=true;
    } else {
      contacto=false;
    }
  }
  if(contacto==true) {
    seleccionado = true;
  } else {
    seleccionado = false;
  }
}





Pero parece que no funciona. No me da error, simplemente el código dentro de with no parece ejecutarse. La variable contacto se queda como la he puesto en el ev. create.

Es importante que siempre que hagas referencia a un código indiques en qué objeto y evento están. Suponiendo que ambos códigos que indicaste van en el evento step del objetoA (lo cual ya me parece extraño ya que habías hablado de hacer la comprobación de la colisión desde un objetoC), la única explicación para que la variable contacto permanezca en false es que pase necesariamente alguna de estas cosas:

-el botón izquierdo del mouse no está presionado
-no existen instancias de objetoB
-existiendo al menos una instancia de objetoB, ninguna está colisionando con alguna otra instancia de objetoA

Si quieres asegurarte de que el código dentro de with se está ejecutando (que es lo mismo que asegurarse de que exista alguna instancia de objetoB), y sólo con propósitos de depuración, puedes colocar una variable con un valor antes del with y dentro de éste cambiarlo, para luego mostrar el resultado:

var prueba=false;
with (objetoB) {
    prueba=true;
    if (place_meeting(x,y,objetoA)) {
      contacto=true;
    } else {
      contacto=false;
    }
  }
if prueba
    show_message("el with se ejecuta");
else
    show_message("el with no se ejecuta");


Otra sugerencia es que si la variable seleccionado es igual a la variable contacto, uses una sola variable para guardar el resultado en vez de duplicar la segunda, a menos que le des usos distintos más adelante. Tampoco me queda clara la necesidad de hacer el cálculo en step en vez de el evento mouse (en el que te ahorras comprobar por código si el botón del mouse está presionado); si lo haces en el evento step (que es una suposición), el código se ejecuta permanentemente mientras esté presionado el botón del mouse, lo cual puede no ser lo óptimo.

EDIT: cambié la última frase donde erróneamente dije que la variable contacto cambia a false al soltar el botón
Título: Re:Detectar una colision de dos objetos desde un tercero
Publicado por: venus en Septiembre 13, 2015, 09:37:19 PM
He hecho las comprobaciones y lo que falla es lo que va dentro de with. El objetoC no existe. Lo que quiero es que al clickar en otro objetoB no se deseleccionen los anteriores objetoB.
Voy a coger el ordenador y OS paso un archivo en gms.
Título: Re:Detectar una colision de dos objetos desde un tercero
Publicado por: kostra en Septiembre 13, 2015, 09:49:23 PM
si solo necesitas que al clickar se seleccione, por que dos objetos?? :S
Título: Re:Detectar una colision de dos objetos desde un tercero
Publicado por: venus en Septiembre 13, 2015, 10:01:59 PM
Os doy las instrucciones.
Cread 2 sprites. Da igual de que sean, pero que se vean.
Cread 2 objetos. ObjetoA y ObjetoB.
Ponedle ujn sprite a cada uno.
En ev. Create de ObjetoA poneis esto:
seleccionado = false;
En ev. Draw de ObjetoA poneis esto:
draw_self();
if(mouse_check_button(mb_left)) {
  if(place_meeting(x,y,objetoB)) {
    seleccionado = true;
  } else {
    seleccionado = false;
  }
}

if(seleccionado == true) {
  draw_circle (x,y,12,true);
}

En ev. Step de ObjetoB poneis esto:
x = mouse_x
y = mouse_y





Lo que quiero es que cuando seleccione un otro ObjetoA no se borre el círculo de los otros. Pero que si se borre cuando no pinche en ningún lado.
Título: Re:Detectar una colision de dos objetos desde un tercero
Publicado por: penumbra en Septiembre 13, 2015, 10:02:49 PM
aquí es donde se muestra la "superioridad" del evento mouse left pressed en lugar de STEP + mouse_check_button_pressed, ya que GMS tendría en cuenta la máscara del objeto B automáticamente. Obvio que se puede hacer sin este evento, pero se necesita tener más cuidado

No es nada personal, pero este post es bastante confuso en cuanto a tus explicaciones: Primero hablabas de un objeto C, que ahora ya no existe, luego cambió a
Cita de: venus en Septiembre 13, 2015, 09:37:19 PM
Lo que quiero es que al clickar en otro objetoB no se deseleccionen los anteriores objetoB.
y ahora cambia a
Cita de: venus en Septiembre 13, 2015, 10:01:59 PM
Lo que quiero es que cuando seleccione un otro ObjetoA no se borre el círculo de los otros.
Y por lo que estoy viendo en tu ejecutable, todo se puede hacer usando un único objeto. El objeto verde que sigue al ratón no es necesario  :-[
Título: Re:Detectar una colision de dos objetos desde un tercero
Publicado por: venus en Septiembre 13, 2015, 10:09:10 PM
Cita de: penumbra en Septiembre 13, 2015, 10:02:49 PM
aquí es donde se muestra la "superioridad" del evento mouse left pressed en lugar de STEP + mouse_check_button_pressed, ya que GMS tendría en cuenta la máscara del objeto B automáticamente. Obvio que se puede hacer sin este evento, pero se necesita tener más cuidado

En el original lo tengo en el evento mouse. Pero para un ejemplo no quería complicarme.
Título: Re:Detectar una colision de dos objetos desde un tercero
Publicado por: penumbra en Septiembre 13, 2015, 10:26:32 PM
Aquí dejo un ejemplo. Click en un objeto no seleccionado, lo selecciona. Click en un objeto seleccionado, lo deselecciona. Click en un espacio vacío, deselecciona todos los objetos.
http://www.mediafire.com/download/a7iktm2ay8rk9yp/selecta2.gmz
Título: Re:Detectar una colision de dos objetos desde un tercero
Publicado por: Guacusio en Septiembre 13, 2015, 10:36:16 PM
Cita de: venus en Septiembre 13, 2015, 10:01:59 PM
Os doy las instrucciones.
Cread 2 sprites. Da igual de que sean, pero que se vean.
Cread 2 objetos. ObjetoA y ObjetoB.
Ponedle ujn sprite a cada uno.
En ev. Create de ObjetoA poneis esto:
seleccionado = false;
En ev. Draw de ObjetoA poneis esto:
draw_self();
if(mouse_check_button(mb_left)) {
  if(place_meeting(x,y,objetoB)) {
    seleccionado = true;
  } else {
    seleccionado = false;
  }
}

if(seleccionado == true) {
  draw_circle (x,y,12,true);
}

En ev. Step de ObjetoB poneis esto:
x = mouse_x
y = mouse_y





Lo que quiero es que cuando seleccione un otro ObjetoA no se borre el círculo de los otros. Pero que si se borre cuando no pinche en ningún lado.

Entiendo que este es el proyecto que llevas adelante con Marth sobre el juego de la comunidad y la guerra de planetas. Por lo que recuerdo haber probado en ese juego, lo que quieres es poder seleccionar varios planetas manteniendo presionado el mouse y soltar este ataque liberando el botón del mouse. El objetoA representaría planetas y el objetoB sería el puntero del mouse. Viendo el código y los nuevos antecedentes con una muy mejorada explicación, veo que esto es lo que ocurre:

Al pasar el puntero sobre una instancia de objetoA con el botón del mouse presionado, la variable seleccionado toma el valor true en esa instancia. Al sacar el puntero del mouse del objetoA estando presionado el botón del mouse, la variable seleccionado toma el valor false porque deja de haber colisión entre objetoA y objetoB. Eso explica por qué los círculos no permanecen. Perdóname que te lo diga pero me parece que la forma en que quieres hacer esto es horrible. Probablemente en tu juego habrá varias instancias de objetoA y cada una ejecutará permanentemente ese código en el evento draw, lo que es tremendamente ineficiente. Deberías revisar la colisión de objetoA con objetoB desde objetoB, que tendrá una sola instancia y además hacerlo en el evento mouse left en vez de en draw. Creo que esto es más eficiente y sencillo:

evento create de objetoA:
seleccionado=false;

evento draw de objetoA:
draw_self();
if seleccionado
    draw_circle(x,y,12,true);


evento mouse left de objetoB:
with instance_place(x,y,objetoA)
    seleccionado=true;


evento mouse left released:
objetoA.seleccionado=false;
Título: Re:Detectar una colision de dos objetos desde un tercero
Publicado por: venus en Septiembre 14, 2015, 03:51:30 PM
Casi. Lo que busco es lo que ha dicho penumbra: "Click en un objeto no seleccionado, lo selecciona. Click en un objeto seleccionado, lo deselecciona. Click en un espacio vacío, deselecciona todos los objetos."
Prefiero reproducir el evento draw en cada planeta porque así puedo modificar colores y colocar números y texto si estar usando todo el rato el comando for u otros.
Como he comentado antes, esto es solo un ejemplo sencillo y sin optimizar. El original tiene y tendrá mas código e interacciones.
Entiendo cual es el problema. Cuando pincho fuera de objetoA la variable seleccionado toma el valor false. Por eso quiero que en vez de comprobar si objetoB hace contacto con él, que lo compruebe con cualquier objetoA.
Título: Re:Detectar una colision de dos objetos desde un tercero
Publicado por: venus en Septiembre 14, 2015, 03:59:31 PM
Pensandolo bien. Si consigo hacer que detecte cuando objetoB está colisionando con objetoA surgirán más problemas. Pues con solo pinchar uno se seleccionarían todos. Por lo tanto la clave está en saber cuando tiene que volver la variable false. A lo mejor podríamos hacer que objetoB detecte cuando no está colisionando con nada (Y el botón izquierdo del ratón ha sido presionado) y desde objetoB cambiar todas las variables seleccionado.
Perdón por hacer doble post.
Título: Re:Detectar una colision de dos objetos desde un tercero
Publicado por: kostra en Septiembre 15, 2015, 01:55:39 AM
ejemplo seleccionar con click, deseleccionar con click, deseleccionar todo con click afuera...


OBJETO SELECCIONABLE
create:
select = 0;

evento mouse_left_pressed:
if select == 0 select = 1; else select = 0;

evento global_mouse_left_pressed:
with elotroobjeto {if !place_meeting(x,y,objetoseleccionable) objetoseleccionable.select = 0;}

FIN xD

PD: Usar un objeto especialmente de puntero del mouse, es absurdo xD
Título: Re:Detectar una colision de dos objetos desde un tercero
Publicado por: venus en Septiembre 15, 2015, 04:39:55 PM
Ya lo hice ayer. Puedes ver el resultado en el hilo que está en Propuestas y soporte.
Si, es estúpido. Pero el juego es para android. Así que cuando elimine todas las funciones que hace como ratón se quedará como controlador general del mapa y permanecerá estático e invisible.
Gracias por indicármelo, kostra. Pero no hago las cosas porque si. Intento que esté lo mas optimizado posible.
Título: Re:Detectar una colision de dos objetos desde un tercero
Publicado por: kostra en Septiembre 24, 2015, 05:50:52 AM
igual sobra, puedes optimizarlo mas,suerte y a darle caña creando! :D