TkInter 2: debuxar e animar

Antes en Python:

  • Bilioteca, método, atributo
  • TkInter: botóns

Neste apartado veremos como:

  1. Crear un lenzo.
  2. Debuxar figuras xeométricas
  3. Crear debuxos
  4. Animar
  5. Interactuar
  6. Xogar

 

1. Crear un lenzo

 

Empregaremos o widget canvas(), que permite debuxar, facer animacións...O canvas tamén é moi importante en HTML5.

O lenzo creado con canvas() vai permitir que debuxemos en el e que animemos os debuxos. Terá unha serie de atributos que facilitarán a nosa labor. De entrada teremos que fixar o ancho e o alto en píxeles (width e height). Un lenzo normal leva este código:

ventana = Tk()
lenzo = Canvas(ventana, width=500, height=500)
lenzo.pack()

2. Debuxar figuras xeométricas

Un dos usos primeiros será debuxar formas: liñas, polígonos, elipses...Os métodos para crealas dependerán de atributos, como as coordenadas, tipo de liñas (grosor, cor...), etc...Se tes traballado en HTML xa coñeces moitos destes atributos: fill, width, font...

Calquera forma terá unhas coordenadas, que poden ser:

Figuras Coordenadas Exemplo
Liñas o punto inicial e final create_line (0,100,100,100)
Polígonos os vértices superior esquerda e inferior dereita create_rectangule(100,100,300,200)
Elipses vértices do rectángulo que contén dita forma create_oval (100,100,300,200)

A maiores poderemos engadirlle os atributos: 

create_nome-da-forma(coordenadas, atributos).

IMPORTANTE: As coordenadas virán referidas a X e Y, sendo  a orixe de coordenadas (0,0) o punto superior esquerda.

Vexamos un exemplo. Imos crear unha liña horizontal, unha vertical, un rectángulo e unha elipse que está inscrita no rectángulo decidindo as coordenadas (e polo tanto o tamaño):

Obxectivo Código Saída
Formas básicas, familiarizarnos coas coordenddas

Usamos atributos para modificar a cor, grosor...das liñas

estruturas secuenciais

 

Indicamos aquí as coordenadas e insistimos para que se traballe. Neste caso o lenzo medía 500 píxeles, polo (250,250) será o centro.

Exercicios:

  1. Crea formas decidindo primeiro as coordenadas.
  2. Modifica a cor e o grosor da liña.

Comezo

3. Crear debuxos

Empregando liñas e as figuras xeométricas xa podemos lanzarnos a debuxar.  Imos crear un alien, que logo poderemos animar con funcións. Intenta debuxalo en papel, pensa as coordenadas e ponlle un nome descritivo a cada parte do corpo.
 
Obxectivo Código Saída
Alien: debuxo en base a formas

Ollo ao método pack()

estruturas secuenciais

 

   

Exercicios:

  1. Crea o teu propio alien en base a formas básicas, con cores, grosor de liña...O que fagas logo poderás utilizalo nunha animación.

4. Animar

Para animar empregaremos funcións recursivas que se chaman  a si mesmas e crean unha repetición, ou utilizamos bucles for ou while. Algúns dos métodos que temos son update() ou after(), que volven debuxar o lenzo con algún cambio. Normalmente utilizaremos o método sleep() para crear pausas na animación (isto é ben coñecido para os de Scratch). Polo tanto debermos incorporar na parte inicial do código a orde para importar o método:

from time import sleep

Unha vez lograda a animación será importante determinar a velocidade, medida en frames por segundo, FPS.

a) Crear múltiples formas aleatorias

Isto será importante para facer xogos, pero de momento permite practicar que os atributos dependan de variables que poden estar xeradas aleatoriamente. Vexamos este exemplo: creamos aleatoriamente círculos en distintas posicións, de distinto tamaño, distintas cores.... Usamos un método recursivo, update(), que actualiza o lenzo e vemos as modificacións, e unnha lista que almacena as cores e vainas cambiando:

while True:
    col = choice(['pink','orange','yellow','purple'])
    x0 = randint(0,tamaño)
    y0 = randint(0,tamaño)
    d = randint(0,tamaño/5)
    lenzo.create_oval(x0,y0,x0+d,y0+d, fill=col)
    ventana.update()
    sleep (0.5)

Neste caso temos un bucle infinito. E non necesitamos utilizar mainloop(), pois xa temos creado un loop con update() e o bucle while. Lembra importar sleep() ao inicio do programa.

Exercicios:

  1. Modifica o código para que utilice outras cores e outras formas.

Comezo

b) Animación básica

Podemos lograr animación doutros xeitos. Vexamos un rectángulo que se move e modifica a súa cor ao facelo:

  • Creamos unha ventana con título e un lenzo de 500x500 con cor gris:

ventana = Tk()
ventana.title('animación')
lenzo = Canvas(ventana, width=500, height=500,bg='grey')
lenzo.pack()

  • Creamos un rectángulo, inicialmente azul, e imos chamalo obxecto, para ver que isto podemos facelo con calquera obxecto:

obxecto = lenzo.create_rectangle(50, 25, 150, 75, fill="blue")

  • agora facemos unha función que mova o rectángulo e lle modifique a cor. Ollo co paso de parámetros:

for i in range(1,20):
    lenzo.move(obxecto,10,0)
    lenzo.itemconfig(obxecto,fill='red') #usamos o método itemconfig para variar un parámetro de obxecto
    sleep(0.5)
    lenzo.update() #isto é a animación
    lenzo.itemconfig(obxecto,fill='blue')
    sleep(0.5)
    lenzo.update()

  • O máis importante, e a principal fonte de confusión, é decatarse que os métodos move(), update(), itemconfig() se pasan sobre o lenzo e non sobre o obxecto. Pode que non sexa obvio entendelo á primeira.
  • Listo, agora escribimos mainloop() e xa temos unha animación. Pero cutre, non?. Haberá que modificala.

Exercicios:

  1. Modifica a animación anterior:
  • Cambiando as cores e incluso a forma.
  • Cambiando a velocidade, para que sexa máis fluida

Comezo

c)Alien animado

Se fixeches o alien pedido no apartado de debuxar, agora imos animalo utilizando funcións que logo chamamos no bucle principal. Faremos 4 frames, abrir e pechar a boca, e chiscar o ollo esquerdo.

Vexamos o da boca. Utilizamos un método importante de coñecer en animación, itemconfig(), que permite modificar atributos de elementos creados. Neste caso modificamos a cor de recheo:

def boca_aberta():
    debuxo.itemconfig(boca, fill='black') #é importante fixarse na sintaxe do método
    debuxo.update()

def boca_pechada():
    debuxo.itemconfig(boca, fill='red')
    debuxo.update()

E agora chiscar o ollo:

def chisco1():
    debuxo.itemconfig(ollo1,fill='green')
    debuxo.itemconfig(pupila1,state=HIDDEN) #podemos ocultar un obxecto
    debuxo.update()

def chisco2():
    debuxo.itemconfig(ollo1,fill='white')
    debuxo.itemconfig(pupila1,state=NORMAL)
    debuxo.update()

Xa postos, podemos incluir texto estático ao carón do alien:

palabras = debuxo.create_text(200,280,text='Son un marciano',font=('Verdana',30))

E por último o bucle principal do programa:

while True:
    boca_aberta()
    sleep(0.5)
    boca_pechada()
    sleep(0.5)
    chisco1()
    sleep(0.5)
    chisco2()
    sleep(0.5)

debuxo.mainloop()

Exercicio:

  1. Crea a animación de teu alien
  2. Modifica o bucle principal utilizando un bucle for

Comezo

d) Xogar ao balón

Queremos mover unha bola animada (ou sexa, un círculo). Vexamos como. Divididimos o código nos seguintes apartados:

  • Crear a ventana e un lenzo(canvas) dun tamaño determinado (teremos que fixar o alto e o ancho)
  • Crear un círculo e situalo nunha posición (coordenadas determinadas). Usamos o método create_oval(x1,y1,x2,y2) sendo os parámetros as coordenadas do punto superior esquerda e do punto inferior dereita do rectángulo que contén á elipse. Se facemos contas teremos un círculo cando o rectángulo sexa un cadrado.
  • Animar o círculo cunha función en bucle. Para isto usamos o método lenzo.move(obxecto_a_mover, dx,dy) sendo dx e dy o desprazamento en horizontal e vertical, e logo o método recursivo lenzo.after(milisegundos, nome_da_función):

def animacion():
    lenzo.move(bola, 6, 0) #isto só move o debuxo unha vez
    ventana.after(330, animacion) #proceso recursivo, teremos 3 debuxos por segundo, 3 fps

Obxectivo Código Saída
Mover un círculo animado

 

estruturas secuenciais

Obviamente deberíamos ter posto un GIF ;-)

Comezo

5. Interactuar

Antes de facer animacións interactivas, xogos, temos que saber algo de eventos. Un evento é cando introducimos información variable e condicional no xogo:

  • Ao pulsar a tecla un moneco se move.
  • Ao chegar o tempo a 0 o xogo vaise deter.
  • Ao mover o rato, debuxamos con outra cor,etc...

Os eventos están recollidos en funcións creadas por nós, por exemplo para mover un moneco coas frechas definimos as ordes de movento xerais e logo as aplicamos sobre ese moneco concreto.

O método principal para recoller isto vai ser bind(), vincular. Cada widget podémolo vincular cun evento mediante esta sintaxe:

widget.bind(evento, modificación) #sendo un evento algo que acontece, habitualmente unha función definida

Obxectivo Código Saída
Interactuar co rato: apuntar as coordenadas

Usamos event.x e event.y para recoller as coordenadas

estruturas secuenciais

Engadimos o teclado: apunta a tecla pulsada

 

 

Comezo

6. Xogar

Agora é cando podes xogar, ben creando animacións, ou complicándote un pouco e creando videoxogos (para iso é máis recomendable a biblioteca pygame, pero con TkInter podes practicar cousas básicas).

Xogo 1: Recolectar moedas

Neste caso imos darte o código enteiro en formato de ficheiro: coins.py (ao baixalo quítalle a extensión .txt).

Se o executas terás un xogo básico de capturar moedas nun tempo dado:

 

Comezo

Exercicios:

  1. Modifica o debuxo de rato, ese cadrado vermello.
  2. Modifica o tempo de duración do xogo.
  3. Avanzado: explica en que parte do código se cambia de pantalla cando logras reunir todas as monedas.

Xogo 2: Cazar ras

Temos creado un xogo de cazar ras, pero como somos moi malos debuxando vas ter que modificalo para melloralo. Nel, fixemos unha serpe vermella que, movéndose coas teclas, ten que comerse ás ras verdes que van saíndo dende a esquerda ata a dereita:

Se queres empezar, aquí tes o código: cazarrAs.py (lembra quitarlle a extensión .txt). O código está parcialmente comentado.

Exercicios:

  1. Modifica o debuxo da serpe. Podes incluso investigar como inserir un debuxo en formato mapa de bits.
  2. Modifica as ras, en especial a súa velocidade.
  3. Explica como se crean as ras.
  4. Explica como desaparecen as ras cando chegan ao borde esquerdo.
  5. Explica como chocan a serpe e as ras.

 

    Comezo

    Pygal: gráficas sexys TkInter: xanelas e botóns TkInter 2: debuxar e animar Pygame: videoxogos