Transformación del panadero con PyGame

Versión: 2.x.

Una pequeña simulación utilizando PyGame y el módulo scheduler para el control de las animaciones.

Transformacion del panadero

  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. import pygame
  4. from scheduler import Scheduler
  5. WHITE = 255, 255, 255
  6. RED = 255, 0, 0
  7. BLUE = 0, 0, 255
  8. class AnimatedScale(object):
  9. def __init__(self, surface, size):
  10. self.surface = surface
  11. self.size = size
  12. self.positions = self._get_pos_path(surface.get_size(), size)
  13. def _get_pos_addends(self, a, b):
  14. dist_x = float(a[0] - b[0]) * -1
  15. dist_y = float(a[1] - b[1]) * -1
  16. loops = max(abs(dist_x), abs(dist_y))
  17. return (loops, (dist_x / loops if loops > 0 else 0,
  18. dist_y / loops if loops > 0 else 0))
  19. def _get_pos_path(self, a, b):
  20. loops, (add_x, add_y) = self._get_pos_addends(a, b)
  21. for i in range(1, int(loops + 1)):
  22. yield int(a[0] + round(add_x*i)), int(a[1] + round(add_y*i))
  23. def update(self):
  24. return pygame.transform.smoothscale(
  25. self.surface, next(self.positions))
  26. class Main(object):
  27. def __init__(self):
  28. pygame.init()
  29. self.screen = pygame.display.set_mode((600, 400))
  30. pygame.display.set_caption("Transformación del panadero")
  31. run = True
  32. self.moving = False
  33. self.stage = 0
  34. self.scaling = False
  35. self.scaling_sprites = []
  36. self.create_surfaces()
  37. pygame.draw.rect(self.first, RED, [0, 0, 252, 252 / 2])
  38. pygame.draw.rect(self.second, BLUE, [0, 0, 252, 252 / 2])
  39. self.screen.fill(WHITE)
  40. scheduler = Scheduler()
  41. scheduler.add(0.01, 0, self.animate_sprite_movement)
  42. scheduler.add(2, 0, self.handle_stage)
  43. from time import sleep
  44. sleep(15)
  45. while run:
  46. for event in pygame.event.get():
  47. if event.type == pygame.QUIT:
  48. run = False
  49. break
  50. scheduler.run()
  51. pygame.display.flip()
  52. pygame.quit()
  53. def animate_sprite_movement(self):
  54. if self.scaling:
  55. for i, animated_scale in enumerate(self.scaling_sprites):
  56. try:
  57. surface = animated_scale.update()
  58. except StopIteration:
  59. self.scaling = False
  60. if i == len(self.scaling_sprites) - 1:
  61. self.stage += 1
  62. self.scaling_sprites = []
  63. else:
  64. self.surface = surface
  65. if not i:
  66. self.clean()
  67. self.screen.blit(self.surface,
  68. (0, self.surface.get_size()[1] * i))
  69. elif self.moving:
  70. if self.offset[1] < 252 / 2:
  71. self.offset[1] += 1
  72. else:
  73. self.offset[0] -= 1
  74. self.clean()
  75. self.screen.blit(self.first, (0, 0))
  76. self.screen.blit(self.second, self.offset)
  77. if self.offset[0] == 0:
  78. self.moving = False
  79. self.stage = 0
  80. def clean(self):
  81. pygame.draw.rect(self.screen, WHITE, [0, 0, 504, 504])
  82. def create_surfaces(self):
  83. self.first = pygame.Surface((252, 252 / 2))
  84. self.second = self.first.copy()
  85. def handle_stage(self):
  86. if self.stage == 0:
  87. self.clean()
  88. self.screen.blit(self.first, (0, 0))
  89. self.screen.blit(self.second, (0, 252 / 2))
  90. self.stage += 1
  91. elif self.stage == 1 and not self.scaling:
  92. self.scaling = True
  93. for sprite in (self.first, self.second):
  94. self.scaling_sprites.append(
  95. AnimatedScale(sprite, (252 * 2, 252 / 4))
  96. )
  97. self.screen.blit(self.first, (0, 0))
  98. self.screen.blit(self.second, (0, 252 / 4))
  99. elif self.stage == 2 and not self.moving:
  100. self.offset = [252, 0]
  101. self.moving = True
  102. self.create_surfaces()
  103. self.first.blit(
  104. self.screen, (0, 0), [0, 0, 252, 252 / 2])
  105. self.second.blit(
  106. self.screen, (0, 0), [252, 0, 252, 252 / 2])
  107. if __name__ == "__main__":
  108. Main()
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import pygame
from scheduler import Scheduler


WHITE = 255, 255, 255
RED = 255, 0, 0
BLUE = 0, 0, 255


class AnimatedScale(object):
    
    def __init__(self, surface, size):
        self.surface = surface
        self.size = size
        self.positions = self._get_pos_path(surface.get_size(), size)
    
    def _get_pos_addends(self, a, b):
        dist_x = float(a[0] - b[0]) * -1
        dist_y = float(a[1] - b[1]) * -1
        loops = max(abs(dist_x), abs(dist_y))
        return (loops, (dist_x / loops if loops > 0 else 0,
                        dist_y / loops if loops > 0 else 0))

    def _get_pos_path(self, a, b):
        loops, (add_x, add_y) = self._get_pos_addends(a, b)
        for i in range(1, int(loops + 1)):
            yield int(a[0] + round(add_x*i)), int(a[1] + round(add_y*i))
    
    def update(self):
        return pygame.transform.smoothscale(
            self.surface, next(self.positions))


class Main(object):
    
    def __init__(self):
        pygame.init()

        self.screen = pygame.display.set_mode((600, 400))
        pygame.display.set_caption("Transformación del panadero")
        run = True
        self.moving = False
        self.stage = 0
        self.scaling = False
        self.scaling_sprites = []
        
        self.create_surfaces()
        pygame.draw.rect(self.first, RED, [0, 0, 252, 252 / 2])
        pygame.draw.rect(self.second, BLUE, [0, 0, 252, 252 / 2])
        
        self.screen.fill(WHITE)
        
        scheduler = Scheduler()
        scheduler.add(0.01, 0, self.animate_sprite_movement)
        scheduler.add(2, 0, self.handle_stage)
        
        from time import sleep
        sleep(15)
        
        while run:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    run = False
                    break
            scheduler.run()
            pygame.display.flip()

        pygame.quit()
        
    def animate_sprite_movement(self):
        if self.scaling:
            for i, animated_scale in enumerate(self.scaling_sprites):
                try:
                    surface = animated_scale.update()
                except StopIteration:
                    self.scaling = False
                    if i == len(self.scaling_sprites) - 1:
                        self.stage += 1
                        self.scaling_sprites = []
                else:
                    self.surface = surface
                    if not i:
                        self.clean()
                    self.screen.blit(self.surface,
                        (0, self.surface.get_size()[1] * i))
        elif self.moving:
            if self.offset[1] < 252 / 2:
                self.offset[1] += 1
            else:
                self.offset[0] -= 1
            
            self.clean()
            self.screen.blit(self.first, (0, 0))
            self.screen.blit(self.second, self.offset)
            
            if self.offset[0] == 0:
                self.moving = False
                self.stage = 0
    
    def clean(self):
        pygame.draw.rect(self.screen, WHITE, [0, 0, 504, 504])
    
    def create_surfaces(self):
        self.first = pygame.Surface((252, 252 / 2))
        self.second = self.first.copy()
    
    def handle_stage(self):
        if self.stage == 0:
            self.clean()
            self.screen.blit(self.first, (0, 0))
            self.screen.blit(self.second, (0, 252 / 2))
            self.stage += 1
        
        elif self.stage == 1 and not self.scaling:
            self.scaling = True
            for sprite in (self.first, self.second):
                self.scaling_sprites.append(
                    AnimatedScale(sprite, (252 * 2, 252 / 4))
                )
            self.screen.blit(self.first, (0, 0))
            self.screen.blit(self.second, (0, 252 / 4))
        
        elif self.stage == 2 and not self.moving:
            self.offset = [252, 0]
            self.moving = True
            self.create_surfaces()
            self.first.blit(
                self.screen, (0, 0), [0, 0, 252, 252 / 2])
            self.second.blit(
                self.screen, (0, 0), [252, 0, 252, 252 / 2])


if __name__ == "__main__":
    Main()

Curso online 👨‍💻

¡Ya lanzamos el curso oficial de Recursos Python en Udemy! Un curso moderno para aprender Python desde cero con programación orientada a objetos, SQL y tkinter en 2024.

Consultoría 💡

Ofrecemos servicios profesionales de desarrollo y capacitación en Python a personas y empresas. Consultanos por tu proyecto.

Deja una respuesta