4

I am programing a Flappy Bird but I can not stop a function with another function ... I wish that the function "fin" stops the movement (of the bird, the ground and the pipes) and the jumps of the bird (and therefore the functions "deplacement" and "saut") if pause == 0 but I did not find anyone wanting the same thing.

That's why I'm asking for this, maybe the answer is really simple but I just do not know it.

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

Here is the link ;)

 # -*- coding: utf-8 -*-
"""Le jeu Flappy Bird

Création du jeu Flappy Bird pour le projet d'ISN...

"""

from tkinter import *
import random
from random import randint

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

def deplacement():
    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)

    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-241)
    if tuyx>=-28:
        tuyx=tuyx-5
    else:
        tuyx=316
        h=randint(256,505)
        score+=1

    canvas.coords(image_tuyau_haut2,tuyx2,H)
    canvas.coords(image_tuyau_bas2,tuyx2,H-241)
    if tuyx2>=-28:
        tuyx2=tuyx2-5
    else:
        tuyx2=316
        H=randint(256,505)
        score+=1

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

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

def fin():
    pause=0
    if pause==0:


def rejouer():
    global tuyx,tuyx2,oisx,oisy,solx,sol2x,score
    tuyx=316
    tuyx2=488
    oisx=67
    oisy=244
    solx=144
    sol2x=432
    score=0



LARGEUR = 286
HAUTEUR = 510
DY = 5
tuyx=316
tuyx2=488 
h=randint(256,505)
H=randint(256,505)
oisx=67
oisy=244
solx=144
sol2x=432
score=0


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()

menu_debut=PhotoImage(file="menu_jeu.png")
M=Button(fenetre,image=menu_debut,relief=FLAT,command=debut)
Menu_w = canvas.create_window(144,256,window=M)

canvas.pack()
canvas.focus_set()

fenetre.mainloop() 
Finstor
  • 109
  • 10
  • 3
    Might be time to re-design your code. What you need is a separate game loop which runs alongside Tkinter's main loop – see [here](https://stackoverflow.com/questions/459083/how-do-you-run-your-own-code-alongside-tkinters-event-loop) for more details. – meowgoesthedog Apr 23 '19 at 12:13
  • Thank you but I did not understand what I'm supposed to do, could you help me please? (i'm french and there are several untranslatable elements :( ) – Finstor Apr 23 '19 at 12:40

1 Answers1

1

In order to suspend the animation, you can stop the after method, with the use of after_cancel. To do so, you must assign a reference to the callback to a variable, and use it to to cancel.

import random
import tkinter as tk


WIDTH, HEIGHT = 500, 500


def create_pipes():
    pipes = []
    for x in range(0, WIDTH, 40):
        y1 = random.randrange(50, HEIGHT - 50)
        y0 = y1 + 50
        pipes.append(canvas.create_line(x, 0, x, y1))
        pipes.append(canvas.create_line(x, y0, x, HEIGHT))
    return pipes


def move_pipes():
    global animate   #<-- must be global so the value assigned is available to the stop() function.
                     #    you probably want to refactor and use classes to avoid propagation of globals in your program.
    for pipe in pipes:
        canvas.move(pipe, -2, 0)
        x, y0, _, y1 = canvas.coords(pipe)
        if x < 0:
            canvas.coords(pipe, WIDTH+20, y0, WIDTH+20, y1)

    if random.randrange(0, 20) == 10:
        on_change()

    animate = root.after(40, move_pipes)  # <-- assign a reference to the global variable animate


def stop():
    root.after_cancel(animate)   # <-- use the reference to the callback to cancel it.


def on_change():
    global score
    score += 1
    score_variable.set(f'score: {score}')


root = tk.Tk()
tk.Button(root, text='start', command=move_pipes).pack()

animate = None   #<-- create a variable to hold a reference to the callback calls
tk.Button(root, text='stop', command=stop).pack()
score = 0
score_variable = tk.StringVar(root, f'score: {score}')
score_lbl = tk.Label(root, textvariable=score_variable)
score_lbl.pack()

canvas = tk.Canvas(root, width=WIDTH, height=HEIGHT, bg="cyan")
canvas.pack()

pipes = create_pipes()

root.mainloop() 
Reblochon Masque
  • 35,405
  • 10
  • 55
  • 80
  • And what should I put if I also want to stop the jumps of the bird with the space key ? – Finstor Apr 23 '19 at 13:56
  • 1
    `sauter` is bound with `canvas.bind("", sauter)` - you can unbind it with `canvas.unbind("")`, I think (you may have to verify the syntax in the docs); you can probably place that line in `stop()` – Reblochon Masque Apr 23 '19 at 14:37