BUG cámara y botones fijos [ SOLUCIONADO ]

Estimadxs,

El contexto es: arranca la aplicación, tengo dos botones en pantalla ( fijados, no deberían moverse al moverse la cámara)

cuando muevo la cámara los botones efectivamente se quedan en su lugar, no así el ROLL OVER y dejan de funcionar como botones, es como si solo quedara fija la imagen del actor pero el funcionamiento interno se moviera.
muestro unas imágenes :

Al presionar el botón la cámara se corre 200 px a la derecha. se puede ver los “radios de colisión” de los botones que se fueron con la cámara, creo que es parte del problema…

1 Like

Oh, efectivamente @diegoacco, es un bug que tengo que mirar para resolver… Voy a investigarlo más tarde a ver si logro resolverlo, te escribo en cuanto tenga alguna novedad.

¡ Gracias por reportarlo !

1 Like

gracias a vos @hugoruscitti !

Ahí pude corregir el bug [1], me encontré que había dos problemas con las coordenadas cuando un actor debería quedar fijo en pantalla:

  • Los eventos del mouse se trataban como coordenadas del escenario (en lugar de ser absolutas) cuando el actor estába fijo.
  • El dibujado de las figuras de colisión no tenía en cuenta que el actor podría estar configurado como fijo.

Estos arreglos van a estar incluídos en la próxima versión de pilas, junto a otro arreglo para espejar actores.

De todas formas, si tu juego va dirigido a personas que posiblemente no tengan esta nueva versión de pilas, igualmente vas a poder incluir estos arreglos directamente en tu código.

Te dejo el código que vas a poder incluir directamente en tu juego, podés agregar el siguiente código justo debajo de “import pilasengine” o directamente en un archivo separado (e importándolo desde el script principal). Lo importante es que se ejecute al principio, porque sobre-escribe métodos internos de pilas que necesitaban corregirse:

import math
import Box2D as box2d
PPM = 30

def colisiona_con_un_punto_patch(self, x, y):
    if not self.fijo:
        x = x + self.pilas.escena_actual().camara.x
        y = y + self.pilas.escena_actual().camara.y

    return (self.izquierda <= x <= self.derecha and self.abajo <= y <= self.arriba)    


def realizar_dibujado_patch(self, painter):
    grosor = 1
    cuerpos = self.pilas.fisica.mundo.bodies

    painter.save()
    self.pilas.camara.aplicar_transformaciones_completas(painter)

    for cuerpo in cuerpos:

        for fixture in cuerpo:

            # cuerpo.type == 0 → estatico
            # cuerpo.type == 1 → kinematico
            # cuerpo.type == 2 → dinamico

            if fixture.userData['sensor']:
                if cuerpo.awake:
                    self._definir_trazo_verde(painter)
                else:
                    self._definir_trazo_verde_oscuro(painter)
            else:
                if cuerpo.awake:
                    self._definir_trazo_blanco(painter)
                else:
                    self._definir_trazo_gris(painter)

            shape = fixture.shape

            if isinstance(shape, box2d.b2PolygonShape):
                vertices = [cuerpo.transform * v * PPM for v in shape.vertices]

                actor = fixture.userData.get('actor', None)

                if actor and actor.fijo:
                    dx = self.pilas.camara.x
                    dy = self.pilas.camara.y
                else:
                    dx = 0
                    dy = 0

                self._poligono(painter, vertices, dx=dx, dy=dy, color=colores.blanco, grosor=grosor, cerrado=True)
            elif isinstance(shape, box2d.b2CircleShape):
                (x, y) = cuerpo.transform * shape.pos * PPM

                actor = fixture.userData.get('actor', None)

                if actor and actor.fijo:
                    x += self.pilas.camara.x
                    y += self.pilas.camara.y

                self._angulo(painter, x, y, - math.degrees(fixture.body.angle), shape.radius * PPM)
                self._circulo(painter, x, y, shape.radius * PPM)
            else:
                raise Exception("No puedo identificar el tipo de figura.")

    painter.restore()

def poligono_patch(self, painter, puntos, dx=0, dy=0, color=colores.negro, grosor=1, cerrado=False):
    x, y = puntos[0]

    if cerrado:
        puntos.append((x, y))

    for p in puntos[1:]:
        nuevo_x, nuevo_y = p

        self._linea(painter, x+dx, y+dy, nuevo_x+dx, nuevo_y+dy)
        x, y = nuevo_x, nuevo_y



pilasengine.depurador.ModoFisica.realizar_dibujado = realizar_dibujado_patch
pilasengine.depurador.ModoFisica._poligono = poligono_patch
pilasengine.actores.Actor.colisiona_con_un_punto = colisiona_con_un_punto_patch

Avisanos cualquier cosa.

¡Saludos!

1 - Reparar areas de colisión y gráficos de depuración para actores fijos · Issue #307 · hugoruscitti/pilas · GitHub

1 Like

Genial !
funcionó el código del parche, ojo le agregué pilasengine a las dos referencias a colores:
la línea que dice:
self._poligono(painter, vertices, dx=dx, dy=dy, color=colores.blanco, grosor=grosor, cerrado=True)

quedaría:

self._poligono(painter, vertices, dx=dx, dy=dy, color=pilasengine.colores.blanco, grosor=grosor, cerrado=True)

y la otra:
def poligono_patch(self, painter, puntos, dx=0, dy=0, color=colores.negro, grosor=1, cerrado=False):

quedaría:
def poligono_patch(self, painter, puntos, dx=0, dy=0, color=pilasengine.colores.negro, grosor=1, cerrado=False):

y funciona OK

muchas gracias @hugoruscitti !!

1 Like

Buenisimo!!, gracias por avisar!

1 Like