# on importe tout le contenu du module tkinter
# pour raccourcir la syntaxe il sera simplement appelé tk dans la suiteimport tkinter as tk
import tkinter as tk

# Fenêtre principale
root = tk.Tk()
#appel de la méthode title de l’objet root pour définir le titre de la fenêtre
root.title("Mini casse-brique (3 murs)")

# Canvas de jeu (Zone de dessin graphique = constituée de pixels)
LARGEUR = 400 # définition d’une constante
HAUTEUR = 600 # définition d’une constante 
zone_de_jeu = tk.Canvas(root, width=LARGEUR, height=HAUTEUR, bg='black')
zone_de_jeu.pack() # méthode pack pour placer la zone de jeu dans root


# Création de la balle
BALLE_RAYON = 8
# positionner ball dans un rectangle englobant (x1,y1,x2,y2)
# x1=gauche=190 y1=haut=140 x2=droit=210 y2=bas=160 couleur = blanc
CENTRE_X = LARGEUR//2
CENTRE_Y = HAUTEUR//2
balle = zone_de_jeu.create_oval(CENTRE_X - BALLE_RAYON//2, CENTRE_Y - BALLE_RAYON//2, CENTRE_X + BALLE_RAYON//2 , CENTRE_Y + BALLE_RAYON//2, fill='white')

# Vitesse initiale
dx, dy = 3, -3

# Raquette
raquette_largeur = LARGEUR // 5
raquette_hauteur = 10
raquette_y = HAUTEUR - 20
raquette_x = 0
# déclaration d'un objet raquette sur deux lignes pour améliorer la lisibilité
raquette = zone_de_jeu.create_rectangle(raquette_x, raquette_y, 
    raquette_x + raquette_largeur , raquette_y + raquette_hauteur, fill='blue')

# vitesse de la raquette = déplacement en nb de pixels si touche appuyée
raquette_dx = 20
raquette_dy = 0
# on souhaite que les déplacements de la raquette soient commandées
# par l'appui sur les touches flèche gauche et flèche droite
# au démarrage on suppose qu'aucune de ces touches flèches n'est appuyée.
left_pressed = False
right_pressed = False
# affichage dans le Terminal des coordonnées initiales de la raquette
print(zone_de_jeu.coords(raquette))
# 
#                    (rx1,ry1)
#                         |					|
#                                       (rx2,ry2)
#                                         
def déplacer_raquette_gauche(event):
    # on lit les coordonnées de la raquette
    rx1, ry1, rx2, ry2 = zone_de_jeu.coords(raquette)
    # si elle n'est pas à gauche de la fenêtre on la décale
    # vers la gauche d'une valeur de -raquette_dx pixels (raquette_dy=0)
    if rx1 > 0:
        zone_de_jeu.move(raquette, -raquette_dx, raquette_dy)

def déplacer_raquette_droite(event):
    # on lit les coordonnées de la raquette
    rx1, ry1, rx2, ry2 = zone_de_jeu.coords(raquette)
    # si elle n'est pas à gauche de la fenêtre on la décale
    # vers la droite d'une valeur de raquette_dx pixels (raquette_dy=0)
    if rx2 < LARGEUR:
        zone_de_jeu.move(raquette, raquette_dx, raquette_dy)

# Gestion des touches pressées
# si une touche du clavier est préssée
def on_key_press(event):
    global left_pressed, right_pressed
    # si la touche concernée est la flèche gauche
    if event.keysym == 'Left':
        left_pressed = True
    # sinon si la touche concernée est la flèche droite
    elif event.keysym == 'Right':
        right_pressed = True
    # sinon rien dans les autres cas

# si une touche du clavier est relachée
def on_key_release(event):
    global left_pressed, right_pressed
    # si la touche concernée est la flèche gauche
    if event.keysym == 'Left':
        left_pressed = False
    # sinon si la touche concernée est la flèche droite
    elif event.keysym == 'Right':
        right_pressed = False
    # sinon rien dans les autres cas

# on associe l'évènement d'appui sur une touche à la fonction on_key_press()
root.bind('<KeyPress>', on_key_press)
# on associe l'évènement de relachement d'une touche à la fonction on_key_release()
root.bind('<KeyRelease>', on_key_release)

# on écrit la fonction qui sera périodiquement exécutée pour actualiser
# la position de la balle et de la raquette
def déplacer_balle_et_raquette():
    # 1- on récupère deux variables dx et dy du programme principal 
    global dx, dy, id_anim_jeu

    # 2- GESTION DE LA NOUVELLE POSITION DE LA BALLE
    # Récupération des coordonnées
    x1, y1, x2, y2 = zone_de_jeu.coords(balle)
    rx1, ry1, rx2, ry2 = zone_de_jeu.coords(raquette)

    # Rebond sur le mur gauche ou sur le mur droit
    # on inverse la composante x du déplacement
    if x1 <= 0 or x2 >= LARGEUR:
        dx = -dx
    # Rebond en haut on inverse la composante y du déplacement
    if y1 <= 0:
        dy = -dy
    # si la balle arrive en bas de l'écran
    if y2 >= raquette_y:
        # si la balle est hors de la raquette on arrête le jeu
        # si coté gauche de la balle à droite du coté droit de la raquette
        # OU si le coté droit de la balle est à gauche du coté gauche de la raquette
        if x1 > rx2  or x2 < rx1 :
            # alors c'est perdu, fin de partie
            zone_de_jeu.after_cancel(id_anim_jeu)
            root.quit() # pour arrêter la boucle root.mainloop()
            root.destroy() # pour fermer la fenêtre
            return
        # sinon la balle rebondit sur la raquette
        else :
            # on inverse la composante y du déplacement
            dy = -dy
    # Déplacement de la balle dans la zone de jeu
    zone_de_jeu.move(balle, dx, dy)
 
    # 3- GESTION DE LA NOUVELLE POSITION DE LA RAQUETTE
    # si la flèche gauche est appuyée
    # et que la raquette n'est pas positionnée contre le mur gauche
    if left_pressed and rx1 > 0:
        # alors on la déplace vers la gauche de -raquette_dx pixels
        zone_de_jeu.move(raquette, -raquette_dx, raquette_dy)
    # si la flèche droite est appuyée
    # et que la raquette n'est pas positionnée contre le mur droit
    if right_pressed and rx2 < LARGEUR:
        # alors on la déplace vers la droite de raquette_dx pixels
        zone_de_jeu.move(raquette, raquette_dx, raquette_dy)
    
    # 4- demander l'exécution de la fonction déplacer_balle_et_raquette() dans 20ms
    id_anim_jeu = zone_de_jeu.after(20, déplacer_balle_et_raquette)

    return

# Lancer le mouvement
déplacer_balle_et_raquette()
# boucle principale de scrutation d'évènements (appui touche, ...)
root.mainloop()
# lorsque la boucle principale est arrêtée par root.quit()
# la suite du programme se déroule
print("c'est fini!")
