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

#!/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