Animaciones con línea de tiempo
animate() le da a un widget su propio movimiento. Cuando varios widgets tienen que moverse a la
vez (una pantalla de título, una escena, un HUD que reacciona a un golpe, un recorrido guiado), ponlos
en una línea de tiempo. Un clip guarda esa línea de tiempo y un reproductor de animaciones
la reproduce, con reproducir, pausar, buscar, velocidad y colas. El AnimationPlayer de Godot funciona
igual.

import pyzed as pz
INTRO = pz.Clip("intro", length=2.2, tracks=[ pz.Track("card:opacity", {0: 0, 0.35: 1}), pz.Track("card:y", [(0, 40, "ease_out_back"), (0.5, 0)]), pz.Track("title:scale", [(0.3, 0.6, "ease_out_back"), (0.7, 1)]), pz.Track(":puntos", [(0.7, 0, "ease_out_cubic"), (1.9, 12_480)]),], calls=[pz.Call(1.6, "campana")])
class Juego(pz.App): def __init__(self): self.puntos = 0 self.player = pz.AnimationPlayer(INTRO, autoplay="intro")
def campana(self): ...
def view(self): return pz.column([ pz.text("NIVEL COMPLETADO").animate(self.player["title"]), pz.text(f"{self.puntos:,.0f}"), ]).animate(self.player["card"])El ejemplo completo es examples/timeline.py.
Para hacer clips sin código, usa el panel Animation
de Pyzed Design.
Las partes de una línea de tiempo
Sección titulada «Las partes de una línea de tiempo»
| Parte | Qué es |
|---|---|
Clip (pz.Clip) |
Una línea de tiempo con nombre: una duración length en segundos, pistas, llamadas y un modo de bucle. |
Pista (pz.Track) |
Una propiedad que cambia con el tiempo, como la y de card. |
Key (pz.Key) |
Un valor en un momento de una pista. Pyzed rellena el tiempo entre keys. |
Llamada (pz.Call) |
Un método de tu app que se ejecuta cuando el cabezal pasa por su momento. |
| Objetivo | Un nombre, como "card", al que se unen los widgets con .animate(self.player["card"]). |
| Cabezal | Dónde está el reproductor dentro del clip (player.position). |
Un clip sin length dura hasta su última key o llamada.
Rutas de las pistas
Sección titulada «Rutas de las pistas»La ruta de una pista dice qué anima:
| Ruta | Anima |
|---|---|
"card:opacity" |
Una propiedad de todos los widgets que reproducen el objetivo card. |
":puntos" |
Un atributo de la app. |
":hud.vida" |
Un atributo de un atributo (sigue los puntos). |
Las pistas de widget usan las propiedades animables (opacity,
x, y, scale, rotate, blur, colores, radius, glow, width, font_size…). Se reproducen
de forma nativa a la frecuencia de la pantalla y tu código no se ejecuta mientras tanto.
Las pistas de atributo (empiezan por :) cambian valores de tu propia app, así que pueden
controlar cualquier parámetro de cualquier widget: el texto de una etiqueta, el valor de una barra
de progreso, un tamaño, un icono. Los números, los colores ("#rrggbb") y las tuplas de números se
mezclan entre keys; los demás valores (textos, booleanos) cambian en cada key. Mira
pistas de atributo y llamadas más abajo.
Escribir keys
Sección titulada «Escribir keys»Las keys se pueden escribir de varias formas:
pz.Track("card:x", {0: -40, 0.5: 0}) # {tiempo: valor}pz.Track("card:x", [(0, -40, "ease_out_back"), (0.5, 0)]) # (tiempo, valor, curva hasta la siguiente key)pz.Track("card:x", [pz.Key(0, -40), pz.Key("500ms", 0)]) # objetos Key; los tiempos también como "500ms"Entre keys
Sección titulada «Entre keys»
- Curva por key. El
easingde una key es la curva hasta la siguiente key. Sirve cualquier nombre depz.animation.EASINGS, además de Bézier cúbicas(x1, y1, x2, y2)y"steps(n)". Eleasingde la pista ("linear"por defecto) se usa en las keys que no fijan uno. - Discreta.
interpolation="discrete"mantiene cada valor hasta la siguiente key, sin movimiento entre ellas. Va bien para fotogramas de sprites, textos e interruptores. - Silenciar.
enabled=Falsedeja la pista en el clip sin reproducirla. - Antes y después de las keys. Un widget mantiene el valor de la primera key antes de ella y el de la última key después, como en Godot.

loop= |
Se reproduce |
|---|---|
"none" (por defecto) |
Una vez, y se queda en el último fotograma. |
"loop" |
Vuelve a empezar al llegar al final, sin parar. |
"pingpong" |
Va hasta el final y vuelve, sin parar. |
REPOSO = pz.Clip("reposo", length=1.2, loop="pingpong", tracks=[ pz.Track("button:scale", [(0, 1, "ease_in_out_sine"), (1.2, 1.06)]),])Pistas de atributo y llamadas
Sección titulada «Pistas de atributo y llamadas»
SUBIDA = pz.Clip("subida", length=2.0, tracks=[ pz.Track(":progreso", [(0, 0, "ease_in_out"), (1.8, 1)]), pz.Track(":estado", {0: "Subiendo…", 0.9: "Casi listo", 1.8: "Hecho"}), # los textos cambian en cada key pz.Track(":archivos", [(0, 0), (1.8, 24)]),], calls=[pz.Call(0.9, "a_medias"), pz.Call(1.8, "terminado", "informe.pdf")])
class Subida(pz.App): def __init__(self): self.progreso, self.estado, self.archivos = 0.0, "", 0 self.player = pz.AnimationPlayer(SUBIDA, autoplay="subida")
def a_medias(self): ...
def terminado(self, nombre): ...
def view(self): return pz.column([pz.text(self.estado), ui.progress(self.progreso), pz.text(f"{self.archivos:.0f} / 24")])pz.Call(tiempo, metodo, *args) llama a un método de la app cuando el clip pasa por ese momento.
metodo también puede ser cualquier función. Lo que devuelve se trata como lo que devuelve un callback
(un Command, un mensaje). Las llamadas se ejecutan al reproducir hacia delante, hacia atrás y en cada
vuelta de un bucle, pero no cuando saltas con seek.
Siguiente: el reproductor de animaciones reproduce, pausa, busca y
encola clips, y los guarda en archivos .pzanim.