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