Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Detectar Colisiones con Sprites muy irregulares COMO!

Iniciado por trutoman, 11 de Abril de 2008, 03:08:25 PM

« anterior - próximo »

trutoman

Hola a todos , estoy comenzando a desarrollar una libreria para graficos 2D.

Ya he conseguido hacer algunas chorraditas con spritesheets, sprites animados, que se mueven con el teclado y cambian de animacion segun saltas o cambias de direcion (sprites inversos), pero esto me ha llevado mas o menos 1 semana.
Ahora queria dar el salto y empezar en serio y me planteo una gran duda:

Los sprites que estoy utilizando y quiero utilizar en un futuro, son los siguientes:

http://sdb.drshnaps.com/sheets/Media/Other/JumpSuperstars/JUS/Vegeta.png

Como veis son muy chulos pero no son para nada regulares, cada uno tiene su forma, no siguen ninguna cuadricula especifica, he decidido para probar coger dos animaciones, muy irregulares, y mi gran problema es decidir que tipo de detector de colisiones utilizar??,      
     -Con simples rectangulos es imposible,
     -Con pixeles, inviable.
Asi que he estado surfeando un poco y he encontrado algo que me convence mas, usar pequeños rectangulos dentro del cuadrado que engloba al sprite, que serian los encargados de detectar la colision, por ejemplo en un sprite de un personaje dando un puñetazo, el pequeño rectangulo de colision se situaria en el puño, mientras que el rectangulo del resto del  personaje no provocaria colision.

La tecnica la he visto aqui,  

http://lazyfoo.net/SDL_tutorials/lesson18/index.php

y por lo visto es la tecnica utilizada en street fighter2.

Luego tambien he pensado en algo diferente, definir poligonos irregulares para cada sprite de manera que meta al personaje en un poligono,  y luego aplicar deteccion de colision por pixel a los poligonos (lo que no seria tan cargante como aplicarla a los sprites) , lo malo de esto es que pensandolo, deberia crear una clase aparte para gestionar una matriz de poligonos, y esto no se cuanto me llevaria.....

Luego esta lo de multirectangulos....mmmm no se

Pues aqui estoy dandole vueltas al asunto.

Conoceis alguna manera de detectar colisiones en sprites tan variados, o sabeis donde puedo leer documentacion sobre el tema??

THX  :?  :?

Loover

La técnica que comentas es una opción, pero será bastante lenta para sprites tochos. Otra aún mejor es definir sólo aquellas áreas que a ti te interesan, que es lo que he utilizado en IndieLib. Lo que yo hago es definir areas mediante triángulos, rectángulos y círculos. Puedes usar tantos como quieras para un mismo sprite, y puedes además agruparlos por nombres.

Por ejemplo, en un mismo sprite de "Ryu" puedes tener:

- 3 círculos con el id="cabeza"
- 4 triángulos ajustados en las piernas con el id="piernas"
- 1 cuadrado ajustado al puño con el id="puño"

Estas colisiones vienen definidas en un archivo xml.

Además, tengo un sistema de animaciones que vienen definidas mediante xml también. En ellas primero defines todos los frames que vas a usar. Luego creas sequencias usando identificadores a dichos frames. En la sección en la que defines los frames puedes también indicar un archivo de colisión como el que he descrito antes.

De forma que para cada frame, tienes un archivo de colisión distinto.

Luego en el bucle del juego, puedes chequear colisiones mediante grupos. Por ejemplo puede saber si hay una colisión entre el puño de un personaje y la cabeza del otro.

Aún hay más. De hecho puedes rotar, escalar los sprites y las áreas se ajustarán al sprite.

Echale un vistazo al tutorial aquí:

http://www.indielib.com/wiki/index.php?title=Tutorial_08_Collisions, si te bajas la SDK hay un ejemplo con código fuente listo para que lo pruebes.

PD: Si lo que quieres es hacer un juego, te recomiendo que elijas una librería que haga lo que necesitas, y empieces ya. Si lo que quieres es hacer una librería... bueno, bienvenido al club, si quieres más detalles sobre la implementación no tendré problema alguno en dartelos.

Un saludo y bienvenido.
IndieLib Libreria 2.5d utilizando aceleración por hardware para la programación de juegos 2d.
Indie Rover The monkeys are reading!

Tei

Mi experiencia como jugador es que si noto que la colision es de pixeles, no me gusta.  Hay que tener en cuenta que tanto vale como pixel un cabello, que la punta del puño. Entonces terminas interiorizando que un puñetazo al pelo es tan valido como un puñetazo al estomago. Y como que no.
Mejor cualquier tipo de reduccion de la figura, si ademas distingues entre cabeza y estomago, pues ganas features :D

Opinion de jugon, nada mas.

sés

Varios rectángulos para cada gráfico, así de simple... y efectivo. No te compliques la vida, no va a notarse.
Soy indeciso... ¿o no?

Loover

CitarVarios rectángulos para cada gráfico, así de simple... y efectivo. No te compliques la vida, no va a notarse.

Yep, yo empecé con rectángulos que es lo más fácil. Más tarde añadí círculos y triángulos. Ahora mismo puedes envolver cualquier área perfectamente así.

Pero vamos, que si lo que quiere es hacer un juego, y ya se lo doy ya hecho... pues eso que gana, ¿no? :D
IndieLib Libreria 2.5d utilizando aceleración por hardware para la programación de juegos 2d.
Indie Rover The monkeys are reading!

trutoman

La indielib es tuya Loover??   un trabajo impresionante.

Le echare un vistazo, pero es que no quiero perder mucho tiempo probando otras librerias, QUIERO HACER LA MIA !! , uno de los principios de la informatica es no reinventes la rueda, lo se, pero todos sabemos que empezando desde abajo es como se adquiere el conocimiento de verdad, y si ese es un principio de la informatica porque el primer año de carrera nos meten tanto calculo y logica formal !?!?!? que nos enseñen lisp y c++ que al final es lo unico q vale, bueno este tema podia formar otro post aparte, asi que paso de seguir en ello. Habra quien no reinvente la rueda y haga un juego en 2 meses, habra quien la reinvente y este dos años para hacer un juego seguramente menos robusto que el anterior pero bueno yo soy de los segundos.

En cuanto a la tecnica, he estado pensando y efectivamente, con varios rectangulos por frame creo que bastará, parece el mejor desarrollo en relacion calidad/precio, que alguna colision quede un poco falsa, pues nada.
En cuanto a la manera de almacenar los datos (coordenadas de los distinto rectangulos) no entiendo loover porque lo haces con xml y mas en un fichero?? no conlleva este mucha sobrecarga?? yo habia pensado en una public class con una matriz de esas estilo [][]  superligera, para cargar los rectangulos en tiempo de ejecucion.
Imagino que si los almacenas en un fichero y con xml cargaras todos los sprites y rectangulos antes de empezar el juego en si, y esto me lleva a otra pregunta, esto no hace el juego muy pesado en memoria??

Yo de momento he optado por una solucion provisional (pseudocod):


struct cuadro= {int x, int y, int ancho, int alto, int identificador}
struct sprite
{
  vector<struct cuadro> imgs//aqui almacena los recortes del fichero de imagen
  vector<struct cuadro> forms//aqui los cuadros del modelo
}
//El identificador define los  cuadros de  formas que pertenecen a un determinado cuadro de imagenes(frame)


estoy ahora codificandolo, mas adelante si veo q funciona lo pasare a array [][]

Se que es una solucion simple, como la veis? Alguna aportacion, para este sistema multirectangulo??

[EX3]

Cita de: "trutoman"Le echare un vistazo, pero es que no quiero perder mucho tiempo probando otras librerias, QUIERO HACER LA MIA !! , uno de los principios de la informatica es no reinventes la rueda, lo se, pero todos sabemos que empezando desde abajo es como se adquiere el conocimiento de verdad, y si ese es un principio de la informatica porque el primer año de carrera nos meten tanto calculo y logica formal !?!?!?
Mi experiencia personal es que no merece la pena reinventar la rueda ya que no te garantiza si o si adquieras el conocimiento de verdad. De ser asi estariamos todos programando sistemas operativos o drivers graficos desde ensamblador :P Si por mi fuera, de no haber tenido necesidad en su dia, (no habia librerias asi para VB6) no hubiera programado mi propia libreria. Lo unico que vas a lograr es con el tiempo entrar en un circulo vicioso como en el que estamos Loover y yo, acabaras dedicando mas tiempo a desarrollar la libreria que a desarrollar juegos :lol:

Sobre las colisiones, coincido con el uso de cajas. Sera suficiente en la gran mayoria de los casos y menos pesado de calcular que triangulos o poligonos amen de ser sencillo de implementar.

Salu2...

P.D.:
CitarHabra quien no reinvente la rueda y haga un juego en 2 meses, habra quien la reinvente y este dos años para hacer un juego seguramente menos robusto que el anterior pero bueno yo soy de los segundos.
Yo llevo 7 años y sigo sumando :lol:
José Miguel Sánchez Fernández
.NET Developer | Game Programmer | Unity Developer

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

Prompt

Siento no haberme leido todos los post.

- Rectangulo Bounding Box.
- Si hay colisión, aplicar colisión en base al color alpha del sprite. Si colisión por pixel. Sino, subdividir a otros Bouding Box, Cabeza, Torax, Brazo iz1 y der, pierna izq y der. Y luego coger esos pixeles y hacer comparación por alpha, como sale en la web que has dado.

El pixel art, muy bueno. Un saludoooo ( me voy corriendooo :)

trutoman

No entiendo muy bien lo que dice prompt en su ultimo post, yo no utilizo los colorkey de los sprites, lo que he pensado, es una clase para manejar sprites, y luego, aparte, otra clase para manejar una matriz imaginaria donde "pinto" los rectangulos de cada sprite, y es sobre esta matriz imaginaria donde detecto las colisiones, que luego aplico a los graficos. Se entiende?  Sin duda una clase y otra estan relacionadas, dado que los rectangulos de la clase matriz (que representa todo el tablero de juego) dependen de la geometria del sprite en cuestion.
Ya casi lo tengo acabado, el tema del dibujo y animacion de sprites, y me he encontrado con un problemon y no se por donde tirar.
Mi intencion primera es hacer un juegecillo tipo Street fighter II pero con mis sprites de goku and company.
Algunas de mis animaciones, constan de hasta 16 frames distintos, y tengo dudas de si merece la pena introducir una variable para almacenar la velocidad de cambio entre frames, no la velocidad (x,y) del sprite sino del cambio entre cuadro y cuadro de la animacion, digo esto porke por ejemplo si mi sprite goku se convierte en super saiyan, seria bonito que ademas de desplazarse mas rapido, su animacion fuera mas rapida tambien (velocidad entre frame y frame).
Lo malo de introducir esta propiedad seria por ejemplo en los saltos, (en los que mis sprites dan una vuelta sobre si mismos), cambio de frame segun cambio de posicion (x,y) del sprite, si cambio la velocidad de cambio de frame......la velocidad del sprite deberia ir en relacion proporcional con la velocidad de cambio de frames???
Se que es un tema un poco general, pero si teneis alguna idea ....os lo agradeceria.  :lol:

Yo tambien soy de Fuenla !! Ex3

Loover

Si tienes un sistema de animación por sprite es muy importante que permitas definir distintas secuencias de frames y delay para cada uno de dichos frames. Y para las secuencias, lógicamente usa instancias a los frames ya cargados, no vayas a cargar varias veces el mismo frame ;). Esto debería ir totalmente separado de la lógica del juego (velocidad de desplazamiento de tus sprites, etc.)

Insisto en que todo esto que comentas lo tiene ya implementado la IndieLib, sé que soy un poco pesao, pero creo que deberías mirartela. Estaría encantado de echarte un cable con cualquier duda que tuvieras. En realidad, viendo lo que quieres hacer, con la IndieLib lo tendrías montado en unas 2 horas aproximadamente (luego sería cuestión de ajustar las colisiones, etc). Pero bueno, si lo que quieres es aprender a hacerlo, pues adelante, pero documentate bien, bien antes y mira como lo hacen en otros lados. Echale un vistazo a los tutoriales del wiki, sobre todo al de animaciones, pues creo que es una forma bastante limpia de hacerlo como lo hago en la IndieLib, que no es que me lo haya inventado, sino que he ido cogiendo ideas de otros programadores y engines ya existentes. Mirate estos dos tutos:

http://www.indielib.com/wiki/index.php?title=Tutorial_04_IND_Animation
http://www.indielib.com/wiki/index.php?title=Tutorial_08_Collisions

CitarEn cuanto a la manera de almacenar los datos (coordenadas de los distinto rectangulos) no entiendo loover porque lo haces con xml y mas en un fichero?? no conlleva este mucha sobrecarga?? yo había pensado en una public class con una matriz de esas estilo [][] superligera, para cargar los rectángulos en tiempo de ejecucion.
¿Sobrecarga? ¿Qué sobrecarga? Defines tus colisiones en un fichero xml por frame y luego las cargas todas de una vez definidos en otro fichero de animación. Mirate el tutorial del wiki. De todos modos, también puedes definir áreas mediante código (o eliminarlas) durante la ejecución. Todo esto se almacena en una estructura de datos propia, con varias clases (Frame, Sequence, Animation, etc). Bajate la SDK y prueba el benchmark en el que renderizo una pechá de ovnis animados descartando automáticamente los que quedan fuera, aunque rotes o hagas zoom a la cámara (utiliza los botones del ratón y la rosca para variar la cámara). Por cierto, la cámara también te vendría bien en un juego de este tipo.

CitarImagino que si los almacenas en un fichero y con xml cargaras todos los sprites y rectangulos antes de empezar el juego en si, y esto me lleva a otra pregunta, esto no hace el juego muy pesado en memoria??
Qué va hombre. ¿Cómo van a ser pesados 3 ints por triángulo, 4 ints por rectángulo y 2 ints por círculo? Ni aunque definieras 5000 áreas por sprites (lo cuál es una locura) ocuparía en memoria más que unos cuantos kb. Lo que ocupan, como siempre en estos casos, son los recursos gráficos (las imágenes).
IndieLib Libreria 2.5d utilizando aceleración por hardware para la programación de juegos 2d.
Indie Rover The monkeys are reading!

trutoman

Gracias Loover, he estado mirando tu libreria y bueno, hay cosas que no entiendo, esta muy por encima de mi nivel como programador, y si ya se lo de la rueda, pero te aseguro que disfruto mas programando una libreria, que haciendo un juego con una libreria existente, eso es casi como utilizar uno de esos editores de aventuras graficas, que te lo dan todo hecho
(un dia un colega albañil me dijo que sabia programar juegos, me sorprendio , le pregunte como lo hacia y descubri los editores estos de aventuras graficas donde lo mas complejo a usar es un "if then else")

Y bueno que quieres decir que a cada velocidad posible del sprite asocie una secuencia de cambios distinta entre frames?, eso seria poco escalable, tiene que existir alguna triquiñuela matematica para ajustarlo, quiero decir:

Si mi animacion tiene 5 frames y quiero que llegue al mismo sitio en menos tiempo seria tan simple como  ajustar el tiempo entre frames con el tipico "frecuencia = 1/Periodo" no?

Y bueno en cuanto a lo de agrupacion de rectangulos de colision, estoy implementandolo yo tambien, es una muy buena idea, lo malo es que me estoy liando un poquillo con el uso de memoria de estos elementos, al haber 20 sprites cargados hay unos 100 rectangulos y estoy intentando que el uso de memoria sea optimo, ya sabeis "cuando no y cuando si hacer destroy" tengo problemas serios, pero saldre adelante  :lol:

Vaya has editado justo cuando yo publique ahora lo leo.......
Editado respondiendo a la edicion de loover:

Gracias por los links, ahora salgo de currar luego me los miro.
Si es verdad que nunca esas estructuras pesarian en memoria que tonteria, lo que pasa es que mi profesor de prog I y II insistio mucho con nosotros en la gestion limpia de memoria y siempre me ha obsesionado esto.

Loover

Sorry, tengo la manía de editar muchísimo, es como si hicera un borrador y luego le voy añadiendo cosas. Lo malo es cuando la otra persona está también mirando el foro, claro :P

CitarGracias Loover, he estado mirando tu libreria y bueno, hay cosas que no entiendo, esta muy por encima de mi nivel como programador, y si ya se lo de la rueda, pero te aseguro que disfruto mas programando una libreria, que haciendo un juego con una libreria existente, eso es casi como utilizar uno de esos editores de aventuras graficas, que te lo dan todo hecho.
(un dia un colega albañil me dijo que sabia programar juegos, me sorprendio , le pregunte como lo hacia y descubri los editores estos de aventuras graficas donde lo mas complejo a usar es un "if then else")
Un tanto contradictorio, ¿no? No puede estar por encima de tu nivel y a la vez ser tan fácil que te lo de todo hecho :). Visto con lo que estás, te sobra nivel :). En realidad está hecha para estar a un nivel hipersencillo, no tendrías problemas en usarla. Aún así no es un gamemaker, es un framework, está pensada para gente que como mínimo tenga nociones de c++. Por lo que es mucho más potente que un parser de aventuras gráficas. Pero bueno, voliendo al hilo, tu mismo con tu mecanismo, faltaría más. Ya dejo de venderte la moto, jeje.

CitarY bueno que quieres decir que a cada velocidad posible del sprite asocie una secuencia de cambios distinta entre frames?, eso seria poco escalable, tiene que existir alguna triquiñuela matematica para ajustarlo, quiero decir:

Si mi animacion tiene 5 frames y quiero que llegue al mismo sitio en menos tiempo seria tan simple como ajustar el tiempo entre frames con el tipico "frecuencia = 1/Periodo" no?
¿Mande? No era eso lo que quería decir (ni siquiera lo entiendo). Mirate como lo hago en los tutos que te he puesto. Resumiento, tu te creas para una misma lista de frames, todas las secuencias que vayas a necesitar. Cada frame de esas secuencias es una instancia a un frame ya cargado. Ejemplo:
Tienes 5 frames
Secuencia0 = 0, 1, 2, 2, 3, 4
Secuencia1 = 1, 1, 2, 2, 0

Si miras los xml del tutorial que te he puesto, verás que no solo defino las secuencias, sino también un "delay" para cada frame. Vamos, que para tu animación de goku tendría dos secuencias, una normal, y otra que llamaría "rápido" cuyos frames tienen un delay menor. Y en todo momento solo tendría cargados en memoria los sprites que he usado para definir todas las secuencias que yo he querido. Los frames de las sencuencias, serían instancias a dichos frames cargados. Luego, totalmente separado de este sistema, en la lógica del juego, tendría una máquina de estados, o un sistema de scripts ejecutándose en paralelo usando Lua, o un sistema de callbacks, o lo que te de más rabia implementar para hacer la lógica :D... y dependiendo del estado actual del jugador mostraría una secuencia de animación u otra. Todo separadito y bien chulo :D

Citary estoy intentando que el uso de memoria sea optimo, ya sabeis "cuando no y cuando si hacer destroy" tengo problemas serios, pero saldre adelante
No tiene mucho misterio, carga la animación cuando la necesites, libera cuando no lo vayas a usar, y listo. No te compliques. Por ejemplo, carga entre fases, etc. Lo típico.
IndieLib Libreria 2.5d utilizando aceleración por hardware para la programación de juegos 2d.
Indie Rover The monkeys are reading!

[EX3]

Cita de: "trutoman"Yo tambien soy de Fuenla !! Ex3
Otra competencia de librerias en el foro y encima en mi ciudad, innaudito! :lol:

Cita de: "trutoman"No tiene mucho misterio, carga la animación cuando la necesites, libera cuando no lo vayas a usar, y listo. No te compliques. Por ejemplo, carga entre fases, etc. Lo típico.
Como dice Loover, centra toda la carga de creacion y destruccion de recursos y objetos en los momentos de carga y descarga de niveles/escenas/intros/menus. De esta forma, durante el juego no sufriras penalizaciones de rendimiento ni problemas de optimizacion serios con la memoria, pero vamos, esto queda ajeno a la libreria/motor/framework, depende mas del diseño del motor o el juego en si.

Cita de: "trutoman"te aseguro que disfruto mas programando una libreria, que haciendo un juego con una libreria existente, eso es casi como utilizar uno de esos editores de aventuras graficas, que te lo dan todo hecho
Hombre, una cosa es un gamemaker, centrado en un genero concreto y con sus limitaciones, y otra es un conjunto de librerias y herramientas de proposito general y sin apenas limitaciones. Todo depende mas de si se lo que uno busca es desarrollar tecnologia o desarrollar juegos. Para lo segundo es mas factible y productivo (y satisfactorio, creeme) empezar a desarrollar el juego sobre una herramienta que te de la base hecha a tener que estudiar e implementar la tuya propia.

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

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

Loover

CitarTodo depende mas de si se lo que uno busca es desarrollar tecnologia o desarrollar juegos

Ese es el quid de la cuestión. ¿Qué quieres hacer? ¿Un juego? ¿Una librería?

Aunque tampoco es malo un híbrido: "usar SDL pero hacer yo mismo mi sistema de animaciones por xml con colisiones por sprite". Si te hace ilusión, ¿por qué no? :D Y haces muy bien en preguntar cuál sería la manera óptima de hacerlo. Así se aprende.

Vamos, que usar IndieLib para hacer tu juego no sería como usar el Mugen, ¿eh? Solo que ya tendrías hecho el sistema de animaciones, colisiones y cámaras (para poder hacer un zoom cuando los jugadores se separasen, que eso queda muy chulo, jaja). Te podrías centrar más en la lógica del juego de esta manera: eso no te lo quita nadie (excepto Mugen, pero entonces si que perderías muchísima libertad).
IndieLib Libreria 2.5d utilizando aceleración por hardware para la programación de juegos 2d.
Indie Rover The monkeys are reading!

trutoman

Uff que de cosas.

1- Me dice ex3 que si quiero hacer un juego o una libreria, pues... las dos cosas, en realidad lo que quiero es aprender a programar y que mejor manera que haciendo un juegillo, eso si en vez de hacerlo en un simple main como hay por ahi miles de ejemplos de tetris y demas, quiero hacerlo desarrollando librerias que me sirvan para mas adelante y bueno como decis, imagino que es un proceso que nunca acaba, simpre seguire retocando mi codigo, imagino, la perfeccion no existe.

2- En cuanto a loover, no se me habia ocurrido !!, que el delay forme parte de la clase animacion y no donde yo tenia pensado meterla, en una clase para manejar eventos de tiempo. Gracias ! lo hare asi.

3- Ya se que no es lo mismo que los editores de aventuras graficas, habia dicho "es casi como" y se que la looverlib no te lo da todo hecho pero usarla me quitaria lo mas divertido de el desarrollo de un juego.

4- Nunca habia pensado en desarrollar el sistema de camara, de momento en mis sprites no he implementado nada para proporciones o tamaños, y de momento no quiero ni pensarlo !! creo que eso podria ser un infierno.

5- En cuanto a lo de la carga entre fase y fase, si esa era mi intencion cargar antes de jugar, lo q dudaba era si por ejemplo en una parte del juego hay 10 personajes que han usado cada uno 10 animaciones distintas mantener todos los sprites cargados con todas las animaciones, es que no me he puesto a calcular cuanto ocuparia esto en memoria, no pesa demasiado no ???, creo que cargare todas las animaciones posibles a utilizar antes de empezar.

Como habia imaginado, mas me meto mas se complica esto, lo dificil que es hacer que un "queco" se mueva por la pantalla!! Si seguro que despues de todo mi trabajo acabo utilizando la looverlib!!

Thx por vuestros post !!  :lol: da gusto encontrar de vez en cuando un foro activo de verdad !  :D :?






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.