Accueil

Traduction

Tutoriel Python - sommaire

Tutoriel Python - recherche

L'auteur : Patrick Darcheville

Vous pouvez me contacter via Facebook pour questions & suggestions : Page Facebook relative à mon site

Animations et jeux basiques avec Tkinter-Canvas

Avant d'aborder l'utilisation de la bibliothèque Pygame je voudrais vous montrer que vous pouvez réaliser des animations visuelles voire des jeux graphiques (très basiques bien sûr) avec le module Tkinter.

Des animations

Première animation dans une objet tkinter-canvas

Le code

#canevas_anime1.py

from tkinter import *
import time

fen = Tk()
fen.title("Animations avec Tkinter-Canvas")
X = 500
Y = 500
canevas = Canvas(fen, width = X, height = Y,bg='lime')
canevas.pack()

canevas.create_rectangle((0,0),(100,25), fill ='navy',outline ='')
canevas.create_oval((X-50,Y-50),(X,Y), fill ='red', outline='')

for i in range(0,100):
    canevas.move(1,5,5)
    canevas.move(2,-5,-5)
    fen.update()
    time.sleep(0.5)
    
fen.mainloop()

Je dessine un objet Canvas nommé "canevas" dans la fenêtre tkinter (nommée "fen").
Je dessine un rectangle et un cercle dans ce canevas qui auront respectivement l'identifiant 1 & 2.
Grâce à une boucle je déplace les formes identifiées 1 & 2 : l'une du coin haut gauche vers le coin bas droit et l'inverse pour la deuxième forme.
fen.update() : tkinter redessine le canevas avec les nouveaux emplacements des deux formes
time.sleep(0.5) : temporisation de 1/2 seconde

Je vous montre que les paramètres des canevas, des formes peuvent être des variables.
Si par exemple, vous souhaitez que le canevas fasse 600 par 600 vous n'aurez que deux modifications à faire dans le script !

Le rendu

Amélioration du script

Il est préférable d'attribuer un nom à chaque forme et de manipuler ces noms plutôt que des identifiants.

Le code (extrait)

...
raquette =canevas.create_rectangle((0,0),(100,25), fill ='navy',outline ='')
balle =canevas.create_oval((X-50,Y-50),(X,Y), fill ='red', outline='')
print ("Coordonnées initiales des formes")
print("balle: ", canevas.coords(balle))
print ("raquette",canevas.coords(raquette))
for i in range(0,60):
    canevas.move(raquette,5,5)
    canevas.move(balle,-5,-5)
    fen.update()
    time.sleep(0.5)

print ("Coordonnées finales des formes")
print("balle :", canevas.coords(balle))
print ("raquette:", canevas.coords(raquette))
...

raquette =canevas.create_rectangle(... : le rectange est identifié "raquette"
print("balle: ", canevas.coords(balle)) : la méthode coords(forme) de l'objet Canvas retourne les coordonnées de la forme sous forme d'une liste de 4 valeurs.

Le contenu du shell dans cette nouvelle version

Coordonnées initiales des formes
balle:  [450.0, 450.0, 500.0, 500.0]
raquette [0.0, 0.0, 100.0, 25.0]
Coordonnées finales des formes
balle : [150.0, 150.0, 200.0, 200.0]
raquette: [300.0, 300.0, 400.0, 325.0]

Déplacer la raquette via le clavier

Le code (à dérouler)

def deplacer(event) : la fonction doit recevoir l'évènement en paramètre.

if event.keysym =='Up' : 'keysym' est un mot clé qui signifie "symbole de touche".

canevas.bind_all('<KeyPress-Up>',deplacer) : La méthode bind_all() dans Tkinter permet de lier un événement à tous les widgets.
Ici l'appui sur la touche directionnele "haut" appelle la fonction "deplace()" avec passage de l'évènement en paramètre.

Le rendu

Balle rebondissante

La balle se déplace automatiquement dans le canevas mais si elle touche un des quatre bords elle rebondit c'est à dire que le delta de déplacement change de signe.

Le code

#canevas_balle_rebondissante.py

from tkinter import *
import time
import random as rd

fen = Tk()
fen.title("Balle rebondissante")
X = 600
Y = 400
canevas = Canvas(fen, width = X, height = Y,bg='lavender')
canevas.pack()
deltax = 6  # déplacement sur l'axe X
deltay = 4	# déplacement sur l'axe Y
balle =canevas.create_oval((300,300),(350,350), fill ='red', outline='')

while 1 : # boucle infinie
    # extraction de la liste
    x1 = canevas.coords(balle)[0]
    y1 = canevas.coords(balle)[1]
    x2 = canevas.coords(balle)[2]
    y2 = canevas.coords(balle)[3]
    if x1 < 0 :
        deltax = -deltax
    if x2 > X : 
        deltax = -deltax
    if y1 < 0 :
        deltay = -deltay
    if y2 > Y :
        deltay = -deltay
    canevas.move(balle,deltax,deltay)
    fen.update()
    time.sleep(0.1)
    
fen.mainloop()

Le rendu

Le jeu de squash

Le joueur peut déplacer la raquette vers la droite ou la gauche pour tenter d'intercepter la balle.
Si la balle touche le bord bas, le joueur a perdu.

Le code (à dérouler)

import tkinter.messagebox as msg: pour pouvoir afficher des boites de dialogue dans le fenêtre tkinter.
deltax = X/100 *1.5 : le déplacement horizontal de la balle par cycle est lié à la largeur du canevas
if yb2 > Y :si la balle touche le bord bas
if (abs(xb1-xr1)<50) and (abs(yb1-yr1)<50) : si les deux sprites se chevauchent ; donc si la balle touche la raquette.

Le rendu

Les limites de tkinter

Dans l'exemple précédent la gestion des collisions est fort empirique.
Même pour un jeu basique (avec seulement deux sprites) le code devient vite verbeux car le développeur ne dispose pas de bons outils ...
En lisant les chapitres suivants vous découvrirez tous les avantages d'une bibliothèque Python dédiée aux jeux vidéo : Pygame.