Hola a todos:
Se me ha planteado una duda bastante curiosa. Como sabeis, estoy liado con el motor de scroll tileado, y ya sólo me queda solucionar el tema de las z, que me trae por la calle de la amargura.
De momento, lo que hago es que cada fila horizontal de tiles tiene una z que vale -2 que la de arriba, y le resto otros 2 por cada tile que subimos en el eje z. Uso el 2 como base para intercalar los sprites en medio.
El problema lo tengo en las esquinas, porque a poco que el personaje sea ancho en los pies se me tapa con el tile de la fila de abajo. Así que he pensado otro método que requeriría usar z aun mayores a las que ya uso.
Las z tienen el mismo límite que un int ¿no? tanto positivo como negativo. ¿Podría suponer un problema con el resto de "objetos" que tienen una z predefinida? (scrolls, textos...) no hablo sólo para el lenguaje, sino a vosotros, como programadores, por tener que modificar sí o sí la z de los textos.
PD: No he encontrado nada acerca de X, Y y Z en el wiki, no están ni en la lista de variables locales predefinidas.
Y porque los tiles tienen distintos valores de Z ?
Cierto... En principio no debería haber diferencia de Z en las diferentes horizontales de tiles del mismo scroll... ¿No?
Aún no me he puesto a hacer un proyecto de semejante en-verga-dura como para tener una seria preocupación por las Z, pero tengo claro que llegado el caso habrá que hacer un "mapa de z" que dictamine qué elementos tienen qué rangos de Z y programar en consecuencia.
Mientras dejes claro qué rango de Z usas o cómo puede cambiarse no creo que vaya a haber problema Drumpi.
Buenas Drumpi,enteoria si la Z deverian de tener el mismo rango que un INT que me imagino que NO sera un INT UNSIGNED,ya sabes que su valor es de -32.768 a 32767...
Por otro lado deverias tener una capa entera con la misma Z en todos sus Tiles,otra capa con la misma Z para sus Tiles ,pero mas arriba o mas abajo que la anterior,y porsupuesto mas profunda que todo ser "Viviente " del juego para que no les oculten,el que se tapen los pies al personaje seguramente es porque esa fila de Tiles es menos profunda que el propio personaje ,pero como te digo para una capa entera pueden tener el mismo valor,cambiar la Z porque este un tilde mas arriba no es "Correcto",lo es ,pero no tiene sentido ;).
En un scroll tileado normal bastaría usar una Z por cada capa y punto.
Pero estoy hablando de un scroll isométrico, que simula 3D, por lo tanto tengo que trabajar con profundidades. Si el suelo fuese liso no habría problema, pero cuando cada tile es un cubo, tienes diferentes alturas y demás, tienes a unos procesos tapando a otros que están más lejos o por debajo.
A eso súmale los personajes moviéndose por pantalla: imagina una sala vacía con un cubo en medio, si tengo un sprite con una 'Y' (de pantalla) menor se debe mostrar detrás del cubo, al estar más lejos, si hay otro sprite con una 'Y' (de pantalla) mayor que la del cubo, se debe mostrar delante. No tengo que explicar lo que pasa si el prota está en el hueco entre dos cubos o cuando tenemos más de dos o tres plantas.
Por eso, cada linea horizontal tiene una Z distinta, y las capas tienen otras.
La duda viene por si dotar a cada capa de un rango de Zs exclusivo (por ejemplo, el suelo usa capas de 0 a -10, la primera planta de -11 a -20...) que sería lo suyo, o simplemente que las plantas superiores tengan la misma Z que la planta de abajo -1, que ahorraría valores de Z.
Todo el día liado y no consigo que el personaje se oculte bien tras los cubos, tengo un error por ahí de medio tile que me tiene amargado.
Humm ...
Recordando esos buenisimos juegos,batman,Head Over Heels,ect, me trae a la mente como estaban "codificados"...
yo lo que haria seria hacer al menos para el suelo diseños planos,y los que serian los primeros añadirles otros planos que seria el canto vertical,con lo que el suelo lo podrias tener todo con una Z,pues como te digo segun el "FlashBack"que tengo de ese tipo de juego, claro esta que tambien lo puedes hacer con las plataformas o las plantas como las llamas,pero seria mas trabajo,esas las dejaria cubicas y daria menos profundidad a las que estuvieran mas cerca de "ti" y menos a las que estuvieran al fondo pero mas que al suelo,y al personaje le tendrias que dar mas que el suelo,si lo que quieres es ahorra Zs,seria hacerte una funcion o proceso que las asignara automaticamente ^^.De todas formas si me pasas el codigo te ayudo o te ayudaria mas ^^.
Sobre las z, ojo con el ctype del proceso "tile" y del proceso "jugador", en su día comprobé que procesos con ctype=C_SCROLL tienen una z "más profunda" que profesos con ctype de pantalla. ¿Ya lo sabías no? :P
DjSonyk: si, eso es lo facil, adaptar las Z en función de lo que hay en pantalla, pero el problema es que esto es un scroll genérico, que debe funcionar en todos los programas posibles, por lo que hacer una personalización de las capas es muy complicado. Además, ten en cuenta que en un momento dado nos podemos juntar fácilmente con cientos de procesos en pantalla y gestionar las Z sería muy lento, por eso en el código recurro a cálculos ya hechos. el código lo tienes en la seccion de proyectos, en el scroll tileado 3.2
Windgate: si, se que los scrolls, modos7 y demás se situan en una z más alejada, pero eso no debería ser problema. Modifico las z de los procesos, así que siempre van a estar en las profundidades que les digo, otra cosa es que el que lo use controle la Z de sus procesos (aunque por eso cree la función que lo situa en pantalla, para que no se tenga que preocupar de ello.
mira, actualmente la z del scroll normal es de 512 (atras), la del mouse es -512 (se puede modificar), no hay limites de Z solo lo que pueda procesarse en un entero con signo...
Gracias, Splinter, es justo lo que sospechaba :)
Bueno, día de descanso y resulta que doy un paso enorme hacia atrás.
Me he dado cuenta de que con el actual sistema de Zs, si un personaje mide dos tiles de altura o sube, será tapado por cualquier tile que esté una "planta" por encima (digo planta porque ancho y alto los uso para referirme al plano horizontal).
Así que necesito volver al sistema primitivo, pero me surge un par de ideas, y como debo tener el cerebro totalmente simétrico o algo así, pues no me decido.
Os comento: en el espacio isométrico, cuanto más abajo se pinte el tile, más cerca está de la cámara y menor será su Z ¿correcto? bien. Cuando queremos poner un tile a una altura superior, este debería tener la misma Z que los tiles que hay en su vertical, pues su distancia a la cámara es la misma.
Pues eso no debe ser así, porque los tiles de mayor altura deben tapar a todos los tiles que hay por debajo, por lo que deberían tener una Z menor.
Y aquí surge el problema: ahora tengo al personaje que mencionaba antes, de dos tiles de altura, y cuando está más cerca de la cámara debería verse por encima de ambos tiles, por lo que su Z es aun menor que la del tile de más altura. En teoría creo que puedo implementar este sistema, pero debería dejar varios valores de Z entre fila y fila de tiles, y esta diferencia dependería de la altura del mayor gráfico que vayamos a usar (y para no pillarme los dedos debería ser del número de filas que cabe en pantalla + 1). Es un sistema complejo pero no tiene el inconveniente del siguiente.
El otro es hacer que todos los tiles de la misma vertical tengan la misma Z. Lo bueno de este sistema es que entre fila y fila puedo dejar una diferencia de 2 unidades de Z para que estén los procesos moviéndose, y simplifica mucho el código. La pega es esa, que todos los tiles de una "columna vertical" tienen la misma Z, y se vería el flickering o como se llame a la superposición aleatoria de ambos procesos, y sería trabajo del diseñador impedir que dichos tiles se solapasen; no es nada difícil pero sería una cosa bastante importante a tener en cuenta, y al usar más tiles no se podría aprovechar el mismo mapa como durezas sin complicar demasiado el código, necesitarías cargar otro mapa (hacerlo es sencillo, el problema es ocupar más memoria).
Así que esas son mis dos alternativas, creo que en la primera puedo hayar algo que me simplifique algunos cálculos, pero quiero saber vuestra opinión, y qué creeis que valoraría más el novato que quiera usar el motor de tiles.
Gracias.
Quote from: Drumpi on October 07, 2009, 10:10:54 PM
El otro es hacer que todos los tiles de la misma vertical tengan la misma Z. Lo bueno de este sistema es que entre fila y fila puedo dejar una diferencia de 2 unidades de Z para que estén los procesos moviéndose, y simplifica mucho el código. La pega es esa, que todos los tiles de una "columna vertical" tienen la misma Z, y se vería el flickering o como se llame a la superposición aleatoria de ambos procesos, y sería trabajo del diseñador impedir que dichos tiles se solapasen; no es nada difícil pero sería una cosa bastante importante a tener en cuenta, y al usar más tiles no se podría aprovechar el mismo mapa como durezas sin complicar demasiado el código, necesitarías cargar otro mapa (hacerlo es sencillo, el problema es ocupar más memoria).
Mmm esto no podrías solucionarlo con "priority"??? creo que te serviria para que no te den problemas los procesos con misma, y así sería la solución con código más simplificado para quien quiera usarlo.
Mmmm, añadir priority a la lista de cosas a tener en cuenta no me gusta. De todas formas, use el método que use, el que quiera hacer un scroll tileado con mi motor no tendrá que preocuparse de calcular la Z (eso lo hace esta función que tantos problemas me está dando), sólo de que textos y otros procesos que deban ir por encima del scroll tienen que decrementar su Z si hay demasiados tiles :D
Para lo que comentas de los pisos:
Se me ocurre que mantengas en una variable el número de planta en el que se encuentra el personaje.
Todo piso en planta superior tendrá una z mínima, por ejemplo -256 y pisos superiores -257, -258...
Y todo piso en planta inferior tendrá una z máxima, por ejemplo 255 y los pisos inferiores 254, 253...
Es una forma de asegurar que toda planta superior tape cualquier tile bajo ella y que toda planta inferior siempre sea tapada por cualquier tile sobre ella...
¿Problemas? He determinado como z mínima -256 y todo iría bien salvo que aparezcan 256 tiles verticalmente en pantalla... Siempre podría hacerse menor esa "z mínima"...
Si te sirve de inspiración pues me alegro xD
Ese es el método actual... si lo he entendido bien.
Cada planta tiene unas Z asignadas, por ejemplo, la primera desde 0 a "numero de lineas verticales" * 2, la siguiente desde ("numero de lineas verticales" * 2)+2 a ("numero de lineas verticales" * 2)+2+("numero de lineas verticales" * 2)... todo esto en negativo.
Suponiendo 10 lineas, la planta 0 tendría Zs con valores de 0 a -18, la planta 1 de -20 a -38, la planta 2 de -40 a -58, etc.
El problema es cuando, por ejemplo, el prota mide dos tiles de altura. Imagina dos cubos apilados, y el prota se pone delante, o sea, más cerca. El prota tapa al cubo de la parte inferior por estar en la misma "planta", pero el de arriba, al tener 20 Zs menos le tapa la cabeza.
Básicamente la duda es si debo romperme la cabeza con el método ya pensado o no hacerlo y obligar al usuario a crear tiles que no se solapen, nada más.
¿2 cubos apilados? En el caso de 2 cubos apilados les daría a ambos cubos la z del cubo más bajo, así todo debería ir bien.
Y eso me hace pensar... ¿En el caso de tiles en "plantas superiores" no bastaría con darles la misma z a tiles que están exactamente unos encima de otros??? Es el mismo caso que los cubos apilados pero con hueco en medio...
Si tienes el código ahí a mano y fresquito prueba eso a ver... Ojala pudiese probarlo yo pero sólo puedo maquinar ::)
Quote from: Windgate on October 09, 2009, 12:25:38 AM
¿2 cubos apilados? En el caso de 2 cubos apilados les daría a ambos cubos la z del cubo más bajo, así todo debería ir bien.
Y eso me hace pensar... ¿En el caso de tiles en "plantas superiores" no bastaría con darles la misma z a tiles que están exactamente unos encima de otros??? Es el mismo caso que los cubos apilados pero con hueco en medio...
Si tienes el código ahí a mano y fresquito prueba eso a ver... Ojala pudiese probarlo yo pero sólo puedo maquinar ::)
Si, ese es el segundo método que explico. Si apilamos los cubos formando una "columna", le podemos dar a todos la misma Z. Pero entonces es posible que la "cara superior" de uno de los cubos inferiores tape parte del tile que está apilado encima, porque son dos procesos que se superponen y tienen la misma Z. A ver si con dibujos
/\ /\
\/ \/
\/ /\
\/ \/
El primero es cómo debería verse, en el segundo el tile inferior tapa al superior por tener la misma Z.
La solución sería que al diseñar el nivel, el tile inferior no tuviera la "cara superior" pintada (se vería como una V muy gorda).
La otra solución es que los tiles, a medida que se apilan, tienen una Z menor, pero entonces el personaje tiene que tener una Z menor aun que el que está más encima, pues aunque sea un gigante, si está más cerca, tapa al tile más alto.
Es difícil de explicar, pero espero que se me entienda
----O----
Se me acaba de venir a la cabeza, pensando en por qué os parece tan sencillo lo de los tiles y no hablábais de la posibilidad de tener tiles a distintas alturas, y ha sido de golpe.
Estaba pensando en el juego más sencillo de scroll isométrico que conozco, el Sonic Labyrinth de GG, y que a pesar de sus cuestas, sus "escalones", todo era sencillo ¿Por qué? porque sólo hay suelo. No hay puentes, no hay que saltar... en definitiva, no hay tiles en la misma vertical, y ahi comprendí que el personaje va siempre por encima del nivel, siempre con una Z menor, el escenario nunca tapa al personaje, sólo lo hacen los sprites.
Eso sería muy sencillo de hacer, tanto como un scroll normal, pero es que lo que intento hacer es lo que después añadiré al scroll normal: una tercera dimension, en la que los tiles SI pueden tapar al personaje. Quiero poder poner tres tiles haciendo una columna, o varios haciendo una pirámide y que el personaje pueda subirla a saltos, cosas así, de ahí la complicación.
De todas formas valoraré lo de poner el scroll simplificado, ya sea con un flags o con un código aparte.
Yo hace tiempo empece un juego Isometrico nunca se acabo porque hacer una copia a cd y formatear el disco duro y que luego el cd no funcionara,pos ya me diras... :(,lo que hice fue dar al suelo una Z a todo,y a las tiles de las plantas una Z que diferenciaba de 5 de una fila a otra,,subia otra planta y mas 10,y mas 5 a cada fila,el personaje tenia una Z menor que el suelo y cada fila que subia le sumaba 5 y al saltar a la primera planta mas 10 a su Z,asi le dejas por ejemplo por encima de la fila 1,donde se supones que quieres llegar y cubierto por la fila 3,la fila 2 claro esta tiene que estar vacia ese hueco para que no se estampe el personaje en la cabeza XD... Lo unico que usaba un Array Tridimensional para saber donde estaba el personaje y modificar su Z.
Otra cosa, que al menos entre filas dejes al menos 3 de diferencia,y entre columnas tambien minimo 3,asi el personaje puede cojer la z del medio para poder ponerle delante de una y detras de la otra correctamente,no se si me explico.. ^^ de todas foramas voy haber si te hago un ejemplo....
Buenas.Relellendo otra vez los post esto que te queria comentar veo que los sabes aun asi...(http://<a%20href="http://www.mediafire.com/imageview.php?quickkey=njtmi4unjzn&thumb=5"%20target="_blank"><img%20src="http://www.mediafire.com/imgbnc.php/034b9d0ce8e0c3e79ca50d4f6385e8a74g.jpg"%20border="0"%20alt="Unlimited%20Free%20Image%20and%20File%20Hosting%20at%20MediaFire"></a>)
Mi solucion seria por cada fila que se moviera el personaje le añadieras a Z al menos 3,para que tengas entre tile y tile una z intermedia,y por cada columna lo mismo,y cuando quisieras ,vamos a decir saltar al piso superior tiene que ser la Z menos profunda que la Z menos del piso de abajo,para que el personaje pueda tener la Z correspondiente a esa altura,a lo que tengas el pj de 2 tiles de altura la unica solución que se me ocurre,es "partir" al personaje en 2,y cada mitad que tenga la Z correspondiente a la altura donde este,la parte de abajo con la Z que corresponda de abajo y la parte de arriba con la de arriba,aun asi te hecho un pequeño ejemplo pero es para solo una parte :(,la voy a dejar por si alguien la quiere hechar un vistazo,va correctamente de derecha a izquierda,falla un poco a "subir" o saltar ,como se mire,no es isometrico,pero puede dar una idea,lo unico moves el cubo rosa a donde el azul y resetear la Z,con la tecla R, cursores mueven el cubo,la tecla A acerca el cubo al usuario,y la tecla S lo aleja,jugando un poco con la A y la S se ve una idea de como hacer lo que dices pero solo a un tile :(,Espaciadora para salir.Lo dicho Verticalmente no va muy correctamente porque se tendria que comprobar en que columna esta ,aun asi en el PRG viene la solucion de como seria,espero que te ayude...y a los demas :)
Aaahhh claro... Ahora he entendido el problema de apilar tiles con la misma z Drumpi... Ahí lo que habéis dicho de decrementar la Z en la vertical de N en N ya tiene sentido, así los tiles apilados pueden decrementarla de 1 en 1 y asegurar un dibujado correcto.
¿El valor de N? Pues el ideal sería la resolución vertical dividida entre la medida vertical del tile en píxels, aunque para tiles extremadamente pequeños o extremadamente grandes... lol
En cualquier caso, como solución EFICAZ, la priority en función de la "altura" del tile supongo que ayudaría, bastaría un
priority = -planta;
Para que se pinten al final los tiles más elevados.
Estamos proponiendo soluciones diversas, todas pueden servir, pero al final KISS (Keep It Simple Stupid) ;D la solución perfecta no debe implicar calculos demasiado complicados ni decisiones de sumar valores diversos hasta conseguir algo válido.
Yo te propondría probar un priority ya que debería ser fácil de programar... En su día programé un cursor con "colita" de 4096 procesos, y no controlaba la z, simplemente con priority la cola se dibujaba en el orden correcto.
Esa solución parece ser mucho mejor que la mia,la de WindGate,digo parece porque la verdad yo con priority sabia que existia pero siempre la e ignorado,pero veo que estado haciendo mal en no haberme fijado en ella...Por cierto siento lo del programa que no fuera del todo bien y el cocris que fuera un kk,pero lo hice de 6 a 8 de la mañana corriendo por si al verlo de otra manera conseguias verlo de otra manera,valgase la redundancia,y veis lo que te fallaba...
Saludos.
DjSonyk: lo de partir al personaje no es una oción, porque eso implica que si luego tu quieres usar el motor de tiles tendrás que hacérselo a los FPG de tu personaje, y además, cuando saltes, el personaje se moverá verticalmente una fracción de tile, por lo que tenemos el mismo problema.
Windgate: al final voy a tener que hacerte caso con lo del KISS, porque he estado intentando de nuevo conseguir lo del comportamiento correcto de la Z respecto alas 3D y no lo consigo: tengo un offset de medio tile que no entiendo, tanto en eje X como en eje Y, y parece que a medida que añadimos tiles extras cambia dicho offset. En serio que no lo entiendo, necesitaría que alguien me echase una mano, cuatro ojos ven más que dos.
Aparte de eso, lo he meditado y la diferencia entre los dos métodos que propuse es simplemente cambiar el valor de una constante, por lo que tampoco me haría falta meter a priority por medio. Pero claro, si no consigo que cambie la Z respecto a coordenadas isométricas en lugar de respecto a la Y de pantalla, da igual, porque de una manera u otra, algun tile se va a solapar quiera o no.
Mantengo lo del priority... Pero lo mejor será que pases el código de tu motor para echarle un vistazo, tal cual lo tengas ahora, aunque meter mano a código de terceros es tarea de chinos :P pero bueno.
¿El offset de medio tile no tendrá que ver con los puntos de control, no?, recuerdo que hace unos días yo mismo propuse poner el punto de control del personaje en los pies...
En los pies está. Creo que puede venir porque los tiles tienen el punto de control en el centro de la cara superior, y la posición (0,0) de la cámara la sitúo en la esquina izquierda. También puede ser por el desplazamiento de la región, no se, no lo veo.
De todas formas, os pongo el código, por si alguno se anima a mirarlo. He intentado que esté lo más claro posible y bien comentado, el error, de haberlo, estaría localizado en isometric_tscroll.inc, y la función que no va bien es la última, la parte de la Z está separada del resto del código, no hay dependencias salvo con la estructura del scroll, donde se almacenan varios puntos de referencia (la posición de la cámara, la region, la posición de tile superior izquierdo...).
Siento tener que pediros ayuda, pero ya ando desesperadísimo.
He probado el programa, me gusta como pinta. Interpreto que el recuadro que se dibuja en pantalla es la "parte que se procesa" ya que fuera de él se ve como se genera el escenario.
No veo el problema del que me hablas, de hecho el protagonista es un tile transparente y que apenas se ve y no logro ponerlo "detrás de un tile" para ver cómo se tapa...
¿Cuál es el problema? Es que no mentero...
Por cierto, aquí la lista de import para que compile a la primera, no sé cómo hacéis para compilar vosotros, ¿Tenéis algo que autodetecte los DLL?
import "mod_file";
import "mod_text";
import "mod_string";
import "mod_map";
import "mod_proc";
import "mod_screen";
import "mod_wm";
import "mod_key";
import "mod_say";
import "mod_video";
import "mod_draw";
import "mod_effects";
import "mod_mem";
No, tengo un bgdc.import estandar con todas las mod para las pruebas ;D
Al cuadrado no le hagas mucho caso, pues es para ver el centro del verdadero prota cuando se usa la linea 57 en lugar de la 56 (el prota es un pájaro azul, si no lo ves es que falta por meter el tiles.fpg, que estaba en el otro archivo que subí con el motor ^^U). El cuadrado igual, es para ver la "pantalla" para esa linea 57 (la diferencia entre ambas lineas es la posición y tamaño de la "region" de trabajo).
De todas maneras, acabo de mirarlo de nuevo y creo que ya lo tengo: resulta que las variables [ts_struct].tileador_posx y [ts_struct].tileador_posy almacenan la posición del tile que se dibuja más a la izquierda y arriba, y uso eso como referencia a la hora de determinar las Z. De lo que no me había dado cuenta es que esta posición hace referencia al centro del tile, y no a la esquina izquierda, como debería, así que lo he solucionado con una simple suma.
Pero no me convence del todo, aun quedan algunos "glitches" en zonas cercanas al cambio de tile, algo más debe haber, pero si se controlan bien las distancias de colisión no habrá problema, se supone que no vamos a ver al personaje atravesando paredes :D Es cuando hay problemas, cuando tile y sprite comparten (X,Y,Z).
De todas formas, cualquier error que veais, decídmelo para corregirlo.
Os subo esto para que veais ahora qué tal va, pero no es el definitivo: los tiles de "altura" superior taparán al personaje hasta que implemente lo que estaba preguntando hace unos días.
Acabo de terminar de implementar el método este y me he dado cuenta de una cosa: al determinar la Z por cercanía a la cámara, sucede que el tile de suelo de la siguiente fila más cercana le tapa el pie al personaje, por lo que estoy como al principio.
No lo puedo hacer por cercanía por lo dicho, tampoco lo puedo hacer por plantas porque entonces, cualquier tile en una planta superior, aunque esté más lejos de la cámara, taparía la cabeza al sprite. Ya no sé cómo hacerlo, la única solución que se me ocurre es determinar la Z en función de todos los sprites de pantalla, pero eso requeriría una integración para la que no está preparada el motor.
A ver si me ayudais a encontrar una ordenación de las Zs mediante una fórmula matemática, porque si no me veo planteando una de dos: o hacer el scroll como el ortogonal, por capas (y que se busque el programador su asignación de Zs y que dibuje las capas como vea), o crear una lista de procesos asignados al scroll y añadir un paso de determinación de Zs a cada uno.
¿Has probado a usar priority ya?
Estaríamos en las mismas: todos los tiles de la misma vertical tendrían la misma Z y se solucionaría con el priority, si, pero el tile de la fila siguiente seguiría dibujándose por encima del sprite al tener una Z menor.
Me temo que no me queda otra :(