Problemas con collision

Started by Trecek, August 14, 2011, 09:22:30 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Trecek

Hola a todos, yo de nuevo dandoos la brasa (que raro, no?  ;D)

Os pongo en situacion:
Estoy con un proyecto de un juego de tablero (casillas cuadradas), y ahora mismo ando peleandome con el editor de pantallas. El juego es tipo espada y brujeria, y con el editor puedes poner diferentes objetos en el tablero para que se los encuentre el jugador durante la partida, como mesas, cofres, muebles diversos... y enemigos (orcos, arqueros, brujos...).

Para colocar objetos en el tablero los arrastras con el boton izq presionado, y los sueltas encima. Mientras mueves el raton encima del tablero para colocar un objeto cualquiera, el objeto automaticamente redondea su X e Y para ajustarse a las casillas del tablero. Mientras lo estas arrastrando, puedes girarlo pulsando el boton derecho.

Mi problema era que al girar los objetos usando angle estos cambiaban ligeramente de posicion, ya que su centro seguia siendo el (0,0) y esto me descuadraba otros procesos auxiliares de ese objeto, aparte de que esteticamente quedaba raro. En un principio no quise liarme con eso porque lo considere un fallo tonto, asi que guarde en el fpg el mismo grafico por cuatriplicado, cada imagen con un angulo diferente (0,90,180 y 270) por usar una solucion rapida y ponerme rapidamente a hacer otras cosas que consideraba mas interesantes pensando "bah, esto lo arreglo luego con puntos de control". Dependiendo de la orientacion deseada usaba un grafico u otro. Con este apaño lo solucione, pero claro, el fpg ocupa mucho mas de lo que debiera.

Ahora me he puesto con ese problema, y la solucion que pense de los puntos de control no me sirve, mi idea era poner un punto de control en cada esquina del grafico y dependiendo de la variable "orientacion" de ese proceso, que va de 0 a 3, variar su angulo, y  usar un punto de control u otro. El codigo queda algo asi como:

IF (ORIENTACION==0)
ANGLE=0;
GET_POINT(0,GRAFICO,0, &CONTROL_X, &CONTROL_Y );
              //punto de control 0=>superior izquierda
ELSE
IF (ORIENTACION==1)
ANGLE=90000;
GET_POINT(0,GRAFICO,1, &CONTROL_X, &CONTROL_Y );
                      //punto de control 1=>superior derecha
ELSE
IF (ORIENTACION==2)
ANGLE=180000;
GET_POINT(0,.GRAFICO,2, &CONTROL_X, &CONTROL_Y );
                               //punto de control 2=>inferior derecha
ELSE
IF (ORIENTACION==3)
ANGLE=270000;
GET_POINT(0,GRAFICO,3, &CONTROL_X, &CONTROL_Y );
                                      //punto de control 3=>inferior izquierda
END
END
END
END
SET_CENTER(0,GRAFICO,CONTROL_X,CONTROL_Y);

Este codigo me soluciona el problema, si, pero me cambia el centro a un punto de control determinado en TODOS los objetos que esten usando ese grafico (logico por otra parte ahora que lo pienso). Habria alguna forma de modificar el centro de una sola mesa sin afectar al resto de mesas iguales en la pantalla?

En caso de que no se pueda supongo que optare por modificar el angle del objeto y de sus procesos auxiliares, aunque me gusta mas como queda con la otra solucion.

Otra solucion que se me ha ocurrido es usar el centro real del grafico, que seria lo ideal pero no es factible a estas alturas. (si, tenia que haberme puesto con este problema en cuanto lo vi, no ahora que ya llevo tropocientas mil lineas de codigo  :-[ )

A alguien se le ocurre un sistema?

PD: Tengo que aprender a resumir  :-X

Trecek

#1
Acabo de guardar dos copias del fpg, una con casi todos los graficos por cuatriplicado y otra con solo un grafico de cada tipo, los he comparado y...

fpg con graficos por cuatriplicado => 28.9 mb
fpg "limpio"                                => 25.2 mb

Desde el principio estaba convencido de que ocupaba tanto por repetir tanto grafico  :P por una diferencia de menos de 4 megas en casi 30 que ocupa ni me molesto, perdonar por haceros perder el tiempo  :-[ . Tendre que mirar que coño he metido ahi que ocupe tanto, a ver si puedo optimizarlo un poco. (fijo que puedo ahorrar bastante espacio si reviso un poco)

PD: Tengo ganas de ponerlo ya en la seccion de proyectos, pero esta muy verde aun, por no hablar de que aun tengo que mirar de hacer que ocupe menos (he estado trabajando con 32 de profundidad de color basicamente porque me hacia ilusion, pero lo bajare a 16 a ver que tal). Que opinais? Pongo una version "temporal" por ahi?

Drumpi

Hay dos soluciones:
La fácil consiste en usar MAP_CLONE, de esta manera puedes cambiar el centro del gráfico sin afectar a los demás. La pega es que estás creando mapas nuevos, que ocupan memoria, que pertenecen al FILE cero, y que te tienes que acordar de descargar al finalizar la partida con UNLOAD_MAP.
La menos fácil es poner el centro en el centro real del mapa, y usar GRAPHIC_INFO para obtener el número de pixels en X y en Y que tienes que desplazar el objeto respecto a la posición donde lo quieres colocar (suponiendo que en dicha posición debe ir la esquina superior izquierda del gráfico, debería ser algo así:

Process mesa (...)
x = posicion_mapa_x + graphic_info(file,graph, G_CENTER_X);
y = posicion_mapa_y + graphic_info(file,graph, G_CENTER_Y);

Respecto a publicarlo ya, eso es tu elección. Yo prefiero esperar a tener una versión estable, para no arruinar la sorpresa y generar hype innecesario... salvo que necesite betatesting (siempre es bueno que el betatesting te lo haga otro, porque tu encontrarás muchos fallos, pero habrá muchos otros que se te pasen, y te pueden dar consejo sobre la jugabilidad).
Hala, como con 1001 procesos sólo va a 9 FPS, vamos a meterle 32 veces más, a ver si revienta.
(Drumpi epic moment)

Trecek

#3
Gracias por las soluciones Drumpi, no se cual usare, pero ambas son mejores que las posibilidades que estaba barajando. Karma ;)
La pega del map_clone no me parece problema, ya que asi practico un poco con lo de unload, que aun no lo he usado. La otra solucion que me has dado... me daria de cabezazos, yo dandole vueltas y resulta que tengo algo parecido en otros trozos del mismo juego para solucionar otro problema relacionado con la posicion de algunos graficos tambien (si es que a veces me obceco y no hay forma :S )

En cuanto a publicarlo... me da algo de verguenza poner algo "a medias", pero tengo ganas de poder mostrar algo y que lo critiqueis a gusto (no es broma, asi es como pulire los fallos). Al final creo que optare por publicar el editor de pantallas cuando esté completamente finalizado, por corregir sus fallos antes de pasar al juego propiamente dicho. De esta forma aunque lo que publique no sea el juego completo, al menos si sera un parte funcional del mismo, de hecho con unos arreglillos se podria usar como un sistema de apoyo informatico para el juego de mesa (el juego en si no es mio, es una version de un juego de hace bastantes años). Sea como sea, gracias por darme tu opinion :)

Trecek

Decidido, segunda solucion.

Al ser un juego de tablero, con una cuadricula, todos los graficos tienen el mismo ancho y alto de una casilla multiplicado por el numero de casillas que ocupa, y dado que ya tengo dos variables en todos esos procesos para almacenar su ancho y alto en casillas, las modificaciones no seran muy complicadas.
Seguire usando como centro el pixel 0,0. Solo tengo que añadir un if con las cuatro posibilidades de angle (0, 90000,180000 o 270000) y en cada una de ellas poner una linea mas que sume o reste un valor a X y/o Y igual al tamaño en pixels de una casilla multiplicado por el numero de casillas que ocupa en el eje X y/o Y. (la verdad, es mas complicado de explicar que de hacer).

Trecek

Ahora gira correctamente usando un solo grafico, pero no me detecta las colisiones con el raton a menos que el angulo sea 0  :o en fin, a revisar.

Trecek

#6
(Antes que nada, decir que he cambiado el titulo del post porque ya no trata de puntos de control, pero he decidido mantenerlo en lugar de abrir uno nuevo ya que hablo del mismo programa y problema)
Nada, que no se donde meto la pata. Tiene pinta de ser la mayor chorrada del mundo, pero yo que se, no lo veo. He modificado un proceso y ahora no me detecta colisiones.
Pongo el proceso que falla:
PROCESS DS_TOTAL(INT X_ABS, INT Y_ABS, BYTE COORD_X, BYTE COORD_Y, BYTE ORIENTACION)
PRIVATE
BYTE CONTADORX=0; //LOS USO DENTRO DEL FOR PARA ASIGNAR VALORES A LAS CASILLAS QUE OCUPA EL OBJETO
BYTE CONTADORY=0;
//INT X_ABS; //VALOR ABSOLUTO DE X SIN SUMAR VALOR RELATIVO DEBIDO AL GIRO
//INT Y_ABS; //VALOR ABSOLUTO DE Y SIN SUMAR VALOR RELATIVO DEBIDO AL GIRO
INT X_REL=0; //VALOR RELATIVO DE X DEBIDO AL GIRO
INT Y_REL=0; //VALOR RELATIVO DE Y DEBIDO AL GIRO
BYTE OCUPAX; //CASILLAS QUE OCUPA EN EL EJE X
BYTE OCUPAY; //CASILLAS QUE OCUPA EN EL EJE Y
END//PRIVATE
BEGIN
OCUPAX=OBJETO_SELECCIONADO.CASILLAS_X;
OCUPAY=OBJETO_SELECCIONADO.CASILLAS_Y;
Z=-1;GRAPH=OBJETO_SELECCIONADO.GRAFICO_DEL_FPG0;
IF (ORIENTACION==0)
ANGLE=0;
X_REL=0;
Y_REL=0;
ELSE
IF (ORIENTACION==1)
ANGLE=90000;
X_REL=0;
Y_REL=((35*(OCUPAY-1))+30);
ELSE
IF (ORIENTACION==2)
ANGLE=180000;
X_REL=((35*(OCUPAX-1))+30);
Y_REL=((35*(OCUPAY-1))+30);
ELSE
IF (ORIENTACION==3)
ANGLE=270000;
X_REL=((35*(OCUPAX-1))+30);
Y_REL=0;
END
END
END
END
TABLA_MAPA[COORD_X][COORD_Y].CASILLAS_X=OBJETO_SELECCIONADO.CASILLAS_X;
TABLA_MAPA[COORD_X][COORD_Y].CASILLAS_Y=OBJETO_SELECCIONADO.CASILLAS_Y;
TABLA_MAPA[COORD_X][COORD_Y].CASILLA_PRINCIPAL_X=COORD_X;
TABLA_MAPA[COORD_X][COORD_Y].CASILLA_PRINCIPAL_Y=COORD_Y;
TABLA_MAPA[COORD_X][COORD_Y].OCUPADO=1;
TABLA_MAPA[COORD_X][COORD_Y].NOMBRE_OBJETO1=OBJETO_SELECCIONADO.NOMBRE_OBJETO1;
TABLA_MAPA[COORD_X][COORD_Y].NOMBRE_OBJETO2=OBJETO_SELECCIONADO.NOMBRE_OBJETO2;
TABLA_MAPA[COORD_X][COORD_Y].TIPO_OBJETO=OBJETO_SELECCIONADO.TIPO_OBJETO;
TABLA_MAPA[COORD_X][COORD_Y].ID_OBJETO=ID;
TABLA_MAPA[COORD_X][COORD_Y].ORIENTACION=ORIENTACION;
TABLA_MAPA[COORD_X][COORD_Y].CATEGORIA=OBJETO_SELECCIONADO.CATEGORIA;
TABLA_MAPA[COORD_X][COORD_Y].AÑO=OBJETO_SELECCIONADO.AÑO;
TABLA_MAPA[COORD_X][COORD_Y].RAZA=OBJETO_SELECCIONADO.RAZA;
TABLA_MAPA[COORD_X][COORD_Y].TIPO=OBJETO_SELECCIONADO.TIPO;
TABLA_MAPA[COORD_X][COORD_Y].PROFESION=OBJETO_SELECCIONADO.PROFESION;
TABLA_MAPA[COORD_X][COORD_Y].MOVIMIENTO=OBJETO_SELECCIONADO.MOVIMIENTO;
TABLA_MAPA[COORD_X][COORD_Y].ATAQUE_NORMAL=OBJETO_SELECCIONADO.ATAQUE_NORMAL;
TABLA_MAPA[COORD_X][COORD_Y].ACIERTO_SIN_ARMAS=OBJETO_SELECCIONADO.ACIERTO_SIN_ARMAS;
TABLA_MAPA[COORD_X][COORD_Y].SEGUNDO_ATAQUE=OBJETO_SELECCIONADO.SEGUNDO_ATAQUE;
TABLA_MAPA[COORD_X][COORD_Y].ATAQUE_DIAGONAL=OBJETO_SELECCIONADO.ATAQUE_DIAGONAL;
TABLA_MAPA[COORD_X][COORD_Y].ATAQUE_DISTAN=OBJETO_SELECCIONADO.ATAQUE_DISTAN;
TABLA_MAPA[COORD_X][COORD_Y].DEFENSA=OBJETO_SELECCIONADO.DEFENSA;
TABLA_MAPA[COORD_X][COORD_Y].CUERPO=OBJETO_SELECCIONADO.CUERPO;
TABLA_MAPA[COORD_X][COORD_Y].MENTE=OBJETO_SELECCIONADO.MENTE;
TABLA_MAPA[COORD_X][COORD_Y].HABILIDAD1=OBJETO_SELECCIONADO.HABILIDAD1;
TABLA_MAPA[COORD_X][COORD_Y].HABILIDAD2=OBJETO_SELECCIONADO.HABILIDAD2;
TABLA_MAPA[COORD_X][COORD_Y].INVULNERAB=OBJETO_SELECCIONADO.INVULNERAB;
TABLA_MAPA[COORD_X][COORD_Y].EXCEP_INVULN=OBJETO_SELECCIONADO.EXCEP_INVULN;
TABLA_MAPA[COORD_X][COORD_Y].GRAFICO_DEL_FPG0=OBJETO_SELECCIONADO.GRAFICO_DEL_FPG0;
TABLA_MAPA[COORD_X][COORD_Y].GRAFICO_DEL_FPG90=OBJETO_SELECCIONADO.GRAFICO_DEL_FPG90;
TABLA_MAPA[COORD_X][COORD_Y].GRAFICO_DEL_FPG180=OBJETO_SELECCIONADO.GRAFICO_DEL_FPG180;
TABLA_MAPA[COORD_X][COORD_Y].GRAFICO_DEL_FPG270=OBJETO_SELECCIONADO.GRAFICO_DEL_FPG270;

//ESTOS FOR ESTAN PENSADOS PARA CASILLAS_X Y CASILLAS_Y MAYORES DE CERO (LA LOGICA DE ESTO ES QUE
//UN OBJETO NO PUEDE OCUPAR CERO CASILLAS DE ANCHO NI DE ALTO)
//relleno las casillas que ocupa el objeto en el mapa (excepto la casilla principal) con todos
//sus datos a cero excepto CASILLA_PRINCIPAL_X, CASILLA_PRINCIPAL_Y y OCUPADO.
FOR (CONTADORX=0;CONTADORX < TABLA_MAPA[COORD_X][COORD_Y].CASILLAS_X;CONTADORX=CONTADORX+1)

FOR (CONTADORY=0;CONTADORY < TABLA_MAPA[COORD_X][COORD_Y].CASILLAS_Y;CONTADORY=CONTADORY+1)

IF ((CONTADORX==0)AND(CONTADORY==0))

//SI CONTADORX=0 Y CONTADORY=0, ENTONCES ESTAMOS APUNTANDO A LA CASILLA PRINCIPAL,
//LA CUAL NO DEBE SER CAMBIADA. NO HACEMOS NADA
ELSE//IF ((CONTADORX==0)AND(CONTADORY==0))
//DATOS
TABLA_MAPA[((COORD_X)+(CONTADORX*2))][((COORD_Y)+(CONTADORY*2))].CASILLA_PRINCIPAL_X=COORD_X;
TABLA_MAPA[((COORD_X)+(CONTADORX*2))][((COORD_Y)+(CONTADORY*2))].CASILLA_PRINCIPAL_Y=COORD_Y;
TABLA_MAPA[((COORD_X)+(CONTADORX*2))][((COORD_Y)+(CONTADORY*2))].OCUPADO=1;
//A CERO
TABLA_MAPA[((COORD_X)+(CONTADORX*2))][((COORD_Y)+(CONTADORY*2))].ID_OBJETO=0;
TABLA_MAPA[((COORD_X)+(CONTADORX*2))][((COORD_Y)+(CONTADORY*2))].CATEGORIA=0;
TABLA_MAPA[((COORD_X)+(CONTADORX*2))][((COORD_Y)+(CONTADORY*2))].AÑO=0;
TABLA_MAPA[((COORD_X)+(CONTADORX*2))][((COORD_Y)+(CONTADORY*2))].CASILLAS_X=0;
TABLA_MAPA[((COORD_X)+(CONTADORX*2))][((COORD_Y)+(CONTADORY*2))].CASILLAS_Y=0;
TABLA_MAPA[((COORD_X)+(CONTADORX*2))][((COORD_Y)+(CONTADORY*2))].NOMBRE_OBJETO1=" ";
TABLA_MAPA[((COORD_X)+(CONTADORX*2))][((COORD_Y)+(CONTADORY*2))].NOMBRE_OBJETO2=" ";
TABLA_MAPA[((COORD_X)+(CONTADORX*2))][((COORD_Y)+(CONTADORY*2))].TIPO_OBJETO=" ";
TABLA_MAPA[((COORD_X)+(CONTADORX*2))][((COORD_Y)+(CONTADORY*2))].RAZA=" ";
TABLA_MAPA[((COORD_X)+(CONTADORX*2))][((COORD_Y)+(CONTADORY*2))].TIPO=" ";
TABLA_MAPA[((COORD_X)+(CONTADORX*2))][((COORD_Y)+(CONTADORY*2))].PROFESION=" ";
TABLA_MAPA[((COORD_X)+(CONTADORX*2))][((COORD_Y)+(CONTADORY*2))].MOVIMIENTO=0;
TABLA_MAPA[((COORD_X)+(CONTADORX*2))][((COORD_Y)+(CONTADORY*2))].ATAQUE_NORMAL=0;
TABLA_MAPA[((COORD_X)+(CONTADORX*2))][((COORD_Y)+(CONTADORY*2))].ACIERTO_SIN_ARMAS=0;
TABLA_MAPA[((COORD_X)+(CONTADORX*2))][((COORD_Y)+(CONTADORY*2))].SEGUNDO_ATAQUE=0;
TABLA_MAPA[((COORD_X)+(CONTADORX*2))][((COORD_Y)+(CONTADORY*2))].ATAQUE_DIAGONAL=0;
TABLA_MAPA[((COORD_X)+(CONTADORX*2))][((COORD_Y)+(CONTADORY*2))].ATAQUE_DISTAN=0;
TABLA_MAPA[((COORD_X)+(CONTADORX*2))][((COORD_Y)+(CONTADORY*2))].DEFENSA=0;
TABLA_MAPA[((COORD_X)+(CONTADORX*2))][((COORD_Y)+(CONTADORY*2))].CUERPO=0;
TABLA_MAPA[((COORD_X)+(CONTADORX*2))][((COORD_Y)+(CONTADORY*2))].MENTE=0;
TABLA_MAPA[((COORD_X)+(CONTADORX*2))][((COORD_Y)+(CONTADORY*2))].HABILIDAD1=0;
TABLA_MAPA[((COORD_X)+(CONTADORX*2))][((COORD_Y)+(CONTADORY*2))].HABILIDAD2=0;
TABLA_MAPA[((COORD_X)+(CONTADORX*2))][((COORD_Y)+(CONTADORY*2))].INVULNERAB=0;
TABLA_MAPA[((COORD_X)+(CONTADORX*2))][((COORD_Y)+(CONTADORY*2))].EXCEP_INVULN=0;
TABLA_MAPA[((COORD_X)+(CONTADORX*2))][((COORD_Y)+(CONTADORY*2))].GRAFICO_DEL_FPG0=0;
TABLA_MAPA[((COORD_X)+(CONTADORX*2))][((COORD_Y)+(CONTADORY*2))].GRAFICO_DEL_FPG90=0;
TABLA_MAPA[((COORD_X)+(CONTADORX*2))][((COORD_Y)+(CONTADORY*2))].GRAFICO_DEL_FPG180=0;
TABLA_MAPA[((COORD_X)+(CONTADORX*2))][((COORD_Y)+(CONTADORY*2))].GRAFICO_DEL_FPG270=0;
TABLA_MAPA[((COORD_X)+(CONTADORX*2))][((COORD_Y)+(CONTADORY*2))].ORIENTACION=0;
END//IF ((CONTADORX==0)AND(CONTADORY==0))
END//FOR
END//FOR
X=X_ABS+X_REL;
Y=Y_ABS+Y_REL;
frame;
WHILE (((X_ABS)>18) AND ((X_ABS)<1069) AND ((Y_ABS)<821) AND ((Y_ABS)>15)AND(!(ESTADO_DISEÑO==999)))
X=X_ABS+X_REL;
Y=Y_ABS+Y_REL;
FRAME;
IF ((COLLISION(TYPE PIXEL_RATON))AND(MOUSE.RIGHT)AND(ESTADO_MENU_DERECHO==0))
ESTADO_MENU_DERECHO=1;
NOMBRE_MENUDERECHO(ID, TABLA_MAPA[COORD_X][COORD_Y].NOMBRE_OBJETO1,TABLA_MAPA[COORD_X][COORD_Y].NOMBRE_OBJETO2,X_ABS,Y_ABS);
ELSE
END//IF
END //WHILE
END//BEGIN


Este proceso lo que hace es poner un objeto en el tablero de juego (estoy haciendo un editor de pantallas). Tabla_mapa y Objeto_seleccionado son structs, actualizo tabla_mapa con este proceso, dependiendo de lo que contenga Objeto_seleccionado (eso sigue funcionando bien). Antes segun su orientacion usaba un grafico diferente, (los cuatro son el mismo, pero girado). Ahora la idea era usar un solo grafico que girase (angle=0, 90, 180 ó 270) pero al girar sobre el punto 0,0 del grafico, se altera su posicion, por lo que lo corrijo añadiendo X_REL y Y_REL a su X e Y. El codigo que tenia antes era practicamente igual, solo he cambiado X e Y por X_ABS y Y_ABS para seguir usandolo igual, y antes de cada frame calculo X e Y sumando ABS-s y REL-s.
En definitiva, gira bien, sigue en las coordenadas adecuadas, todo perfecto... Pero no me detecta las colisiones con PIXEL_RATON(proceso hotspot del raton) a menos que su angle sea 0 (si angle es cero, si que funciona como deberia). Nombre_MenuDerecho es un proceso al que llamas haciendo click derecho sobre el objeto (un menu con opciones de editar, cortar, copiar y eliminar el objeto), y estado_diseño es una global que vale 999 cuando se sale del programa con la tecla escape. No se que hacer con esto, alguien ve que pasa? pongo el codigo del proceso antes de los cambios? se entiende algo de lo que digo? porque laaaa leeeche, que parrafada acabo de soltar...  :P

Drumpi

Primero, una tontería de nada:

!(ESTADO_DISEÑO==999)
es lo mismo que
ESTADO_DISEÑO!=999
;)

Después, pues no sé, pero intuyo que X_ABS e Y_ABS no valen lo que indica el rango necesario para entrar en el último WHILE.
Usa SAY para que escriba en la ventana de comandos los valores de todas las variables necesarias para entrar en el bucle. Pon otro SAY nada más entrar al bucle para asegurarte de que realmente ha entrado (pon cualquier texto como "ha entrado al bucle"), y otro dentro del IF de collision. También usaría SAY para saber si MOUSE.RIGHT vale true y ESTADO_MENU_DERECHO vale realmente cero (no lo hagas con collision, ya sabes que una segunda comprobación antes de frame busca un segundo proceso de ese tipo, que intuyo que no existirá).

Por cierto, puedes hacer COLLISION(TYPE mouse) sin problemas, la colisión con el ratón sólo se realiza con el hotspot (un único pixel), tenga o no gráfico asignado.
Hala, como con 1001 procesos sólo va a 9 FPS, vamos a meterle 32 veces más, a ver si revienta.
(Drumpi epic moment)

Trecek

#8
Hombre... lo cierto es que eso YA lo hice :D de hecho hasta sustitui todas las condiciones por una sola, if collision type pixel_raton, y nada. Puse un say dentro del if que me decia el dato orientacion del objeto cuando colisionaba, puse varios objetos, y pase el raton por encima de ellos, solo colisionaba con los de orientacion = 0 (angulo 0).

No obstante, acabo de volver a comprobarlo con varios objetos, por ejemplo uno me ha dado:

x_abs=474
y_abs=366
mouse.right=1
estado_menu_derecho=0

Y nada, que no colisiona :S puedo colocar el objeto, pero no colisiona con pixel_raton. En cambio el mismo objeto en el mismo sitio, si lo pongo con angulo cero, si colisiona.
Para ver estos datos esta vez he puesto write_var.
mouse.right obviamente es cero hasta que pulso el boton derecho, que pasa a ser uno.
estado_menu_derecho es cero siempre (pasa a ser uno cuando sale el menu), y esto solo pasa cuando el angulo es cero, entonces (ademas de ver el menu) me sale por pantalla "estado_menu_derecho: 1" (por el write_var correspondiente).
Y si, no me extraña que me digas lo que me has dicho, yo tambien lo pense, es la unica conclusion logica, pero los datos son correctos, al menos estoy convencido de ello, aunque francamente ya no se que pensar. Todo esto suena a fallo tonto como los que me has señalado que podrian estar pasando, pero hasta donde yo se no es nada de eso.

Edito: gracias por advertirme de que puedo hacer collision(type mouse), pero es que pixel_raton lo uso para comprobar otras colisiones. Me resulta mas sencillo asi. Lo que no sabia era lo de "ya sabes que una segunda comprobación antes de frame busca un segundo proceso de ese tipo, que intuyo que no existirá", anotado.

Trecek

#9
Mira, asi estaba antes, cuando usaba 4 graficos distintos para cada orientacion (no modifico el angulo ni corrijo X e Y porque cada uno de los graficos ya esta girado antes de ser guardado en el fpg)

PROCESS DS_TOTAL(INT X, INT Y, BYTE COORD_X, BYTE COORD_Y, BYTE ORIENTACION)
PRIVATE
BYTE CONTADORX=0; //LOS USO DENTRO DEL FOR PARA ASIGNAR VALORES A LAS CASILLAS QUE OCUPA EL OBJETO
BYTE CONTADORY=0;
END//PRIVATE
BEGIN
Z=-1;
IF (ORIENTACION==0)
GRAPH=OBJETO_SELECCIONADO.GRAFICO_DEL_FPG0;
ELSE
IF (ORIENTACION==1)
GRAPH=OBJETO_SELECCIONADO.GRAFICO_DEL_FPG90;
ELSE
IF (ORIENTACION==2)
GRAPH=OBJETO_SELECCIONADO.GRAFICO_DEL_FPG180;
ELSE
IF (ORIENTACION==3)
GRAPH=OBJETO_SELECCIONADO.GRAFICO_DEL_FPG270;
END
END
END
END
TABLA_MAPA[COORD_X][COORD_Y].CASILLAS_X=OBJETO_SELECCIONADO.CASILLAS_X;
TABLA_MAPA[COORD_X][COORD_Y].CASILLAS_Y=OBJETO_SELECCIONADO.CASILLAS_Y;
TABLA_MAPA[COORD_X][COORD_Y].CASILLA_PRINCIPAL_X=COORD_X;
TABLA_MAPA[COORD_X][COORD_Y].CASILLA_PRINCIPAL_Y=COORD_Y;
TABLA_MAPA[COORD_X][COORD_Y].OCUPADO=1;
TABLA_MAPA[COORD_X][COORD_Y].NOMBRE_OBJETO1=OBJETO_SELECCIONADO.NOMBRE_OBJETO1;
TABLA_MAPA[COORD_X][COORD_Y].NOMBRE_OBJETO2=OBJETO_SELECCIONADO.NOMBRE_OBJETO2;
TABLA_MAPA[COORD_X][COORD_Y].TIPO_OBJETO=OBJETO_SELECCIONADO.TIPO_OBJETO;
TABLA_MAPA[COORD_X][COORD_Y].ID_OBJETO=ID;
TABLA_MAPA[COORD_X][COORD_Y].ORIENTACION=ORIENTACION;
TABLA_MAPA[COORD_X][COORD_Y].CATEGORIA=OBJETO_SELECCIONADO.CATEGORIA;
TABLA_MAPA[COORD_X][COORD_Y].AÑO=OBJETO_SELECCIONADO.AÑO;
TABLA_MAPA[COORD_X][COORD_Y].RAZA=OBJETO_SELECCIONADO.RAZA;
TABLA_MAPA[COORD_X][COORD_Y].TIPO=OBJETO_SELECCIONADO.TIPO;
TABLA_MAPA[COORD_X][COORD_Y].PROFESION=OBJETO_SELECCIONADO.PROFESION;
TABLA_MAPA[COORD_X][COORD_Y].MOVIMIENTO=OBJETO_SELECCIONADO.MOVIMIENTO;
TABLA_MAPA[COORD_X][COORD_Y].ATAQUE_NORMAL=OBJETO_SELECCIONADO.ATAQUE_NORMAL;
TABLA_MAPA[COORD_X][COORD_Y].ACIERTO_SIN_ARMAS=OBJETO_SELECCIONADO.ACIERTO_SIN_ARMAS;
TABLA_MAPA[COORD_X][COORD_Y].SEGUNDO_ATAQUE=OBJETO_SELECCIONADO.SEGUNDO_ATAQUE;
TABLA_MAPA[COORD_X][COORD_Y].ATAQUE_DIAGONAL=OBJETO_SELECCIONADO.ATAQUE_DIAGONAL;
TABLA_MAPA[COORD_X][COORD_Y].ATAQUE_DISTAN=OBJETO_SELECCIONADO.ATAQUE_DISTAN;
TABLA_MAPA[COORD_X][COORD_Y].DEFENSA=OBJETO_SELECCIONADO.DEFENSA;
TABLA_MAPA[COORD_X][COORD_Y].CUERPO=OBJETO_SELECCIONADO.CUERPO;
TABLA_MAPA[COORD_X][COORD_Y].MENTE=OBJETO_SELECCIONADO.MENTE;
TABLA_MAPA[COORD_X][COORD_Y].HABILIDAD1=OBJETO_SELECCIONADO.HABILIDAD1;
TABLA_MAPA[COORD_X][COORD_Y].HABILIDAD2=OBJETO_SELECCIONADO.HABILIDAD2;
TABLA_MAPA[COORD_X][COORD_Y].INVULNERAB=OBJETO_SELECCIONADO.INVULNERAB;
TABLA_MAPA[COORD_X][COORD_Y].EXCEP_INVULN=OBJETO_SELECCIONADO.EXCEP_INVULN;
TABLA_MAPA[COORD_X][COORD_Y].GRAFICO_DEL_FPG0=OBJETO_SELECCIONADO.GRAFICO_DEL_FPG0;
TABLA_MAPA[COORD_X][COORD_Y].GRAFICO_DEL_FPG90=OBJETO_SELECCIONADO.GRAFICO_DEL_FPG90;
TABLA_MAPA[COORD_X][COORD_Y].GRAFICO_DEL_FPG180=OBJETO_SELECCIONADO.GRAFICO_DEL_FPG180;
TABLA_MAPA[COORD_X][COORD_Y].GRAFICO_DEL_FPG270=OBJETO_SELECCIONADO.GRAFICO_DEL_FPG270;

//ESTOS FOR ESTAN PENSADOS PARA CASILLAS_X Y CASILLAS_Y MAYORES DE CERO (LA LOGICA DE ESTO ES QUE
//UN OBJETO NO PUEDE OCUPAR CERO CASILLAS DE ANCHO NI DE ALTO)
//relleno las casillas que ocupa el objeto en el mapa (excepto la casilla principal) con todos
//sus datos a cero excepto CASILLA_PRINCIPAL_X, CASILLA_PRINCIPAL_Y y OCUPADO.
FOR (CONTADORX=0;CONTADORX < TABLA_MAPA[COORD_X][COORD_Y].CASILLAS_X;CONTADORX=CONTADORX+1)
FOR (CONTADORY=0;CONTADORY < TABLA_MAPA[COORD_X][COORD_Y].CASILLAS_Y;CONTADORY=CONTADORY+1)
IF ((CONTADORX==0)AND(CONTADORY==0))
//SI CONTADORX=0 Y CONTADORY=0, ENTONCES ESTAMOS APUNTANDO A LA CASILLA PRINCIPAL,
//LA CUAL NO DEBE SER CAMBIADA. NO HACEMOS NADA
ELSE//IF ((CONTADORX==0)AND(CONTADORY==0))
//DATOS
TABLA_MAPA[((COORD_X)+(CONTADORX*2))][((COORD_Y)+(CONTADORY*2))].CASILLA_PRINCIPAL_X=COORD_X;
TABLA_MAPA[((COORD_X)+(CONTADORX*2))][((COORD_Y)+(CONTADORY*2))].CASILLA_PRINCIPAL_Y=COORD_Y;
TABLA_MAPA[((COORD_X)+(CONTADORX*2))][((COORD_Y)+(CONTADORY*2))].OCUPADO=1;
//A CERO
TABLA_MAPA[((COORD_X)+(CONTADORX*2))][((COORD_Y)+(CONTADORY*2))].ID_OBJETO=0;
TABLA_MAPA[((COORD_X)+(CONTADORX*2))][((COORD_Y)+(CONTADORY*2))].CATEGORIA=0;
TABLA_MAPA[((COORD_X)+(CONTADORX*2))][((COORD_Y)+(CONTADORY*2))].AÑO=0;
TABLA_MAPA[((COORD_X)+(CONTADORX*2))][((COORD_Y)+(CONTADORY*2))].CASILLAS_X=0;
TABLA_MAPA[((COORD_X)+(CONTADORX*2))][((COORD_Y)+(CONTADORY*2))].CASILLAS_Y=0;
TABLA_MAPA[((COORD_X)+(CONTADORX*2))][((COORD_Y)+(CONTADORY*2))].NOMBRE_OBJETO1=" ";
TABLA_MAPA[((COORD_X)+(CONTADORX*2))][((COORD_Y)+(CONTADORY*2))].NOMBRE_OBJETO2=" ";
TABLA_MAPA[((COORD_X)+(CONTADORX*2))][((COORD_Y)+(CONTADORY*2))].TIPO_OBJETO=" ";
TABLA_MAPA[((COORD_X)+(CONTADORX*2))][((COORD_Y)+(CONTADORY*2))].RAZA=" ";
TABLA_MAPA[((COORD_X)+(CONTADORX*2))][((COORD_Y)+(CONTADORY*2))].TIPO=" ";
TABLA_MAPA[((COORD_X)+(CONTADORX*2))][((COORD_Y)+(CONTADORY*2))].PROFESION=" ";
TABLA_MAPA[((COORD_X)+(CONTADORX*2))][((COORD_Y)+(CONTADORY*2))].MOVIMIENTO=0;
TABLA_MAPA[((COORD_X)+(CONTADORX*2))][((COORD_Y)+(CONTADORY*2))].ATAQUE_NORMAL=0;
TABLA_MAPA[((COORD_X)+(CONTADORX*2))][((COORD_Y)+(CONTADORY*2))].ACIERTO_SIN_ARMAS=0;
TABLA_MAPA[((COORD_X)+(CONTADORX*2))][((COORD_Y)+(CONTADORY*2))].SEGUNDO_ATAQUE=0;
TABLA_MAPA[((COORD_X)+(CONTADORX*2))][((COORD_Y)+(CONTADORY*2))].ATAQUE_DIAGONAL=0;
TABLA_MAPA[((COORD_X)+(CONTADORX*2))][((COORD_Y)+(CONTADORY*2))].ATAQUE_DISTAN=0;
TABLA_MAPA[((COORD_X)+(CONTADORX*2))][((COORD_Y)+(CONTADORY*2))].DEFENSA=0;
TABLA_MAPA[((COORD_X)+(CONTADORX*2))][((COORD_Y)+(CONTADORY*2))].CUERPO=0;
TABLA_MAPA[((COORD_X)+(CONTADORX*2))][((COORD_Y)+(CONTADORY*2))].MENTE=0;
TABLA_MAPA[((COORD_X)+(CONTADORX*2))][((COORD_Y)+(CONTADORY*2))].HABILIDAD1=0;
TABLA_MAPA[((COORD_X)+(CONTADORX*2))][((COORD_Y)+(CONTADORY*2))].HABILIDAD2=0;
TABLA_MAPA[((COORD_X)+(CONTADORX*2))][((COORD_Y)+(CONTADORY*2))].INVULNERAB=0;
TABLA_MAPA[((COORD_X)+(CONTADORX*2))][((COORD_Y)+(CONTADORY*2))].EXCEP_INVULN=0;
TABLA_MAPA[((COORD_X)+(CONTADORX*2))][((COORD_Y)+(CONTADORY*2))].GRAFICO_DEL_FPG0=0;
TABLA_MAPA[((COORD_X)+(CONTADORX*2))][((COORD_Y)+(CONTADORY*2))].GRAFICO_DEL_FPG90=0;
TABLA_MAPA[((COORD_X)+(CONTADORX*2))][((COORD_Y)+(CONTADORY*2))].GRAFICO_DEL_FPG180=0;
TABLA_MAPA[((COORD_X)+(CONTADORX*2))][((COORD_Y)+(CONTADORY*2))].GRAFICO_DEL_FPG270=0;
TABLA_MAPA[((COORD_X)+(CONTADORX*2))][((COORD_Y)+(CONTADORY*2))].ORIENTACION=0;
END//IF ((CONTADORX==0)AND(CONTADORY==0))
END//FOR
END//FOR

frame;
WHILE (((X)>18) AND ((X)<1069) AND ((Y)<821) AND ((Y)>15)AND(!(ESTADO_DISEÑO==999)))
FRAME;
IF ((COLLISION(TYPE PIXEL_RATON))AND(MOUSE.RIGHT)AND(ESTADO_MENU_DERECHO==0))
ESTADO_MENU_DERECHO=1;
NOMBRE_MENUDERECHO(ID, TABLA_MAPA[COORD_X][COORD_Y].NOMBRE_OBJETO1,TABLA_MAPA[COORD_X][COORD_Y].NOMBRE_OBJETO2,X,Y);
ELSE
END//IF
END //WHILE
END//BEGIN

Como ves los cambios en el codigo son minimos. No lo entiendo.
En esta version funcionaba todo perfectamente. La verdad es que puedo prescindir de arreglarlo y usar 4 imagenes, pero aparte de que no es una solucion elegante, me tiene intrigado.  ???

Trecek

Quote from: Drumpi on August 19, 2011, 12:13:38 AM
Después, pues no sé, pero intuyo que X_ABS e Y_ABS no valen lo que indica el rango necesario para entrar en el último WHILE.
Otra cosa, fijate que dentro de ese while hay un frame. Si no entrase en el while, el dibujo del objeto desapareceria de la pantalla al terminar el codigo del proceso, no? Bueno, pues no desaparece. Chico, la verdad es que esto me esta volviendo loco y seguro que es una gilipollez como un piano, pero no lo veo  :-\

Drumpi

Estoy pensando una cosa... Por curiosidad, dices que haces colisión con el proceso pixel_ratón en otras partes ¿no? No estoy seguro si hacer la llamada a collision en otros procesos tiene el mismo efecto que llamarlo en el mismo (pasar al siguiente proceso de ese tipo, y si no hay más, no comprobar colisión). Por si acaso, comprueba a ver si esos otros procesos también colisionan.
Si no, cambia el TYPE por el ID del proceso (si sólo hay uno, puedes guardarlo en una variable global al crearlo) o usa TYPE MOUSE, a ver si así funciona.

No creo que sea eso, pero por descartar.
Si los valores indican que debe poder entrar, salvo collision, haz un say con el resultado de la llamada a collision, a ver si es eso.
Por cierto ¿el objeto se ve en pantalla? no veo que en este proceso uses FILE. Ten en cuenta que los FPG devuelven un valor al cargar que no siempre es el que se espera (0, 1, 2, 3...).
Hala, como con 1001 procesos sólo va a 9 FPS, vamos a meterle 32 veces más, a ver si revienta.
(Drumpi epic moment)

Trecek

He modificado un poco el codigo a partir del while, ya no compruebo X e Y, solo que no se haya pulsado escape (si se pulsa escape la global estado_diseño pasa a ser 999, este while lo tengo en casi todos los procesos para detectar el final del programa). Acto seguido compruebo si colisiona con el raton, si es asi cambio el grafico del raton a traves de la global estado_raton; dentro de ese if meto otro anidado para saber si se ha pulsado el boton derecho del raton, lo que hace que el grafico del raton cambie de nuevo (estado_raton) y llame al menu del boton derecho (nombre_menuderecho).

He probado con IF (COLLISION (TYPE MOUSE)) y con IF (COLLISION(ID_RATON)), id_raton es una global int en la que meto el id de pixel_raton al llamarlo ID_RATON=PIXEL_RATON();
En todos los casos el resultado es el mismo, me detecta colisiones solo si el angulo es cero.

No entiendo muy bien que quieres que haga con file, solo uso un fpg, asi que no me he preocupado de file en ningun momento, ya que he dado por sentado que es 0, y que todas las referencias que haga a graph sin especificar su file seran tomadas como una referencia al fpg 0 (me equivoco?). Los numeros de los graficos de cada objeto (entre otras cosas) estan en una struct, de ahi sacaba valores para graph dependiendo de la orientacion (4 numeros distintos), ahora naturalmente solo saco un valor, el correspondiente a orientacion=0 y lo giro modificando su angle.

Pongo el codigo que he cambiado a partir del while, el resto sigue como antes, con angle y tal.

WHILE (!(ESTADO_DISEÑO==999))
X=X_ABS+X_REL;
Y=Y_ABS+Y_REL;
FRAME;
IF (COLLISION(ID_RATON))
ESTADO_RATON=1; //MANO SEÑALANDO (302)
IF((MOUSE.RIGHT)AND(ESTADO_MENU_DERECHO==0))
ESTADO_RATON=2; //MANO PULSANDO (303)
ESTADO_MENU_DERECHO=1;
NOMBRE_MENUDERECHO(ID, TABLA_MAPA[COORD_X][COORD_Y].NOMBRE_OBJETO1,TABLA_MAPA[COORD_X][COORD_Y].NOMBRE_OBJETO2,X_ABS,Y_ABS);
END
ELSE
END//IF
END //WHILE
END//BEGIN


Saquemos o no que esta mal en este proceso, gracias por molestarte drumpi. Yo me veo incapaz de arreglarlo, si a ti o a alguien del foro se le ocurre alguna posibilidad la probare y os dire, pero mientras tanto seguire con otras partes del programa, que lo tengo estancado desde que empece a tratar de arreglar esto (sin exito).

Drumpi

Hombre, si sólo tienes un FPG en memoria no pasa nada, pero no sería la primera ni la última vez que se vieran problemas por no usar la variable FILE cargando varios FPG o porque se supone que los valores cargados son 0, 1, 2, ...

Resolver los problemas sin tener el código completo es, en ocasiones, muy complicado. Teniendo el código se pueden poner writes, says y usar el debuger, de otra forma, sólo podemos suponer cosas (con mayor o menor acierto). Lo suyo es que intentes buscar el error por tí mismo.
PD: no me mandes el código a mi, que no ando yo muy católico para ponerme a programar ^^U
Hala, como con 1001 procesos sólo va a 9 FPS, vamos a meterle 32 veces más, a ver si revienta.
(Drumpi epic moment)

Trecek

Hmmm, creo que tratare de hacer un miniprograma con este proceso y lo minimo para que funcione, a ver si asi puedo aislar el problema, o en caso contrario al menos para tener algo que poder enviar mas facil de leer.
Entiendo lo que dices, siempre es mas sencillo teniendo el codigo, si no lo he puesto es porque son demasiadas lineas. Eso si, si alguien se anima a echarle un vistazo a ver si encuentra el fallo que me diga, que lo envio, toda ayuda sera agradecida eternamente (o al menos hasta que se me olvide).

Gracias Drumpi, si consigo enterarme de que pasa con esto lo pondre por aqui y cuando tenga una version mas o menos completa y estable del editor... te apeteceria probarlo :D?