Finstor
Finstor

Reputation: 109

How to stop a function with another function ? (in python)

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

Upvotes: 4

Views: 2450

Answers (1)

Reblochon Masque
Reblochon Masque

Reputation: 36682

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

Upvotes: 1

Related Questions