Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





mostrar sprite en pantalla de diferentes alturas

Iniciado por vib, 14 de Diciembre de 2012, 10:51:15 PM

« anterior - próximo »

vib

Holas chicos! si el titulo es un poco raro pero nose me ha ocurrido nada mejor para resumirlo

El caso es que estoy viendo un problema que nose de que manera encararlo, os explico.

Tengo un juego 2d, vista desde arriba, estilo pokemon de la gameboy.

Tengo un scroll, donde aveces hay tiles que son el doble del tamaño normal para representar ciertas paredes,la duda que tengo esque al mostrar el personaje nose como hacerlo para que depende en que parte del mapa quede el mapa por encima del personaje y cuando al reves.

Nose si se entiende...
En mi bucle represento para mostrar en pantalla
matriz mapa
objetos
personaje

Claro siempre personaje queda por encima de todo...
Como se podria hacer?
validando cada tile del scroll para saber si esta el posicion para que quede por encima o por debajo?
y si es asi..y el personaje lo tengo en medio de 2 tiles 1 de estar encima y del otro de estar debajo.. que hago imprimo media matriz mapa
paro imprimo personaje
imprimo el resto de matriz?

Aparte de nose como encararlo..si lo encarara asi como he puesto al final nose como lo tendria de hacer porque solo se me ocurren chapuzas asquerosas...
Gracias

adrigm

Este problema es típico y se soluciona con la prioridad de tiles se debe dibujar por prioridad siempre. Supon que tienes una capa donde tienes tus paredes y otras donde esta tu personaje:

1 1 1 1 1
2 2 2 2 2
3 3 3 3 3
4 4 4 4 4

Si a cada fila le vas dando una prioridad mayor si tu personaje esta en la fila 2 y la pared en la fila 3 aunque la pared sea tan alta que llega a la fila 2 tiene mas prioridad que tu personaje que al estar en la fila 2 tiene prioridad 2, cuando baja una fila la prioridad de tu personaje aumenta en una unidad ahora tu personaje esta en la fila 3 y tiene prioridad 3 por tanto pasa por encima de la pared.

Espero que hayas entendido el concepto general.
http://razonartificial.com/ - Blog personal sobre desarrollo de videojuegos

julen26

#2
En los juegos 2D generalmente, cuando se trata de objetos se suele usar un valor de profundidad para dar prioridad al dibujado de unos objetos sobre otros. Este valor de profundidad suele ser directamente la posición "y" del objeto. Cuanto menor sea su cordenada "y" mayor sera su profundidad y será dibujada antes.

En el caso de tiles, y lo mas sencillo sobre todo para evitar algoritmos de ordenación que ralenticen el ciclo de tu juego, es usar capas. Definir capas para objetos, para personajes etc. Y definir distintas capas para los tiles, para que algunas de ellas se dibujen antes y otras después del personaje.

vib

Vale era lo que me he ido imaginando...mmm
Pero mas o menos como funciona de manera algoritmica? me imagino que los 2 debeis hablar de capas o de algo similar?

Ami de lo que me habeis hablando solo se me ocurre hacer una matriz que antes de imprimir por pantalla guarde todas las posiciones que se imprimiran y eso ordenar para que quede bien...pero claro me da ese problema que se menciona en el 2n mensaje... que dependiendo las grandarias podria darme problemas de ordenacion tardando mucho...

Quizas hay algo que no este haciendo bien... porque de momento uso 2 matrices, 1 del mapa para representarlo y otra de durezas con 1 o 0 para representar las colisiones con el mapa...nose si eso es lo correcto o tiene demasiado consumo?
Luego con el problema mencionado podriais horientarme para asignar prioridades


NOSE solo se me ocurre hacer un recorrido 1r para comprovar las prioridades y luego hacer otro para imprimir pero creo que es super chapuzero y gastoso

julen26

Yo en tu caso tiraría por la solución de capas, ya que según as dicho es un juego con tiles. Haz que sean todos del mismo tamaño, divide los grandes en varios y coloca sus partes en diferentes capas.

El metodo de las collisiones esta bien aplicada, si usas un buen algoritmo no tiene porque consumir. Por ejemplo, al usar una matriz, siempre puedes obtener la posicion del personaje en esa matriz a partir de la posicion XY del personaje. Y así solo comprobar las celdas adyacentes.

vib

Si lo he ido pensando pero nose como plantearlo para hacerlo de forma automatica..
tengo la matriz que representa el mapa

1 1 2 1 3 1
1 1 (1 2) 2 2
2 2 1 3 2 2

Y el tema (1 2) tiene de estar por encima del personaje....

La unica manera que se me ocurre es:
Aparte de tener de ir a las posiciones de la matriz manualmente para decirle que esas son las de mas prioridad.. cosa que no me convence..
o es normal los tiles de mapa decir de forma manual la prioridad?
Luego las prioridades para mostrarlas se me ocurre  hacer una matriz que compruebe las imagenes que se muestran en pantalla i si es asi que se ordene en una matriz o array de manera que que se tiene de imprimir 1r...

Nose es lo que se me ocurre otra manera y nose esta manera me parece fea y lenta...
Podrias aconsejarme?:/

[EX3]

Yo tal y como lo he implementado siempre en mi motor ha sido creando listas de dibujado o creando una coordenada Z para definir profundidad.

Lo de las listas de dibujado es como crear capas de dibujo, son simplemente listas que almacenan los parámetros de dibujado del objeto sprite a la hora de renderizar la escena (textura, coordenada, si se le aplica cámara para desplazamiento, transformaciones, efectos, etc...) y la llamada de dibujo simplemente tiene un parámetro en el que indicas el indice de lista o capa donde quieres dibujar el sprite y esta añade dicha información a lista que corresponde.

Lo de la coordenada Z es simplemente tener una misma lista de dibujo pero que se ordene de menor a mayor según el valor de Z de cada elemento a dibujar en la lista. Si lo haces bien no sueles perder rendimiento.

En ambos métodos es simplemente cambiar el valor de un parámetro para alterar su profundidad de dibujo.

Salu2...
José Miguel Sánchez Fernández
.NET Developer | Game Programmer | Unity Developer

Blog | Game Portfolio | LinkedIn | Twitter | Itch.io | Gamejolt

bnl

Yo esto siempre lo he hecho de la forma que te han comentado: por capas.
Tendrias 3 capas.
La primera a dibujar seria la del mapa donde dibujarias todo salvo (1 2)
Luego tendrias la capa de personajes donde dibujarias a los personajes. Y finalmente dibujarias la capa donde estaria (1 2). Evidentemente esta ultima capa seria una matriz de las mismas dimensiones que la primera pero que solo tendria establecidas esas dos casillas, el resto serian 0, -1 o el valor que quieras para indicar que esa casilla no se ha de dibujar

Mi web: http://www.brausoft.com/
No sabían que era imposible, así que lo hicieron.

vib

Mas o menos ya voy haciendo...
A todas las clase animanacion " que es donde genero lo que se imprime" he creado una variable de prioridad.. que va de 0 asta un max puesto como constante.
Luego gerero en el loop la funcion de generar_prioridad que simplemente me comprueba que animaciones son visibles para imprimir en pantalla poniendome la prioridad las alta asta la mas baja en una array.
Si 2 prioridades son iguales que compruebe que y+h es mas grande y yata.

Vale el metodo de ordenacion ya buscare un algorismo que tengo por aqui de ordenacion rapida...

Luego me a surgido una duda
la ARRAY que contiene lo que se imprimira por pantalla como la genero?

hago un:

animacion orden[] ? y empaquetarle todas las animaciones? guardando su x,y,h,w i valores que no necesito guardar?
o sabeis alguna manera para guardar el orden de otra manera?

Nose tenia pensado hacer una array de animaciones
siendo por ejemplo scroll tiene numero 1, personaje numero 2, objeto1 numero 3 etc
y a la hora de ordenar simplemente tuviera de cojer el numero y no toda la clase.

[EX3]

Cita de: vib en 18 de Diciembre de 2012, 12:50:16 PM
Luego me a surgido una duda
la ARRAY que contiene lo que se imprimira por pantalla como la genero?

hago un:

animacion orden[] ? y empaquetarle todas las animaciones? guardando su x,y,h,w i valores que no necesito guardar?
o sabeis alguna manera para guardar el orden de otra manera?

Nose tenia pensado hacer una array de animaciones
siendo por ejemplo scroll tiene numero 1, personaje numero 2, objeto1 numero 3 etc
y a la hora de ordenar simplemente tuviera de cojer el numero y no toda la clase.
Yo es que no suelo diferenciar entre animaciones, tiles, texto, etc... En mi motor se definen objetos que pueden dibujarse a los cuales les añades despues sus caracteristicas, de esa base obtengo los sprites, que pueden ser animados o no, textos, primitivas (lineas, cajas, etc...).

Yo solia trabajar con listas dinamicas, no con arrays fijos, por lo que el limite no era algo que tener en cuenta salvo que fuera necesario. Yo simplemente añadia un nuevo elemento a la lista, con la informacion necesaria, en cuanto llamaba al metodo Draw() de cada objeto del motor, y despues simplemente llamaba al metodo Draw() del render para que procesara todas las llamadas acumuladas. En dicho proceso:

- Aplico la ordenacion a la lista de menor a mayor (valores negativos seran los primeros en dibujarse).
- Recorro la lista ordenada de principio a fin:
     - Proceso los datos del elemento de turno y hago la llamada para dibujarlo.
- Termino el render.
- Vacio la lista para la proxima pasada del render.

Cita de: vib en 18 de Diciembre de 2012, 12:50:16 PM
Luego gerero en el loop la funcion de generar_prioridad que simplemente me comprueba que animaciones son visibles para imprimir en pantalla poniendome la prioridad las alta asta la mas baja en una array.
Yo esto quizas me complicaria menos si asignara un valor que identificara la altura en el tile que puede pisar el personaje. De esta manera te evitas calculos innecesarios y defines facilmente alturas en tu escenario para ubicar los objetos.

Cita de: vib en 18 de Diciembre de 2012, 12:50:16 PM
Vale el metodo de ordenacion ya buscare un algorismo que tengo por aqui de ordenacion rapida...
Una pregunta importante, ¿en que lenguaje estas programando? por que algunos lenguajes o frameoworks como Java o .NET, sus objetos lista o array ya tienen implementadas funciones base para definir orden en sus elementos, lo cual te quitaria trabajo de encima.

Salu2...
José Miguel Sánchez Fernández
.NET Developer | Game Programmer | Unity Developer

Blog | Game Portfolio | LinkedIn | Twitter | Itch.io | Gamejolt

vib

Lo de la clase animacion es por lo siguiente
tengo clase imagen " que guarda la imagen" clase animacion que hereda de imagen "guardando el rectangulo a imprimir, tamaño, posicion
Luego de animacion sale la clase objeto que es herencia de animacion, sale scroll que es lo mismo...
Luego sale tambien personaje que de hay sale herencia de principal, enemigos

Por eso decia de guardarlo en una array de animacion ya que  al ser herencias...animacion es lo que tienen en comun todo lo que hay en el juego.

Luego el tema de hacer array statica era un ejemplo..realmente lo estoy haciendo todo con vectores menos el mapa que utilizo un matriz de punteros **mapp

El lenguaje es c++ y la libreria aunque en esta duda no es importante,creo, es SDL.
La verdad esque le he dado varias vueltas y la manera mas "eficiente que se me ocurre" aunque no me gusta es la siguiente:
PD:no he recurrido a otra manera porque no acabo de entender bien lo que me deciis...creo.

Hago una clase Juego
private: vectores de: scroll,personaje,objeto,enemigos,escenario"complementos del mapa rollo arboles etc"
(todo esos vectores son las clases que estan en el juego creados, si aparece un nuevo enemigo se añadira a vector enemigo y asi...)
Luego la clase juego aparte de tener todo lo que hay en el juego en vectores, pondre tambien un:

vector <animacion>mostrar

Y lo que hago es: un metodo que gestione el orden

En la clase animacion terdra un
int prioridad que va de 0 a un max contante siendo por ejemplo 0 imprime abajo, 3 lo de mas arriba
mapa capa0=0
objeto=1
personaje=2
enemigo=2
escenario=2
mapa capa1=3

Teniendo esto, en el metodo gestor comprovare uno a uno todos los vectores que contiene todo el material que hay en el juego para comprovar si aparece en pantalla o no, siendo una variable de
bool visible=true/false

si es true, lo añadimos al vector mostrar

mientras haga esto, si añado un elemento al vector mostrar, si esta vacio añado sin comprobar si hay elemento entonces miro si es la prioridad mas alta i asi haciendolo con algun metodo como quick short o nuse
Luego teniendo el vector mostrar ordenado con el 1r valor es el de menos valor que sera el 1r a imprimir i asi..
Si veo 2 elementos con misma prioridad (personaje,escenario,enemigos) entonces compruebo que elemento esta mas abajo de la pantalla y ese entonces es quien tiene mas prioridad.

Luego una vez hecho esto, llamo al metodo de dibujar, donde dibujo todo lo del vector mostrar.

Esta es la manera que se me ha ocurrido dandole vueltas.
Nose si se entiende espero que si xD
Y nose...no me convence mucho esta manera asi que alguna opinion al respecto lo agradeceria :D

[EX3]

#11
Cita de: vib en 19 de Diciembre de 2012, 12:45:09 AM
Lo de la clase animacion es por lo siguiente
tengo clase imagen " que guarda la imagen" clase animacion que hereda de imagen "guardando el rectangulo a imprimir, tamaño, posicion
Luego de animacion sale la clase objeto que es herencia de animacion, sale scroll que es lo mismo...
Luego sale tambien personaje que de hay sale herencia de principal, enemigos

Por eso decia de guardarlo en una array de animacion ya que  al ser herencias...animacion es lo que tienen en comun todo lo que hay en el juego.
La lista de elementos a dibujar de la que te hablaba no contiene exactamente elementos u objetos de tu juego, solo contiene los parametros a dibujar correspondientes a ese ciclo concreto de la escena a dibujar. Piensa que tu no dibujas una animacion, dibujas el fotograma correspondiente a ese tiempo concreto con unas transformaciones y propiedades concretas, y esto da igual que al final sea un tile, un sprite, un texto, o una linea, basicamente es una llamada al render del framework que estes usando.

Lo que tendrias que hacer, o al menos lo que yo hice, es definir una estructura generica que pudiera almacenar tal informacion como: tipo (sprite, texto, linea, etc...), textura, region a dibujar, posicion, coordenada Z (para ordenar), escala, color, espejado, etc, etc... y la lista de renderizado deberia ser de esta estructura. Luego, en el momento de dibujar la escena solo deberias recorrer dicha lista y procesar los parametros de cada elemento añadido (segun el tipo que defina el elemento).

Cada metodo Draw() de los objetos dibujables de tu juego simplemente añade esos parametros un elemento nuevo del array, sin importar la posicion dentro del array, de eso ya nos encargaremos antes de procesar la lista con el algoritmo de ordenacion.

De esta manera, si te fijas, puedes organizar el codigo de tu juego como quieras y más comodo te sea, ya que no interferira con el proceso de render, y de esta forma puedes tener bien sepapara la logica del dibujo sin romperte la cabeza en como realizar correctamente el orden de llamadas de dibujo, solo te tienes que preocupar de asignar el valor deseado al parametro de ordenacion o coordenada Z.

No se si se entiende un poco mejor ahora la idea que trataba de exponer, que entiendo puede ser un poco compleja asi explicada.

Salu2...
José Miguel Sánchez Fernández
.NET Developer | Game Programmer | Unity Developer

Blog | Game Portfolio | LinkedIn | Twitter | Itch.io | Gamejolt

vib

Bueno de momento lo dejo como he dicho
Mas o menos lo he planteado de manera como he dicho
Lo envez de hacer una array para ordenar las prioridades a imprimir en pantalla
hacer N arrays, donde N es el valor maximo de prioridad siendo z por ejemplo va de 0 a 3
hare array de 3 posiciones quedandose en la posicion 0 las prioridades de 0 la de 1 de 1 i asi
luego ala hora de ordenare seran arrays con muchas menos posiciones y creo que resultara mas rapido.

Por cierto he implementado el algorismo de ordenacion merme sort, siempre he usado el quick short pèro veo que este es mas estable xD
Bueno a todo esto gracias la verdad esque me habeis dado las ideas que necesitaba para continuar gracias :D

[EX3]

Cita de: vib en 19 de Diciembre de 2012, 09:01:06 PM
Lo envez de hacer una array para ordenar las prioridades a imprimir en pantalla
hacer N arrays, donde N es el valor maximo de prioridad siendo z por ejemplo va de 0 a 3
hare array de 3 posiciones quedandose en la posicion 0 las prioridades de 0 la de 1 de 1 i asi
luego ala hora de ordenare seran arrays con muchas menos posiciones y creo que resultara mas rapido.
Lo de crear tantos arrays como capas de dibujo vas a usar es el metodo que utilizo en mi vieja libreria para desarrollo de juegos (para simular eje Z para ordenar las llamadas) y el metodo que utilice en mi ultimo motor en XNA (más que nada por que al tenerlo separado por listas me es posible aplicar transformaciones y efectos a cada capa independientemente de como este armada la escena). Lo bueno de usar este metodo es que te evitas tener que implementar ordenacion alguna, simplemente ejecutas cada array secuencialmente y listos.

Sobre rendimiento, salvo que vayas a dibujar una millonada de sprites en pantalla, el metodo de la lista unica con ordenacion, si su metodo de ordenacion esta bien implementado, no deberia darte problemas de rendimiento, asi que ahi poca diferencia vas a notar entre un metodo y otro.

Salu2...
José Miguel Sánchez Fernández
.NET Developer | Game Programmer | Unity Developer

Blog | Game Portfolio | LinkedIn | Twitter | Itch.io | Gamejolt






Stratos es un servicio gratuito, cuyos costes se cubren en parte con la publicidad.
Por favor, desactiva el bloqueador de anuncios en esta web para ayudar a que siga adelante.
Muchísimas gracias.