python-3.xcanvastkintertkinter-canvasflappy-bird-clone

How to display a game over screen with Tkinter?


I'm programming a Flappy Bird clone but whatever I do, I can not display a game over screen if the bird touches the pipes. I did not think it was going to be difficult but it is. I managed to get a start screen with the debut and rapide function and canvas.delete ... However, I do not know how to do the opposite: display images / buttons or text if the game is over.

Thank you in advance for your help in hopes that the solution is simple but I just did not find it.

I tried to manage the image displays but the images just do not appear ...

Here are the pictures of the game (it's a mediafire link to download the zip file of the pictures)!

Here are the pictures


from tkinter import *
import random
from random import randint

def sauter(event):
    canvas.move(image_oiseau, 0, -10*DY)

def deplacement():
    global mouvement
    global tuyx,tuyx2,h,H,oisx,oisy,solx,sol2x,score

    x0, y0, x1, y1 = canvas.bbox(image_oiseau)
    if y1 < 416 :
        canvas.move(image_oiseau, 0, DY)

    else :
        fin()

    if y1<=-5:
        fin()

    canvas.coords(image_sol,solx,512)  
    if solx >= -144:
        solx=solx-5
    else:
        solx=144

    canvas.coords(image_sol2,sol2x,512)
    if sol2x >= 144:
        sol2x=sol2x-5
    else:
        sol2x=432

    canvas.coords(image_tuyau_haut,tuyx,h)
    canvas.coords(image_tuyau_bas,tuyx,h-379.8)
    if tuyx>=-28:
        tuyx=tuyx-5
    else:
        tuyx=316
        h=randint(272,523)
        score+=1

    canvas.coords(image_tuyau_haut2,tuyx2,H)
    canvas.coords(image_tuyau_bas2,tuyx2,H-379.8)
    if tuyx2>=-28:
        tuyx2=tuyx2-5
    else:
        tuyx2=316
        H=randint(272,523)
        score+=1

    collision()

    lscore.config(text=str(score))    
    mouvement =canvas.after(40,deplacement)    

def collision():
    global liste_coords
    x0, y0, x1, y1 = canvas.bbox(image_oiseau)
    liste_coords=canvas.coords(image_oiseau)
    liste_items=canvas.find_overlapping(x0,y0,x1,y1)
    test_collision=False
    if len(liste_items)>3:
        for x in liste_items :
            if x != image_oiseau:
                test_collision=True
                break
    if test_collision==True:
        fin()       

def debut():
    pause=1 
    if pause==1:
        deplacement()
        canvas.bind("<space>",sauter)
        Eclair.destroy()
        Jouer.destroy()
        canvas.delete(image_menu_jeu)

def rapide():
    debut()
    debut()
    Eclair.destroy()
    Jouer.destroy()
    canvas.delete(image_menu_jeu)


def rejouer():
    global tuyx,tuyx2,oisx,oisy,solx,sol2x,score,finx,finy
    tuyx=316
    tuyx2=488
    oisx=67
    oisy=244
    solx=144
    sol2x=432
    score=0 
    finx=1000
    finy=1000
    canvas.coords(image_menu_fin,finx,finy)

def fin():
    pause=0
    if pause==0:
        canvas.after_cancel(mouvement)
        canvas.unbind("<space>",sauter)
        finx=144
        finy=256
        canvas.coords(image_menu_fin,finx,finy)

def debut2():
    pause=1 
    if pause==1:
        rejouer()
        deplacement()
        canvas.bind("<space>",sauter)

def rapide2():
    debut2()
    debut2()

LARGEUR = 286
HAUTEUR = 510
DY = 5
tuyx=316
tuyx2=488 
h=randint(272,523)
H=randint(272,523)
oisx=67
oisy=244
solx=144
sol2x=432
score=0
mouvement=None
finx=1000
finy=1000

fenetre = Tk()
canvas = Canvas(fenetre, width=LARGEUR, height=HAUTEUR)

fond = PhotoImage(file="background-day.png")
fond2 = PhotoImage(file="background-night.png")
fond=[fond,fond2]
F= random.choice(fond)
canvas.create_image(144,256, anchor=CENTER,image=F)

tuyau_haut = PhotoImage(file="tuyau_vers_le_haut.png")
image_tuyau_haut = canvas.create_image(tuyx,h,anchor=CENTER,image=tuyau_haut)
image_tuyau_haut2 = canvas.create_image(tuyx2,H,anchor=CENTER,image=tuyau_haut)

tuyau_bas = PhotoImage(file="tuyau_vers_le_bas.png")
image_tuyau_bas = canvas.create_image(tuyx,h,anchor=CENTER,image=tuyau_bas)
image_tuyau_bas2 = canvas.create_image(tuyx2,H,anchor=CENTER,image=tuyau_bas)

sol = PhotoImage(file="sol-day.png")
image_sol = canvas.create_image(144,512, anchor=S,image=sol)
image_sol2 = canvas.create_image(432,512, anchor=S,image=sol)

oiseau = PhotoImage(file="yellowbird-midflap.png")
oiseau2 = PhotoImage(file="bluebird-midflap.png")
oiseau3 = PhotoImage(file="redbird-midflap.png")
oiseau=[oiseau,oiseau2,oiseau3]
O=random.choice(oiseau)
image_oiseau=canvas.create_image(oisx,oisy, anchor=W,image=O) 

lscore=Label(fenetre,text='0')
lscore.pack()

bouton_play=PhotoImage(file="bouton_play.gif")
Jouer=Button(fenetre,image=bouton_play,relief=FLAT,borderwidth=0,highlightthickness=0,command=debut)
canvas.create_window(77.55,364,window=Jouer)

bouton_eclair=PhotoImage(file="bouton_eclair.gif")
Eclair=Button(fenetre,image=bouton_eclair,relief=FLAT,borderwidth=0,highlightthickness=0,command=rapide)
canvas.create_window(210.45,364,window=Eclair)  

bouton_quitter=PhotoImage(file="bouton_quitter.png")
Quitter=Button(fenetre,image=bouton_quitter,relief=FLAT,borderwidth=0,highlightthickness=0,command=fenetre.destroy)
canvas.create_window(255.5,29.63,window=Quitter) 

menu_jeu = PhotoImage(file="menu_jeu.png")
image_menu_jeu = canvas.create_image(144,256,anchor=CENTER,image=menu_jeu)

menu_fin = PhotoImage(file="menu_fin.png")
image_menu_fin = canvas.create_image((finx,finy),anchor=CENTER,image=menu_fin)

canvas.pack()
canvas.focus_set()


fenetre.mainloop() 

Solution

  • You have use canvas.unbind("<space>") instead of canvas.unbind("<space>",sauter) which gives error message. Now you should see Game Over image.


    Pipes are stil moving.

    You need global pause in fin(), debut(), debut2().
    And use pause in deplacement to stop animation.

    if pause == 1:
        mouvement = canvas.after(40,deplacement)
    

    You use after_cancel to stop it but it can't stop running function. It removes function from list of functions waiting for execution. But deplacement may run in the moment when you use after_cancel and it will use after() after your after_cancel - so it will not stop.


    Instead of pause = 0, pause = 1 you could use pause = False, pause = True


    Full code:

    from tkinter import *
    import random
    from random import randint
    
    def sauter(event):
        canvas.move(image_oiseau, 0, -10*DY)
    
    def deplacement():
        global mouvement
        global tuyx,tuyx2,h,H,oisx,oisy,solx,sol2x,score
    
        x0, y0, x1, y1 = canvas.bbox(image_oiseau)
        if y1 < 416 :
            canvas.move(image_oiseau, 0, DY)
    
        else :
            fin()
    
        if y1<=-5:
            fin()
    
        canvas.coords(image_sol,solx,512)
        if solx >= -144:
            solx=solx-5
        else:
            solx=144
    
        canvas.coords(image_sol2,sol2x,512)
        if sol2x >= 144:
            sol2x=sol2x-5
        else:
            sol2x=432
    
        canvas.coords(image_tuyau_haut,tuyx,h)
        canvas.coords(image_tuyau_bas,tuyx,h-379.8)
        if tuyx>=-28:
            tuyx=tuyx-5
        else:
            tuyx=316
            h=randint(272,523)
            score+=1
    
        canvas.coords(image_tuyau_haut2,tuyx2,H)
        canvas.coords(image_tuyau_bas2,tuyx2,H-379.8)
        if tuyx2>=-28:
            tuyx2=tuyx2-5
        else:
            tuyx2=316
            H=randint(272,523)
            score+=1
    
        collision()
    
        lscore.config(text=str(score))
        if pause == 1:
            mouvement = canvas.after(40,deplacement)
    
    def collision():
        global liste_coords
        x0, y0, x1, y1 = canvas.bbox(image_oiseau)
        liste_coords=canvas.coords(image_oiseau)
        liste_items=canvas.find_overlapping(x0,y0,x1,y1)
        test_collision=False
        if len(liste_items)>3:
            for x in liste_items :
                if x != image_oiseau:
                    test_collision=True
                    break
        if test_collision==True:
            fin()
    
    def debut():
        global pause
        pause=1
        if pause==1:
            deplacement()
            canvas.bind("<space>",sauter)
            Eclair.destroy()
            Jouer.destroy()
            canvas.delete(image_menu_jeu)
    
    def rapide():
        debut()
        debut()
        Eclair.destroy()
        Jouer.destroy()
        canvas.delete(image_menu_jeu)
    
    
    def rejouer():
        global tuyx,tuyx2,oisx,oisy,solx,sol2x,score,finx,finy
        tuyx=316
        tuyx2=488
        oisx=67
        oisy=244
        solx=144
        sol2x=432
        score=0
        finx=1000
        finy=1000
        canvas.coords(image_menu_fin,finx,finy)
    
    def fin():
        global pause
        pause=0
        if pause==0:
            canvas.after_cancel(mouvement)
            canvas.unbind("<space>")#,sauter)
            finx=144
            finy=256
            canvas.coords(image_menu_fin,finx,finy)
    
    def debut2():
        global pause
        pause=1
        if pause==1:
            rejouer()
            deplacement()
            canvas.bind("<space>",sauter)
    
    def rapide2():
        debut2()
        debut2()
    
    LARGEUR = 286
    HAUTEUR = 510
    DY = 5
    tuyx=316
    tuyx2=488
    h=randint(272,523)
    H=randint(272,523)
    oisx=67
    oisy=244
    solx=144
    sol2x=432
    score=0
    mouvement=None
    finx=1000
    finy=1000
    pause=1
    fenetre = Tk()
    canvas = Canvas(fenetre, width=LARGEUR, height=HAUTEUR)
    
    fond = PhotoImage(file="background-day.png")
    fond2 = PhotoImage(file="background-night.png")
    fond=[fond,fond2]
    F= random.choice(fond)
    canvas.create_image(144,256, anchor=CENTER,image=F)
    
    tuyau_haut = PhotoImage(file="tuyau_vers_le_haut.png")
    image_tuyau_haut = canvas.create_image(tuyx,h,anchor=CENTER,image=tuyau_haut)
    image_tuyau_haut2 = canvas.create_image(tuyx2,H,anchor=CENTER,image=tuyau_haut)
    
    tuyau_bas = PhotoImage(file="tuyau_vers_le_bas.png")
    image_tuyau_bas = canvas.create_image(tuyx,h,anchor=CENTER,image=tuyau_bas)
    image_tuyau_bas2 = canvas.create_image(tuyx2,H,anchor=CENTER,image=tuyau_bas)
    
    sol = PhotoImage(file="sol-day.png")
    image_sol = canvas.create_image(144,512, anchor=S,image=sol)
    image_sol2 = canvas.create_image(432,512, anchor=S,image=sol)
    
    oiseau = PhotoImage(file="yellowbird-midflap.png")
    oiseau2 = PhotoImage(file="bluebird-midflap.png")
    oiseau3 = PhotoImage(file="redbird-midflap.png")
    oiseau=[oiseau,oiseau2,oiseau3]
    O=random.choice(oiseau)
    image_oiseau=canvas.create_image(oisx,oisy, anchor=W,image=O)
    
    lscore=Label(fenetre,text='0')
    lscore.pack()
    
    bouton_play=PhotoImage(file="bouton_play.gif")
    Jouer=Button(fenetre,image=bouton_play,relief=FLAT,borderwidth=0,highlightthickness=0,command=debut)
    canvas.create_window(77.55,364,window=Jouer)
    
    bouton_eclair=PhotoImage(file="bouton_eclair.gif")
    Eclair=Button(fenetre,image=bouton_eclair,relief=FLAT,borderwidth=0,highlightthickness=0,command=rapide)
    canvas.create_window(210.45,364,window=Eclair)
    
    bouton_quitter=PhotoImage(file="bouton_quitter.png")
    Quitter=Button(fenetre,image=bouton_quitter,relief=FLAT,borderwidth=0,highlightthickness=0,command=fenetre.destroy)
    canvas.create_window(255.5,29.63,window=Quitter)
    
    menu_jeu = PhotoImage(file="menu_jeu.png")
    image_menu_jeu = canvas.create_image(144,256,anchor=CENTER,image=menu_jeu)
    
    menu_fin = PhotoImage(file="menu_fin.png")
    image_menu_fin = canvas.create_image((finx,finy),anchor=CENTER,image=menu_fin)
    
    canvas.pack()
    canvas.focus_set()
    
    
    fenetre.mainloop()