Tilengine - The 2D retro graphics engine forum

Full Version: como crear sistema de colisiones
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Pages: 1 2
Hola otra vez. Biggrin

Creo otro tema para no mezclar cosas.He creado otro ejemplo para hacer las pruebas de las colisiones y tengo la clase jugador y otras dos clase para los enemigos.Tambien tengo dos archivos ,una para la colision con distancia y otro para colision con rectangulos que de momento no he introducido nada.

En el ejemplo de distancia el jugador tiene el metodo distancia para usarlo en cualquier metodo y tengo creado dos metodos para la colision con el enemigo 1 y otro para el enemigo 2,el problema que tengo es que cuando estoy usando los dos metodos solo funciona el ultimo,por eso en el metodo colision enemigo 1 tengo un if con dos or y ahi me funciona bien pero solo tengo dos enemigos distintos,si tuviera 20 enemigos de distintas clases tendria que crear 20 or enlazados.

El archivo sobre colision con rectangulos pues de momento no tiene nada porque tienes que aclararme dos cosas,la primera ya te lo he preguntado en el otro tema,pero te lo pregunto otra vez.¿Como obtengo el ancho y el largo de sprite?.

La otra cosa que no me queda clara es algo de la pagina genbeta que me pasates,en la teoria sobre colisiones hay una variable llamada "P" que representa un punto 2d(x,y) ,luego si miras el metodo collide de la clase rect,esta tiene self.p.x y self.p.y.Si la variable "P" ya tiene la "X" y la "Y",de donde saca el self.p.y y self.p.x.

Te dejo el archivo para que lo mires cuando puedas,y corrijas lo que te paresca.
https://drive.google.com/file/d/1WaHUMVd...sp=sharing
Buenas!

Manera rápida de resolverlo sobre lo que tienes: la función isinstance() acepta una tupla (lista inmutable) de clases que quieres comprobar. Por tanto sólo necesitas un único método colisiónEnemigo() con la siguiente forma:

Code:
def colisionEnemigo(self):
    for actor in actores:
        if(isinstance(actor,(Enemigo, Enemigo2)) and self.distancia(actor) < 100):
            engine.sprites[actor.sprite].set_scaling(1,1)
        else:
            engine.sprites[actor.sprite].set_scaling(2,2)

Fíjate en la llamada a isinstance(actor,(Enemigo, Enemigo2)), cómo pregunta por varias clases a la vez.

No entiendo la duda que tienes con el punto de genbeta

Code:
self.p.x

self es el rectángulo, que tiene un miebro llamado p de tipo Punto, que a su vez contiene un miembro llamado x. X pertenece a Punto, no a Rect.
Vaya!!!,que chula la funcion isinstance(),eso me resuelve el problema para mas objetos.Sobre lo de la colision rectangular,primero voy a intentar hacerlo solo y cuando tenga algo funcional te comento.

Pero si tengo una cosa que comentar,prueba el ejemplo que te he pasado y mueve el jugador a los bordes de la pantalla,por ejemplo...Muevete a la izquierda de la pantalla y cuando este en el borde pulsa a la izquierda y arriba,veras que el sprite se mete un poco hacia adentro.Esto pasa en todos los lados menos en uno,tal vez un bug de tilengine o un error en mi programacion.
Buenos días!

He mirado el efecto que dices, parece que hay dos cosas que no están relacionadas.

En tu código, tienes la lógica de movimiento al revés: primero estableces la posición del sprite con el valor actual, y luego actualizas las coordenadas, debería ser lo contrario: primero la variable y luego haces efectivo el cambio. Esto provoca un pequeño "salto" cada vez que cambias la dirección de movimiento del sprite:

Code:
def mover(self):
    if(ventana.get_input(tilengine.Input.LEFT) and self.x > 8):
        self.x -= self.velocidad
        engine.sprites[self.sprite].set_position(self.x,self.y)
    elif(ventana.get_input(tilengine.Input.RIGHT) and self.x < 608):
        self.x += self.velocidad
        engine.sprites[self.sprite].set_position(self.x,self.y)
    if(ventana.get_input(tilengine.Input.UP) and self.y > 16):
        self.y -= self.velocidad
        engine.sprites[self.sprite].set_position(self.x,self.y)
    elif(ventana.get_input(tilengine.Input.DOWN) and self.y < 430):
        self.y += self.velocidad
        engine.sprites[self.sprite].set_position(self.x,self.y)

En cuanto al efecto del sprite que se mete un poco por el borde izquierdo, de entrada no le encuentro explicación, puede ser un bug dentro de tilengine. He comprobado que cuando estableces la coordenada x=0 correctamente, en efecto aparece ligeramente desplazado. Tengo que depurarlo. Buena observación! Wink
Descubierto el tema del sprite desplazado:

No es un bug, es por el factor de escala. Los sprites se escalan desde el centro. Como estás aplicando un factor de escalado de x2, el sprite se expande equitativamente en todas direcciones a partir de la posición que le das, con lo que ves que se te mete por el borde, es normal.
Bueno...ya tengo montada la funcion de colision en el archivo colision rectangular y funciona bastante bien,por cierto,habia un error en la formula de la pagina de genbeta.

Te paso el archivo para que lo mires y me digas si esta bien o hay que corregir algo,despues de esto voy a crear un ejemplo sobre niveles,creo dos niveles y al pulsar un boton paso al nivel 2 y en el nivel 2 pulso otro boton para pasar al nivel1,nunca he hecho esto en una libreria asi que seguramente haga una chapuza y te tendre que prenguntar.

Otra cosa,estoy utilizando el ide liclipse,lo que pasa es que cuando copio la carpeta del proyecto y lo pongo en el escritorio al ejecutar el archivo python no funciona,no me pasa con todos y no se que sera.

Dejo de enrrollarme y te paso el proyecto actualizado.
https://drive.google.com/file/d/1WiQeGGk...sp=sharing
Veo que no has aprovechado para corregir eel movimiento, vuelves a tener el saltito al cambiar la dirección. Primero se actualiza la variable y luego se establece el estado del sprite, lo tienes al revés.

Al calcular el rectángulo de colisión hitbox, por qué sumas 16 píxeles al ancho y alto real de los sprites?

Los archivos python (.py) no son ejecutables, no puedes ejecutarlos directamente pulsando doble clic. Tienes que asociarlos con algún lanzador de python que hayas instalado previamente, o abrir un terminal de consola en la carpeta donde tienes el proyecto y ejecutar:

Code:
python colisionRectangulo.py
No habia corregido lo del movimiento porque no habia visto tu respuesta,al desplazar las barras me puso donde decias que habias descurbierto el tema del sprite desplazado y no vi lo de arriba.

He colocado 16 pixeles de mas porque el jugador al colisionar con los otros sprites se tenia que meter en dentro para que detectara la colision,es decir,tenia que llegar casi al centro del otro sprite,parece que si colisiono por debajo hay que entrar un poco para que lo detecte y si lo hago por los lados es casi instantaneo,haz la prueba quitando la suma de 16.

Otra cosa que habras visto es que sigo escribiendo "engine.sprite[self.sprite]...........",tu me enseñastes una manera mas corta pero si lo hago asi,el autocompletado ya no funciona.
No entiendo que el autompletado te falle al usar la sintaxis abreviada, debe de ser algo de la configuración de tu entorno. Yo utilizo VS Code y funciona bien, al hacer self.sprite. me despliega todos los miembros de sprite correctamente
La verdad es que liclipse me suele dar problemas,hace unas semanas estuve trasteando con pygame para aprender mas sobre programacion y luego poder aplicar lo aprendido en tilengine.La cuestion es que algunas cosas me autocompletaban bien pero otras no,tambien estuve probando wing ide pero este me salia el autocompletado en el primer punto,cuando ponia el segundo punto ya no habia autocompletado.

El vscode lo probe hace tiempo cuando tu me recomendastes que lo usara pero no funciona en mi viejo ordenador.En verano o como muy tarde en navidad,sera cuando me compre un ordenador nuevo,segun vea que todo lo que esta pasando se solucione.

Te paso la pagina de wing ide por si te apetece probarlo,tambien te paso la de pyscripter este con pygame no me autocompletaba nada pero todavia no lo he probado con tilengine.

https://wingware.com/
https://sourceforge.net/projects/pyscripter/
Pages: 1 2