# PyGame test de excepciones
import pygame
import math
class Motor:
def __init__(self, tam_ventana, jugador, pnjs):
self.__j = jugador
self.__screen = pygame.display.set_mode(tam_ventana)
self.__clock = pygame.time.Clock()
self.__pnjs = pnjs
if pygame.font:
self.__font = pygame.font.SysFont(None, 40)
...
...
def start(self):
self.__dt = 0.0
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
...
...
self.__screen.fill("beige")
if self.__j.vidas <= 0:
self.__escribe("Has muerto.")
else:
self.__mostrar_frame_juego()
...
pygame.display.flip()
self.__dt = self.__clock.tick(60) / 1000
...
...
def __escribe(self, msg):
if pygame.font:
text_surface = self.__font.render(msg, False, (0, 0, 0))
self.__screen.blit(text_surface, (0,0))
...
...
def __mostrar_frame_juego(self):
scr = self.__screen
# Mostrar personajes
pygame.draw.circle(scr, "blue", self.__j.pos, self.__j.tam, self.__j.tam)
for pnj in self.__pnjs:
pygame.draw.rect(scr, "red",
pygame.Rect(pnj.pos.x, pnj.pos.y, pnj.tam, pnj.tam),
pnj.tam)
...
# Info del juego
self.__escribe(f"Vidas: {self.__j.vidas}")
# Movimiento
self.__j.mueve(self.__dt, self.__pnjs, pygame.key.get_pressed())
for pnj in self.__pnjs:
pnj.mueve(self.__dt, self.__j)
...
...
...
class Personaje:
def __init__(self, maxX, maxY, posX, posY, tam):
self.__tam_ventana = (maxX, maxY)
self.__pos = pygame.Vector2(posX, posY)
self.__tam = tam
@property
def pos(self):
return self.__pos
...
@property
def tam(self):
return self.__tam
...
@property
def tam_ventana(self):
return self.__tam_ventana
...
def distancia_a(self, otro):
toret = self.__tam_ventana[0] * 2
if isinstance(otro, Personaje):
mix = self.pos.x + (self.tam / 2)
miy = self.pos.y + (self.tam / 2)
sux = otro.pos.x + (otro.tam / 2)
suy = otro.pos.y + (otro.tam / 2)
xs = (mix - sux) ** 2
ys = (miy - suy) ** 2
toret = math.sqrt(xs + ys)
...
return toret
...
def hay_colision_con(self, otro):
return self.distancia_a(otro) < (self.tam * 2)
...
...
class PersonajeJugador(Personaje):
def __init__(self, maxX, maxY, posX, posY, tam):
super().__init__(maxX, maxY, posX, posY, tam)
self.__vidas = 3
...
@property
def vidas(self):
return self.__vidas
...
def pierde_vida(self):
self.__vidas -= 1
print(f"\aVidas jugador: {self.vidas}")
...
def mueve(self, dt, pnjs, keys):
ancho = self.tam_ventana[0]
alto = self.tam_ventana[1]
try:
if keys[pygame.K_w]:
self.pos.y -= 300 * dt
if self.pos.y < 0:
raise ValueError(('y', self.pos.y))
if keys[pygame.K_s]:
self.pos.y += 300 * dt
if self.pos.y >= alto:
raise ValueError(('y', self.pos.y))
if keys[pygame.K_a]:
self.pos.x -= 300 * dt
if self.pos.x < 0:
raise ValueError(('x', self.pos.x))
if keys[pygame.K_d]:
self.pos.x += 300 * dt
if self.pos.x >= ancho:
raise ValueError(('x', self.pos.x))
for pnj in pnjs:
if self.hay_colision_con(pnj):
raise ValueError((pnj,))
...
...
except ValueError as exc:
self.__corrige_pos(exc.args[0])
...
...
def __corrige_pos(self, datos):
ancho = self.tam_ventana[0]
alto = self.tam_ventana[1]
if datos[0] == 'x':
if datos[1] < 0:
self.pos.x = ancho
elif datos[1] >= ancho:
self.pos.x = 0
...
elif datos[0] == 'y':
if datos[1] < 0:
self.pos.y = alto
elif datos[1] >= alto:
self.pos.y = 0
...
else:
# Colision
self.pierde_vida()
self.pos.y = datos[0].pos.y + 40
self.pos.x = datos[0].pos.x + 40
...
...
...
class PersonajeNoJugador(Personaje):
def __init__(self, maxX, maxY, posX, posY, tam):
super().__init__(maxX, maxY, posX, posY, tam)
...
def mueve(self, dt, jugador):
paso = 50
nuevo_x = paso * dt
nuevo_y = paso * dt
if self.pos.x > jugador.pos.x:
nuevo_x *= -1
...
if self.pos.y > jugador.pos.y:
nuevo_y *= -1
...
self.pos.x += nuevo_x
self.pos.y += nuevo_y
...
...
if __name__ == "__main__":
tam_ventana = (800, 600)
pygame.init()
try:
pygame.font.init()
except (ImportError, NotImplementedError) as exc:
# En ocasiones, no se inicializa font correctamente
print(f"Font module not found: {exc}")
pygame.font = None
j = PersonajeJugador(tam_ventana[0], tam_ventana[1],
tam_ventana[0] / 2, tam_ventana[1] / 2, 20)
pnjs = [
PersonajeNoJugador(tam_ventana[0], tam_ventana[1], 100, 100, 20),
PersonajeNoJugador(tam_ventana[0], tam_ventana[1], 512, 512, 20),
PersonajeNoJugador(tam_ventana[0], tam_ventana[1], 256, 300, 20),
PersonajeNoJugador(tam_ventana[0], tam_ventana[1], 45, 45, 20)
]
m = Motor(tam_ventana, j, pnjs)
m.start()
pygame.quit()
...
IyBQeUdhbWUgdGVzdCBkZSBleGNlcGNpb25lcwoKCmltcG9ydCBweWdhbWUKaW1wb3J0IG1hdGgKCgpjbGFzcyBNb3RvcjoKICAgIGRlZiBfX2luaXRfXyhzZWxmLCB0YW1fdmVudGFuYSwganVnYWRvciwgcG5qcyk6CiAgICAgICAgc2VsZi5fX2ogPSBqdWdhZG9yCiAgICAgICAgc2VsZi5fX3NjcmVlbiA9IHB5Z2FtZS5kaXNwbGF5LnNldF9tb2RlKHRhbV92ZW50YW5hKQogICAgICAgIHNlbGYuX19jbG9jayA9IHB5Z2FtZS50aW1lLkNsb2NrKCkKICAgICAgICBzZWxmLl9fcG5qcyA9IHBuanMKICAgICAgICAKICAgICAgICBpZiBweWdhbWUuZm9udDoKICAgICAgICAgICAgc2VsZi5fX2ZvbnQgPSBweWdhbWUuZm9udC5TeXNGb250KE5vbmUsIDQwKQogICAgICAgIC4uLgogICAgLi4uICAgIAoKCiAgICBkZWYgc3RhcnQoc2VsZik6CiAgICAgICAgc2VsZi5fX2R0ID0gMC4wCiAgICAgICAgcnVubmluZyA9IFRydWUKICAgICAgICAKICAgICAgICB3aGlsZSBydW5uaW5nOgogICAgICAgICAgICBmb3IgZXZlbnQgaW4gcHlnYW1lLmV2ZW50LmdldCgpOgogICAgICAgICAgICAgICAgaWYgZXZlbnQudHlwZSA9PSBweWdhbWUuUVVJVDoKICAgICAgICAgICAgICAgICAgICBydW5uaW5nID0gRmFsc2UKICAgICAgICAgICAgICAgIC4uLgogICAgICAgICAgICAuLi4KICAgICAgICAKICAgICAgICAgICAgc2VsZi5fX3NjcmVlbi5maWxsKCJiZWlnZSIpCiAgICAgICAgICAgIAogICAgICAgICAgICBpZiBzZWxmLl9fai52aWRhcyA8PSAwOgogICAgICAgICAgICAgICAgc2VsZi5fX2VzY3JpYmUoIkhhcyBtdWVydG8uIikKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgIHNlbGYuX19tb3N0cmFyX2ZyYW1lX2p1ZWdvKCkKICAgICAgICAgICAgLi4uCiAgICAgICAgICAgIAogICAgICAgICAgICBweWdhbWUuZGlzcGxheS5mbGlwKCkKICAgICAgICAgICAgc2VsZi5fX2R0ID0gc2VsZi5fX2Nsb2NrLnRpY2soNjApIC8gMTAwMAogICAgICAgIC4uLiAgICAKICAgIC4uLgogICAgCiAgICBkZWYgX19lc2NyaWJlKHNlbGYsIG1zZyk6CiAgICAgICAgaWYgcHlnYW1lLmZvbnQ6CiAgICAgICAgICAgIHRleHRfc3VyZmFjZSA9IHNlbGYuX19mb250LnJlbmRlcihtc2csIEZhbHNlLCAoMCwgMCwgMCkpCiAgICAgICAgICAgIHNlbGYuX19zY3JlZW4uYmxpdCh0ZXh0X3N1cmZhY2UsICgwLDApKQogICAgICAgIC4uLgogICAgLi4uCiAgICAKICAgIGRlZiBfX21vc3RyYXJfZnJhbWVfanVlZ28oc2VsZik6CiAgICAgICAgc2NyID0gc2VsZi5fX3NjcmVlbgogICAgICAgIAogICAgICAgICMgTW9zdHJhciBwZXJzb25hamVzCiAgICAgICAgcHlnYW1lLmRyYXcuY2lyY2xlKHNjciwgImJsdWUiLCBzZWxmLl9fai5wb3MsIHNlbGYuX19qLnRhbSwgc2VsZi5fX2oudGFtKQogICAgICAgIGZvciBwbmogaW4gc2VsZi5fX3BuanM6CiAgICAgICAgICAgIHB5Z2FtZS5kcmF3LnJlY3Qoc2NyLCAicmVkIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBweWdhbWUuUmVjdChwbmoucG9zLngsIHBuai5wb3MueSwgcG5qLnRhbSwgcG5qLnRhbSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcG5qLnRhbSkKICAgICAgICAuLi4gICAgCiAgICAgICAgICAKICAgICAgICAjIEluZm8gZGVsIGp1ZWdvCiAgICAgICAgc2VsZi5fX2VzY3JpYmUoZiJWaWRhczoge3NlbGYuX19qLnZpZGFzfSIpCiAgICAgICAgCiAgICAgICAgIyBNb3ZpbWllbnRvCiAgICAgICAgc2VsZi5fX2oubXVldmUoc2VsZi5fX2R0LCBzZWxmLl9fcG5qcywgcHlnYW1lLmtleS5nZXRfcHJlc3NlZCgpKQogICAgICAgIGZvciBwbmogaW4gc2VsZi5fX3BuanM6CiAgICAgICAgICAgIHBuai5tdWV2ZShzZWxmLl9fZHQsIHNlbGYuX19qKQogICAgICAgIC4uLgogICAgLi4uICAgICAgICAKLi4uCgoKY2xhc3MgUGVyc29uYWplOgogICAgZGVmIF9faW5pdF9fKHNlbGYsIG1heFgsIG1heFksIHBvc1gsIHBvc1ksIHRhbSk6CiAgICAgICAgc2VsZi5fX3RhbV92ZW50YW5hID0gKG1heFgsIG1heFkpCiAgICAgICAgc2VsZi5fX3BvcyA9IHB5Z2FtZS5WZWN0b3IyKHBvc1gsIHBvc1kpCiAgICAgICAgc2VsZi5fX3RhbSA9IHRhbQogICAgCiAgICBAcHJvcGVydHkKICAgIGRlZiBwb3Moc2VsZik6CiAgICAgICAgcmV0dXJuIHNlbGYuX19wb3MKICAgIC4uLgogICAgCiAgICBAcHJvcGVydHkKICAgIGRlZiB0YW0oc2VsZik6CiAgICAgICAgcmV0dXJuIHNlbGYuX190YW0KICAgIC4uLgogICAgCiAgICBAcHJvcGVydHkKICAgIGRlZiB0YW1fdmVudGFuYShzZWxmKToKICAgICAgICByZXR1cm4gc2VsZi5fX3RhbV92ZW50YW5hCiAgICAuLi4KICAgIAogICAgZGVmIGRpc3RhbmNpYV9hKHNlbGYsIG90cm8pOgogICAgICAgIHRvcmV0ID0gc2VsZi5fX3RhbV92ZW50YW5hWzBdICogMgogICAgICAgIAogICAgICAgIGlmIGlzaW5zdGFuY2Uob3RybywgUGVyc29uYWplKToKICAgICAgICAgICAgbWl4ID0gc2VsZi5wb3MueCArIChzZWxmLnRhbSAvIDIpCiAgICAgICAgICAgIG1peSA9IHNlbGYucG9zLnkgKyAoc2VsZi50YW0gLyAyKQogICAgICAgICAgICBzdXggPSBvdHJvLnBvcy54ICsgKG90cm8udGFtIC8gMikKICAgICAgICAgICAgc3V5ID0gb3Ryby5wb3MueSArIChvdHJvLnRhbSAvIDIpCiAgICAgICAgICAgIHhzID0gKG1peCAtIHN1eCkgKiogMgogICAgICAgICAgICB5cyA9IChtaXkgLSBzdXkpICoqIDIKICAgICAgICAgICAgdG9yZXQgPSBtYXRoLnNxcnQoeHMgKyB5cykKICAgICAgICAuLi4KICAgICAgICAKICAgICAgICByZXR1cm4gdG9yZXQKICAgIC4uLgogICAgCiAgICBkZWYgaGF5X2NvbGlzaW9uX2NvbihzZWxmLCBvdHJvKToKICAgICAgICByZXR1cm4gc2VsZi5kaXN0YW5jaWFfYShvdHJvKSA8IChzZWxmLnRhbSAqIDIpCiAgICAuLi4KLi4uCiAgIApjbGFzcyBQZXJzb25hamVKdWdhZG9yKFBlcnNvbmFqZSk6CiAgICBkZWYgX19pbml0X18oc2VsZiwgbWF4WCwgbWF4WSwgcG9zWCwgcG9zWSwgdGFtKToKICAgICAgICBzdXBlcigpLl9faW5pdF9fKG1heFgsIG1heFksIHBvc1gsIHBvc1ksIHRhbSkKICAgICAgICBzZWxmLl9fdmlkYXMgPSAzCiAgICAuLi4KICAgIAogICAgQHByb3BlcnR5CiAgICBkZWYgdmlkYXMoc2VsZik6CiAgICAgICAgcmV0dXJuIHNlbGYuX192aWRhcwogICAgLi4uCiAgICAKICAgIGRlZiBwaWVyZGVfdmlkYShzZWxmKToKICAgICAgICBzZWxmLl9fdmlkYXMgLT0gMQogICAgICAgIHByaW50KGYiXGFWaWRhcyBqdWdhZG9yOiB7c2VsZi52aWRhc30iKQogICAgLi4uICAgIAogICAgCiAgICBkZWYgbXVldmUoc2VsZiwgZHQsIHBuanMsIGtleXMpOgogICAgICAgIGFuY2hvID0gc2VsZi50YW1fdmVudGFuYVswXQogICAgICAgIGFsdG8gPSBzZWxmLnRhbV92ZW50YW5hWzFdCiAgICAgICAgCiAgICAgICAgdHJ5OgogICAgICAgICAgICBpZiBrZXlzW3B5Z2FtZS5LX3ddOgogICAgICAgICAgICAgICAgc2VsZi5wb3MueSAtPSAzMDAgKiBkdAogICAgICAgICAgICAgICAgaWYgc2VsZi5wb3MueSA8IDA6CiAgICAgICAgICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigoJ3knLCBzZWxmLnBvcy55KSkKICAgICAgICAgICAgaWYga2V5c1tweWdhbWUuS19zXToKICAgICAgICAgICAgICAgIHNlbGYucG9zLnkgKz0gMzAwICogZHQKICAgICAgICAgICAgICAgIGlmIHNlbGYucG9zLnkgPj0gYWx0bzoKICAgICAgICAgICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCgneScsIHNlbGYucG9zLnkpKQogICAgICAgICAgICBpZiBrZXlzW3B5Z2FtZS5LX2FdOgogICAgICAgICAgICAgICAgc2VsZi5wb3MueCAtPSAzMDAgKiBkdAogICAgICAgICAgICAgICAgaWYgc2VsZi5wb3MueCA8IDA6CiAgICAgICAgICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigoJ3gnLCBzZWxmLnBvcy54KSkKICAgICAgICAgICAgaWYga2V5c1tweWdhbWUuS19kXToKICAgICAgICAgICAgICAgIHNlbGYucG9zLnggKz0gMzAwICogZHQKICAgICAgICAgICAgICAgIGlmIHNlbGYucG9zLnggPj0gYW5jaG86CiAgICAgICAgICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigoJ3gnLCBzZWxmLnBvcy54KSkKICAgICAgICAgICAgICAgIAogICAgICAgICAgICBmb3IgcG5qIGluIHBuanM6CiAgICAgICAgICAgICAgICBpZiBzZWxmLmhheV9jb2xpc2lvbl9jb24ocG5qKToKICAgICAgICAgICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yKChwbmosKSkKICAgICAgICAgICAgICAgIC4uLgogICAgICAgICAgICAuLi4gICAgCiAgICAgICAgZXhjZXB0IFZhbHVlRXJyb3IgYXMgZXhjOgogICAgICAgICAgICBzZWxmLl9fY29ycmlnZV9wb3MoZXhjLmFyZ3NbMF0pCiAgICAgICAgLi4uCiAgICAuLi4KICAgIAogICAgZGVmIF9fY29ycmlnZV9wb3Moc2VsZiwgZGF0b3MpOgogICAgICAgIGFuY2hvID0gc2VsZi50YW1fdmVudGFuYVswXQogICAgICAgIGFsdG8gPSBzZWxmLnRhbV92ZW50YW5hWzFdCiAgICAgICAgCiAgICAgICAgaWYgZGF0b3NbMF0gPT0gJ3gnOgogICAgICAgICAgICBpZiBkYXRvc1sxXSA8IDA6CiAgICAgICAgICAgICAgICBzZWxmLnBvcy54ID0gYW5jaG8KICAgICAgICAgICAgZWxpZiBkYXRvc1sxXSA+PSBhbmNobzoKICAgICAgICAgICAgICAgIHNlbGYucG9zLnggPSAwCiAgICAgICAgICAgIC4uLiAgICAKICAgICAgICBlbGlmIGRhdG9zWzBdID09ICd5JzoKICAgICAgICAgICAgaWYgZGF0b3NbMV0gPCAwOgogICAgICAgICAgICAgICAgc2VsZi5wb3MueSA9IGFsdG8KICAgICAgICAgICAgZWxpZiBkYXRvc1sxXSA+PSBhbHRvOgogICAgICAgICAgICAgICAgc2VsZi5wb3MueSA9IDAKICAgICAgICAgICAgLi4uCiAgICAgICAgZWxzZToKICAgICAgICAgICAgIyBDb2xpc2lvbgogICAgICAgICAgICBzZWxmLnBpZXJkZV92aWRhKCkKICAgICAgICAgICAgc2VsZi5wb3MueSA9IGRhdG9zWzBdLnBvcy55ICsgNDAKICAgICAgICAgICAgc2VsZi5wb3MueCA9IGRhdG9zWzBdLnBvcy54ICsgNDAKICAgICAgICAuLi4KICAgIC4uLgouLi4KCgpjbGFzcyBQZXJzb25hamVOb0p1Z2Fkb3IoUGVyc29uYWplKToKICAgIGRlZiBfX2luaXRfXyhzZWxmLCBtYXhYLCBtYXhZLCBwb3NYLCBwb3NZLCB0YW0pOgogICAgICAgIHN1cGVyKCkuX19pbml0X18obWF4WCwgbWF4WSwgcG9zWCwgcG9zWSwgdGFtKQogICAgLi4uCiAgICAKICAgIGRlZiBtdWV2ZShzZWxmLCBkdCwganVnYWRvcik6CiAgICAgICAgcGFzbyA9IDUwCiAgICAgICAgbnVldm9feCA9IHBhc28gKiBkdAogICAgICAgIG51ZXZvX3kgPSBwYXNvICogZHQKICAgICAgICAKICAgICAgICBpZiBzZWxmLnBvcy54ID4ganVnYWRvci5wb3MueDoKICAgICAgICAgICAgbnVldm9feCAqPSAtMQogICAgICAgIC4uLgogICAgICAgIAogICAgICAgIGlmIHNlbGYucG9zLnkgPiBqdWdhZG9yLnBvcy55OgogICAgICAgICAgICBudWV2b195ICo9IC0xCiAgICAgICAgLi4uCiAgICAgICAgCiAgICAgICAgc2VsZi5wb3MueCArPSBudWV2b194CiAgICAgICAgc2VsZi5wb3MueSArPSBudWV2b195CiAgICAuLi4KLi4uCgoKaWYgX19uYW1lX18gPT0gIl9fbWFpbl9fIjoKICAgIHRhbV92ZW50YW5hID0gKDgwMCwgNjAwKQogICAgcHlnYW1lLmluaXQoKQogICAgCiAgICB0cnk6CiAgICAgICAgcHlnYW1lLmZvbnQuaW5pdCgpCiAgICBleGNlcHQgKEltcG9ydEVycm9yLCBOb3RJbXBsZW1lbnRlZEVycm9yKSBhcyBleGM6CiAgICAJIyBFbiBvY2FzaW9uZXMsIG5vIHNlIGluaWNpYWxpemEgZm9udCBjb3JyZWN0YW1lbnRlCiAgICAgICAgcHJpbnQoZiJGb250IG1vZHVsZSBub3QgZm91bmQ6IHtleGN9IikKICAgICAgICBweWdhbWUuZm9udCA9IE5vbmUKICAgIAogICAgaiA9IFBlcnNvbmFqZUp1Z2Fkb3IodGFtX3ZlbnRhbmFbMF0sIHRhbV92ZW50YW5hWzFdLAogICAgICAgICAgICAgICAgICAgICAgICAgdGFtX3ZlbnRhbmFbMF0gLyAyLCB0YW1fdmVudGFuYVsxXSAvIDIsIDIwKQogICAgcG5qcyA9IFsKICAgICAgICBQZXJzb25hamVOb0p1Z2Fkb3IodGFtX3ZlbnRhbmFbMF0sIHRhbV92ZW50YW5hWzFdLCAxMDAsIDEwMCwgMjApLAogICAgICAgIFBlcnNvbmFqZU5vSnVnYWRvcih0YW1fdmVudGFuYVswXSwgdGFtX3ZlbnRhbmFbMV0sIDUxMiwgNTEyLCAyMCksCiAgICAgICAgUGVyc29uYWplTm9KdWdhZG9yKHRhbV92ZW50YW5hWzBdLCB0YW1fdmVudGFuYVsxXSwgMjU2LCAzMDAsIDIwKSwKICAgICAgICBQZXJzb25hamVOb0p1Z2Fkb3IodGFtX3ZlbnRhbmFbMF0sIHRhbV92ZW50YW5hWzFdLCA0NSwgNDUsIDIwKQogICAgXQogICAgCiAgICBtID0gTW90b3IodGFtX3ZlbnRhbmEsIGosIHBuanMpCiAgICBtLnN0YXJ0KCkKICAgIHB5Z2FtZS5xdWl0KCkKLi4uCgo=