So I copied this code from a python book, and the code is meant to be like an egg catcher game, however if you run the code, you can see, tkinter creates everything and the game sets up, however, the game itself does not start. Does anyone know how to make it start? I tried pressing buttons and making the whole thing a function, however, they both do not work. Here is my code below...
from itertools import cycle
from random import randrange
from tkinter import Canvas, Tk, messagebox, font
canvas_width = 800
canvas_height = 400
root = Tk()
c = Canvas(root, width=canvas_width, height=canvas_height, background='deep sky blue')
c.create_rectangle(-5, canvas_height - 100, canvas_width + 5, canvas_height + 5, \
fill='sea green', width=0)
c.create_oval(-80, -80, 120, 120, fill='orange', width=0)
c.pack()
color_cycle = cycle(['light blue', 'light green', 'light pink', 'light yellow', 'light cyan'])
egg_width = 45
egg_height = 55
egg_score = 10
egg_speed = 500
egg_interval = 4000
difficulty_factor = 0.95
catcher_color = 'blue'
catcher_width = 100
catcher_height = 100
catcher_start_x = canvas_width / 2 - catcher_width / 2
catcher_start_y = canvas_height - catcher_height - 20
catcher_start_x2 = catcher_start_x + catcher_width
catcher_start_y2 = catcher_start_y + catcher_height
catcher = c.create_arc(catcher_start_x, catcher_start_y, \
catcher_start_x2, catcher_start_y2, start=200, extent=140, \
style='arc', outline=catcher_color, width=3)
game_font = font.nametofont('TkFixedFont')
game_font.config(size=18)
score = 0
score_text = c.create_text(10, 10, anchor='nw', font=game_font, fill='darkblue', \
text='Score: ' + str(score))
lives_remaining = 3
lives_text = c.create_text(canvas_width - 10, 10, anchor='ne', font=game_font, fill='darkblue', \
text='Lives: ' + str(lives_remaining))
eggs = []
def create_egg():
x = randrange(10, 740)
y = 40
new_egg = c.create_oval(x, y, x + egg_width, y + egg_height, fill=next(color_cycle), width=0)
eggs.append(new_egg)
root.after(egg_interval, create_egg)
def move_eggs():
for egg in eggs:
(egg_x, egg_y, egg_x2, egg_y2) = c.coords(egg)
c.move(egg, 0, 10)
if egg_y2 > canvas_height:
egg_dropped(egg)
root.after(egg_speed, move_eggs)
def egg_dropped(egg):
eggs.remove(egg)
c.delete(egg)
lose_a_life()
if lives_remaining == 0:
messagebox.showinfo('Game Over!', 'Final Score: ' + str(score))
root.destroy()
def lose_a_life():
global lives_remaining
lives_remaining -= 1
c.itemconfigure(lives_text, text='Lives: ' + str(lives_remaining))
def check_catch():
(catcher_x, catcher_y, catcher_x2, catcher_y2) = c.coords(catcher)
for egg in eggs:
(egg_x, egg_y, egg_x2, egg_y2) = c.coords(egg)
if catcher_x < egg_x and egg_x2 < catcher_x2 and catcher_y2 - egg_y2 < 40:
eggs.remove(egg)
c.delete(egg)
increase_score(egg_score)
root.after(100, check_catch)
def increase_score(points):
global score, egg_speed, egg_interval
score += points
egg_speed = int(egg_speed * difficulty_factor)
egg_interval = int(egg_interval * difficulty_factor)
c.itemconfigure(score_text, text='Score: ' + str(score))
def move_left(event):
(x1, y1, x2, y2) = c.coords(catcher)
if x1 > 0:
c.move(catcher, -20, 0)
def move_right(event):
(x1, y1, x2, y2) = c.coords(catcher)
if x2 < canvas_width:
c.move(catcher, 20, 0)
c.bind('<Left>', move_left)
c.bind('<Right>', move_right)
c.focus_set()
root.after(1000, create_egg)
root.after(1000, move_eggs)
root.after(1000, check_catch)
root.mainloop()
I see lots of functions but no calls to them, especially the function that runs the Tkinter main loop.
Given the similarity you would expect between the move_left() and move_right() functions, it's a near certainty that the final lines of the latter should not be indented to where they are.
With your current code, the lines doing the binding and timer call-back setups are only executed when move_right() is called. Which it isn't, because the key binding that would call it is only set up when it's called (which it isn't because ...
WARNING W-42: thought process terminated due to likely stack overflow in wet-ware :-)
In other words, your code should be something like:
def move_left(event):
(x1, y1, x2, y2) = c.coords(catcher)
if x1 > 0:
c.move(catcher, -20, 0)
def move_right(event):
(x1, y1, x2, y2) = c.coords(catcher)
if x2 < canvas_width:
c.move(catcher, 20, 0)
# Run this at top level, NOT as part of move_right().
c.bind('<Left>', move_left)
c.bind('<Right>', move_right)
c.focus_set()
root.after(1000, create_egg)
root.after(1000, move_eggs)
root.after(1000, check_catch)
root.mainloop()
As an aside, it may just be the way you pasted the code in, but you should try to follow the PEP8 style guide when writing code, specifically the four-space-indent guideline. They generally make your code much easier to read and/or analyse.
And, just so you're aware, those move_xxx() functions will actually allow your catcher to go off the edges of the screen (up to twenty pixels, I think). If that's not what you want, you may want to make a small change:
move_sz = 20
def move_left(event):
(x1, y1, x2, y2) = c.coords(catcher)
c.move(catcher, -min(move_sz, x1), 0)
def move_right(event):
(x1, y1, x2, y2) = c.coords(catcher)
c.move(catcher, min(move_sz, canvas_width - x2 - 1), 0)
I haven't tested that (particularly the possibility of being out by one pixel - I'll leave that up to you) but the idea is just to limit how much you move if that would send your catcher outside the canvas bounds.
You'll see I've also replaced the magic constant 20 with a more appropriate variable - that's so you only need to change it in one place should you want to adjust the movement speed.
Related
I was trying to make a catch the egg game but it didn't go to plan and it brought up an error saying
_tkinter.TclError: invalid command name ".!canvas".
I have searched the whole of the internet about the problem but none of the solutions that people the person helped me at all.
anyways this is what I have written so far it would be appreciated if someone helped especailly because I'm new.
from itertools import cycle
from random import randrange
from tkinter import Canvas, Tk, messagebox, font
canvas_width = 800
canvas_height = 400
root = Tk()
c = Canvas(root, width = canvas_width, height = canvas_height, background="deep sky blue")
c.create_rectangle(-5, canvas_height - 100, canvas_width + 5, canvas_height + 5, fill = "sea green", width=0)
c.create_oval(-80, -80, 120, 120, fill="orange", width=0)
c.pack()
color_cycle = cycle(["light blue", "light green", "light pink", "light yellow", "light cyan"])
egg_width = 45
egg_height = 55
egg_score = 10
egg_speed = 500
egg_interval = 4000
difficulty_factor = 0.95
catcher_color = "magenta"
catcher_width = 100
catcher_height = 100
catcher_start_x = canvas_width / 2 - catcher_width / 2
catcher_start_y = canvas_height - catcher_width - 20
catcher_start_x2 = catcher_start_x = catcher_width
catcher_start_y2 = catcher_start_y + catcher_height
catcher = c.create_arc(catcher_start_x, catcher_start_y, catcher_start_x2, catcher_start_y2, start = 200, extent = 140, \
style = "arc", outline = catcher_color, width = 3)
game_font = font.nametofont("TkFixedFont")
game_font.config(size = 18)
score = 0
score_text = c.create_text(10, 10, anchor="nw" , font=game_font, fill="darkblue", text="Score: " + str(score))
lives_remaining = 1
lives_text = c.create_text(canvas_width - 10, 10, anchor="ne", font = game_font, fill="darkblue", text = "Lives " + str(lives_remaining))
eggs = []
def create_egg():
x = randrange(10, 740)
y = 40
new_egg = c.create_oval(x, y, x + egg_width, y + egg_height, fill = next(color_cycle), width=0)
eggs.append(new_egg)
root.after(egg_interval, create_egg)
def move_eggs():
for egg in eggs:
(egg_x, egg_y, egg_x2, egg_y2) = c.coords(egg)
c.move(egg, 0, 10)
if egg_y2 > canvas_height:
egg_dropped(egg)
root.after(egg_speed, move_eggs)
def egg_dropped(egg):
eggs.remove(egg)
lose_a_life()
if lives_remaining == 0:
messagebox.showinfo("Game Over!", "Final Score: " + str(score))
root.destroy()
def lose_a_life():
global lives_remaining
lives_remaining -= 1
c.itemconfigure(lives_text, text = "Lives: " + str(lives_remaining))
def check_catch():
(catcher_x, catcher_y, catcher_x2, catcher_y2) = c.coords(catcher)
for egg in eggs:
(egg_x, egg_y, egg_x2, egg_y2) = c.coords(egg)
if catcher_x < egg_x and egg_x2 < catcher_x2 and catcher_y2 - egg_y2 - egg_y2 < 40:
eggs.remove(egg)
c.delete(egg)
increase_score(egg_score)
root.after(100, check_catch)
def increase_score(points):
global score, egg_speed, egg_interval
score += points
egg_speed = int(egg_speed * difficulty_factor)
egg_interval = int(egg_interval * difficulty_factor)
c.itemconfigure(score_text, text="Score: " + str(score))
def move_left(event):
(x1, y1, x2, y2) = c.coords(catcher)
if x1 > 0:
c.move(catcher, -20, 0)
def move_right(event):
(x1, y1, x2, y2) = c.coords(catcher)
if x2 < canvas_width:
c.move(catcher, 20, 0)
c.bind("<Left>" , move_left)
c.bind("<Right>" , move_right)
c.focus_set()
root.after(1000, create_egg)
root.after(1000, move_eggs)
root.after(1000, check_catch)
root.mainloop()
I changed the way it checks for hits and it works now.
def check_catch():
catcher_x, catcher_y, catcher_x2, catcher_y2 = c.coords(catcher)
for egg in eggs:
egg_x, egg_y, egg_x2, egg_y2 = c.coords(egg)
print(c.coords(egg))
if egg_x<catcher_x<egg_x2 and (catcher_y2 - egg_y2) < 5:
eggs.remove(egg)
c.delete(egg)
increase_score(egg_score)
root.after(100, check_catch)
I am trying to make a catch the egg game and it is going fine apart from the basket, which is supposed to look like an arc upside-down but it became a very strange shape, and I have searched as far as I could but no one has had such a problem like this.
I want it to look like this:
I'll have to post the whole program otherwise you wouldn't understand:
from itertools import cycle
from random import randrange
from tkinter import Canvas, Tk, messagebox, font
canvas_width = 800
canvas_height = 400
root = Tk()
c = Canvas(
root,
width=canvas_width,
height=canvas_height,
background="deep sky blue"
)
c.create_rectangle(
-5,
canvas_height - 100,
canvas_width + 5,
canvas_height + 5,
fill="sea green",
width=0
)
c.create_oval(-80, -80, 120, 120, fill="orange", width=0)
c.pack()
color_cycle = cycle([
"light blue",
"light green",
"light pink",
"light yellow",
"light cyan"
])
egg_width = 45
egg_height = 55
egg_score = 10
egg_speed = 500
egg_interval = 4000
difficulty_factor = 0.95
catcher_color = "blue"
catcher_width = 100
catcher_height = 100
catcher_start_x = canvas_width / 2 - catcher_width / 2
catcher_start_y = canvas_height - catcher_width - 20
catcher_start_x2 = catcher_start_x = catcher_width
catcher_start_y2 = catcher_start_y + catcher_height
catcher = c.create_arc(
catcher_start_x,
catcher_start_y,
catcher_start_x2,
catcher_start_y2,
start=200,
extent=140,
style="arc",
outline=catcher_color,
width=30
)
game_font = font.nametofont("TkFixedFont")
game_font.config(size=18)
score = 0
score_text = c.create_text(
10,
10,
anchor="nw" ,
font=game_font,
fill="darkblue",
text="Score: " + str(score)
)
lives_remaining = 3
lives_text = c.create_text(
canvas_width - 10,
10,
anchor="ne",
font=game_font,
fill="darkblue",
text="Lives " + str(lives_remaining)
)
eggs = []
def create_egg():
x = randrange(10, 740)
y = 40
new_egg = c.create_oval(
x,
y,
x + egg_width,
y + egg_height,
fill=next(color_cycle),
width=0
)
eggs.append(new_egg)
root.after(egg_interval, create_egg)
def move_eggs():
for egg in eggs:
(egg_x, egg_y, egg_x2, egg_y2) = c.coords(egg)
c.move(egg, 0, 10)
if egg_y2 > canvas_height:
egg_dropped(egg)
root.after(egg_speed, move_eggs)
def egg_dropped(egg):
eggs.remove(egg)
lose_a_life()
if lives_remaining == 0:
messagebox.showinfo("Game Over!", "Final Score: " + str(score))
root.destroy()
def lose_a_life():
global lives_remaining
lives_remaining -= 1
c.itemconfigure(lives_text, text = "Lives: " + str(lives_remaining))
def check_catch():
catcher_x, catcher_y, catcher_x2, catcher_y2 = c.coords(catcher)
for egg in eggs:
egg_x, egg_y, egg_x2, egg_y2 = c.coords(egg)
if egg_x<catcher_x<egg_x2 and (catcher_y2 - egg_y2) < 5:
eggs.remove(egg)
c.delete(egg)
increase_score(egg_score)
root.after(100, check_catch)
def increase_score(points):
global score, egg_speed, egg_interval
score += points
egg_speed = int(egg_speed * difficulty_factor)
egg_interval = int(egg_interval * difficulty_factor)
c.itemconfigure(score_text, text="Score: " + str(score))
def move_left(event):
(x1, y1, x2, y2) = c.coords(catcher)
if x1 > 0:
c.move(catcher, -20, 0)
def move_right(event):
(x1, y1, x2, y2) = c.coords(catcher)
if x2 < canvas_width:
c.move(catcher, 20, 0)
c.bind("<Left>" , move_left)
c.bind("<Right>", move_right)
c.focus_set()
root.after(1000, create_egg)
root.after(1000, move_eggs)
root.after(1000, check_catch)
root.mainloop()
You have a typo on line 27 - you have written catcher_start_x2 = catcher_start_x = catcher_width where you should have catcher_start_x2 = catcher_start_x - catcher_width.
Also, the backslash on line 29 is unnecessary as things contained in brackets automatically continue on multiple lines.
One more thing - once the typo is fixed, the eggs are only caught in the left area of the catcher because line 79 (if egg_x<catcher_x<egg_x2 and (catcher_y2 - egg_y2) < 5:) is checking if the left x coord of the catcher is inside the x coords of the egg not the other way around. To fix this, replace it with
if catcher_x - 10 < egg_x and egg_x2 < catcher_x2 + 10 and (catcher_y2 - egg_y2) < 5: (the -10 and +10 are to give the player a bit of leeway so the egg doesn't have to be exactly in the centre).
I wanted to get a little square to move to the left 10 pixels every 3 seconds and my code is below. I'm not sure why it only moves once. Some help would be greatly apprecaited!
import tkinter as tk
import time
root = tk.Tk()
WIDTH = HEIGHT = 400
x1 = y1 = WIDTH / 2
canvas = tk.Canvas(root, width=WIDTH, height=HEIGHT)
canvas.pack()
c1 = canvas.create_rectangle(x1, y1, x1 + 10, y1 + 10)
c2 = canvas.create_rectangle(x1, y1, x1 + 10, y1 + 10)
def draw_rect():
global c2
canvas.delete(c2)
c2 = canvas.create_rectangle(x1, y1, x1 + 10, y1 + 10, fill="green")
def del_rect():
canvas.delete(c1)
#canvas.create_rectangle(x1, y1, x1 + 10, y1 + 10, fill="white", opacity=0.5)
while 1:
root.update()
time.sleep(3)
del_rect()
x1 -= 10
draw_rect()
root.mainloop()
mainloop() runs loop which works until you close window - so it blocks all loop and it is executed only once and it move rectangle only once. In your version you should remove mainloop() and it will not block it - and because you use update() in loop so it will run correctly.
But you could do this in different way.
You can use root.after(3000, draw_rect) to execute draw_rect() after 3 seconds. And draw_rect() should run again root.after(3000, draw_rect) to run it again after another 3 seconds - this way it will loop and it will not blocked by mainloop() (mainloop() will run draw_rect() every 3 seconds)
Canvas has function move(object, dx, dy) so you don't have to delete rectangle and create it again.
I use 300ms to run it faster.
import tkinter as tk
# --- constants --- (PEP8: UPPER_CASE_NAMES)
WIDTH = 400
HEIGHT = 400
# --- functions ---
def move_rect():
canvas.move(c1, -10, 0) # move left
canvas.move(c2, 10, 0) # move right
# run again after 300ms
root.after(300, move_rect) # 300ms = 0.3s # I use smaller value to make it faster
# --- main ---
x1 = y1 = WIDTH / 2
root = tk.Tk()
canvas = tk.Canvas(root, width=WIDTH, height=HEIGHT)
canvas.pack()
c1 = canvas.create_rectangle(x1, y1, x1 + 10, y1 + 10, fill="green")
c2 = canvas.create_rectangle(x1, y1, x1 + 10, y1 + 10, fill="red")
# run first time after 300ms
root.after(300, move_rect) # 300ms = 0.3s # I use smaller value to make it faster
root.mainloop()
PEP 8 -- Style Guide for Python Code
EDIT:
Version which uses variables speed1, speed2 to change direction when rectangle is near border.
import tkinter as tk
# --- constants --- (PEP8: UPPER_CASE_NAMES)
WIDTH = 400
HEIGHT = 400
# --- functions ---
def move_rect():
global speed1
global speed2
#x1, y1, x2, y2 = canvas.coords(c1)
pos = canvas.coords(c1)
if speed1 < 0 :
if pos[0] < 10:
speed1 = -speed1
else:
if pos[2] > WIDTH-10:
speed1 = -speed1
#x1, y1, x2, y2 = canvas.coords(c2)
pos = canvas.coords(c2)
if speed2 < 0:
if pos[0] < 10:
speed2 = -speed2
else:
if pos[2] > WIDTH-10:
speed2 = -speed2
canvas.move(c1, speed1, 0) # move left
canvas.move(c2, speed2, 0) # move right
# run again after 30ms
root.after(30, move_rect) # 30ms = 0.03s - I uses smaller value to make it faster
# --- main ---
x1 = y1 = WIDTH / 2
speed1 = -10
speed2 = +10
root = tk.Tk()
canvas = tk.Canvas(root, width=WIDTH, height=HEIGHT)
canvas.pack()
print(dir(canvas))
c1 = canvas.create_rectangle(x1, y1, x1 + 10, y1 + 10, fill="green")
c2 = canvas.create_rectangle(x1, y1, x1 + 10, y1 + 10, fill="red")
# run first time after 300ms
root.after(300, move_rect) # 300ms = 0.3s - I uses smaller value to make it faster
root.mainloop()
I'm making a basic game. I want the ball to bounce back up ONLY when it hits the platform. So far, I've written code that will make the ball bounce off the top and bottom screen, but I'm having trouble with getting the ball to bounce off the platform.
from tkinter import *
import time
import tkinter
tk = Tk()
canvas = Canvas(tk, bg="white",width=(900),height=(500))
canvas.pack()
platform = canvas.create_rectangle(400,400,500,410)
def ball():
xspeed = 2
yspeed = 2
ball = canvas.create_oval(430,10,470,50)
while True:
canvas.move(ball, xspeed, yspeed)
pos = canvas.coords(ball)
if pos[2] >=900 or pos[0] <0:
xspeed = -xspeed
tk.update()
time.sleep(0.01)
def board():
board_right()
board_left()
def board_right(event):
xspeed = 5
yspeed = 0
canvas.move(platform,xspeed,yspeed)
tk.update
time.sleep(0.01)
def board_left(event):
xspeed = 5
yspeed = 0
canvas.move(platform,-xspeed,yspeed)
tk.update()
time.sleep(0.01)
canvas.bind_all("<Right>",board_right)
canvas.bind_all("<Left>",board_left)
ball()
tk.mainloop()
Do not use time.sleep() as it will block the tkinter mainloop, use after() instead.
To check whether the ball hits the platform, you need to get the center x of the ball and the lower y of the ball. If center x is within the left and right of platform and the ball lower y is the platform upper y, then reverse the ball y speed. Otherwise game over!
Below is sample code based on yours:
import tkinter as tk
root = tk.Tk()
width = 900
height = 500
canvas = tk.Canvas(root, bg='white', width=width, height=height)
canvas.pack()
ball = canvas.create_oval(430, 10, 470, 50, fill='green')
platform_y = height - 20
platform = canvas.create_rectangle(width//2-50, platform_y, width//2+50, platform_y+10, fill='black')
# ball moving speed
xspeed = yspeed = 2
def move_ball():
global xspeed, yspeed
x1, y1, x2, y2 = canvas.coords(ball)
if x1 <= 0 or x2 >= width:
# hit wall, reverse x speed
xspeed = -xspeed
if y1 <= 0:
# hit top wall
yspeed = 2
elif y2 >= platform_y:
# calculate center x of the ball
cx = (x1 + x2) // 2
# check whether platform is hit
px1, _, px2, _ = canvas.coords(platform)
if px1 <= cx <= px2:
yspeed = -2
else:
canvas.create_text(width//2, height//2, text='Game Over', font=('Arial Bold', 32), fill='red')
return
canvas.move(ball, xspeed, yspeed)
canvas.after(20, move_ball)
def board_right(event):
x1, y1, x2, y2 = canvas.coords(platform)
# make sure the platform is not moved beyond right wall
if x2 < width:
dx = min(width-x2, 10)
canvas.move(platform, dx, 0)
def board_left(event):
x1, y1, x2, y2 = canvas.coords(platform)
# make sure the platform is not moved beyond left wall
if x1 > 0:
dx = min(x1, 10)
canvas.move(platform, -dx, 0)
canvas.bind_all('<Right>', board_right)
canvas.bind_all('<Left>', board_left)
move_ball()
root.mainloop()
My question is about displaying and updating text, in order to display the score on screen.
I would like to create a score like the real game that would appear on the screen. But after researching Google, I have not found anyone wishing to increase a score on the screen ...
Indeed, I would like the score to increase each time the bird passes between the pipes and therefore whenever the pipes have an X of 67 pixels. So does anyone know how to do this?
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
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)
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)
canvas.after(40,deplacement)
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
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)
deplacement()
canvas.pack()
canvas.focus_set()
canvas.bind("<space>",sauter)
fenetre.mainloop()
Could someone explain the problem to me because I thought it would be easy :(
Here are the pictures of the game :)
Here are the pictures of the game
Here is one approach to display the scores: It uses a tk.Label, that is updated at the same time the score increases.
The trigger that increases the score is currently a random call to on_change; you can modify this to be a test if a pipe x coordinates becomes lower than the bird x coordinates (the bird successfully crossed the obstacle)
You can, if you want relocate the score label on the canvas.
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():
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()
root.after(40, move_pipes)
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()
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()