canvas.bind_all("<key>", ....) 没有调用我的函数
canvas.bind_all("<key>", ....) isn't calling my function
我一直在制作一款游戏,其中玩家控制一艘船并且必须在屏幕周围收集东西。但是,我发现船的运动不尽如人意,而且很难控制。为了解决这个问题,我想让船一直在移动,玩家可以使用箭头键改变船的方向。
我以为我找到了解决方案,但 c.bind_all 不会调用我的函数。我在 shell 中没有收到任何错误,它会调用其他函数。
from tkinter import *
from random import randint
from time import sleep, time
# Window size
window_height = 500
window_width = 800
ship_speed = 10 # Sets how many pixels to move the ship when a key is pressed
min_bubble_r = 10 # Minimum size of each bubble
max_bubble_r = 30 # Maximum size of each bubble
max_bubble_speed = 4 # Maximum speed of each bubble
gap = 100 # How far across the screen to spawn the bubbles (higher is further right)
bubble_chance = 50 # The chance of a bubble being created
# Changes the direction of the ship depending on which key is pressed
def ship_direction(event):
global ship_direction # Takes the ship direction variable from outside the function
if event.keysym == "Up":
ship_direction = "Up"
elif event.keysym == "Down":
ship_direction = "Down"
elif event.keysym == "Right":
ship_direction = "Right"
elif event.keysym == "Left":
ship_direction = "Left"
# Creates a bubble and adds its info to the lists
def create_bubble():
# Sets the bubble position on the canvas
x = window_width + gap
y = randint(0, window_height)
r = randint(min_bubble_r, max_bubble_r) # Picks a random size for the bubble between the min and max
id1 = c.create_oval(x-r, y-r, x+r, y+r, outline="white") # Creates the bubble shape
# Adds the ID, radius and speed of the bubble to the lists
bubble_id.append(id1)
bubble_r.append(r)
bubble_speed.append(randint(1, max_bubble_speed))
# Moves the ship depending on its direction
ship_direction = str() # Creates an empty string for the ship's movement direction
def move_ship():
if ship_direction == "Up":
c.move(ship_part1, 0, -ship_speed)
c.move(ship_part2, 0, -ship_speed)
elif ship_direction == "Down":
c.move(ship_part1, 0, ship_speed)
c.move(ship_part2, 0, ship_speed)
elif ship_direction == "Right":
c.move(ship_part1, ship_speed, 0)
c.move(ship_part2, ship_speed, 0)
elif ship_direction == "Left":
c.move(ship_part1, -ship_speed, 0)
c.move(ship_part2, -ship_speed, 0)
# Goes through each existing bubble and moves them
def move_bubbles():
# Runs once for each existing bubble
for i in range(len(bubble_id)):
c.move(bubble_id[i], -bubble_speed[i], 0) # Moves the bubble depending on its speed
# Gets the co-ordinates of a bubble
def get_coordinates(id_number):
pos = c.coords(id_number) # Gets the co-ordinates
x = (pos[0] + pos[2])/2 # Works out the x co-ordinate of the middle of the bubble
y = (pos[1] + pos[3])/2 # Works out the y co-ordinate of the middle of the bubble
return x, y
window = Tk() # Creates a new window
window.title("Bubble Blaster") # Title in the top bar
c = Canvas(window, width=window_width, height=window_height, bg="#4269dd") # Creates a canvas that can be drawn on
c.pack()
ship_part1 = c.create_polygon(10, 10, 10, 50, 50, 10, 50, 50, fill="white") # Creates the centre part of the ship
ship_part2 = c.create_oval(3, 3, 57, 57, outline="white") # Creates the circle part of the ship
ship_r = 27 # Sets the ship's radius (for colisions
mid_x = window_width / 2 # Sets the page midway point on the X axis
mid_y = window_height / 2 # Sets the page midway point on the Y axis
c.move(ship_part1, mid_x-ship_r, mid_y-ship_r) # Moves part 1 of the ship to the centre of the page
c.move(ship_part2, mid_x-ship_r, mid_y-ship_r) # Moves part 2 of the ship to the centre of the page
c.bind_all("<Key>", ship_direction) # Runs the ship_direction function whenever a key is pressed
# Creates empty lists to store the ID, radius and speed of each bubble
bubble_id = list()
bubble_r = list()
bubble_speed = list()
# Main loop
while True:
if randint(1, bubble_chance) == 1:
create_bubble()
move_ship()
move_bubbles()
window.update() # Redraws the newly moved objects
sleep(0.01)
your problem was that you are trying to call a function that is not yet defined. So i did some replacing of your code but did not need to add a single character to it for it to work. here you go
from tkinter import *
from random import randint
from time import sleep, time
# Window size
window_height = 500
window_width = 800
ship_speed = 10 # Sets how many pixels to move the ship when a key is pressed
min_bubble_r = 10 # Minimum size of each bubble
max_bubble_r = 30 # Maximum size of each bubble
max_bubble_speed = 4 # Maximum speed of each bubble
gap = 100 # How far across the screen to spawn the bubbles (higher is further right)
bubble_chance = 50 # The chance of a bubble being created
window = Tk() # Creates a new window
window.title("Bubble Blaster") # Title in the top bar
c = Canvas(window, width=window_width, height=window_height, bg="#4269dd") # Creates a canvas that can be drawn on
c.pack()
ship_part1 = c.create_polygon(10, 10, 10, 50, 50, 10, 50, 50, fill="white") # Creates the centre part of the ship
ship_part2 = c.create_oval(3, 3, 57, 57, outline="white") # Creates the circle part of the ship
ship_r = 27 # Sets the ship's radius (for colisions
mid_x = window_width / 2 # Sets the page midway point on the X axis
mid_y = window_height / 2 # Sets the page midway point on the Y axis
c.move(ship_part1, mid_x-ship_r, mid_y-ship_r) # Moves part 1 of the ship to the centre of the page
c.move(ship_part2, mid_x-ship_r, mid_y-ship_r) # Moves part 2 of the ship to the centre of the page
# Changes the direction of the ship depending on which key is pressed
def ship_direction(event):
global ship_direction # Takes the ship direction variable from outside the function
if event.keysym == "Up":
ship_direction = "Up"
elif event.keysym == "Down":
ship_direction = "Down"
elif event.keysym == "Right":
ship_direction = "Right"
elif event.keysym == "Left":
ship_direction = "Left"
c.bind_all("<Key>", ship_direction) # Runs the ship_direction function whenever a key is pressed
# Creates a bubble and adds its info to the lists
def create_bubble():
# Sets the bubble position on the canvas
x = window_width + gap
y = randint(0, window_height)
r = randint(min_bubble_r, max_bubble_r) # Picks a random size for the bubble between the min and max
id1 = c.create_oval(x-r, y-r, x+r, y+r, outline="white") # Creates the bubble shape
# Adds the ID, radius and speed of the bubble to the lists
bubble_id.append(id1)
bubble_r.append(r)
bubble_speed.append(randint(1, max_bubble_speed))
# Moves the ship depending on its direction
ship_direction = str() # Creates an empty string for the ship's movement direction
def move_ship():
if ship_direction == "Up":
c.move(ship_part1, 0, -ship_speed)
c.move(ship_part2, 0, -ship_speed)
elif ship_direction == "Down":
c.move(ship_part1, 0, ship_speed)
c.move(ship_part2, 0, ship_speed)
elif ship_direction == "Right":
c.move(ship_part1, ship_speed, 0)
c.move(ship_part2, ship_speed, 0)
elif ship_direction == "Left":
c.move(ship_part1, -ship_speed, 0)
c.move(ship_part2, -ship_speed, 0)
# Goes through each existing bubble and moves them
def move_bubbles():
# Runs once for each existing bubble
for i in range(len(bubble_id)):
c.move(bubble_id[i], -bubble_speed[i], 0) # Moves the bubble depending on its speed
# Gets the co-ordinates of a bubble
def get_coordinates(id_number):
pos = c.coords(id_number) # Gets the co-ordinates
x = (pos[0] + pos[2])/2 # Works out the x co-ordinate of the middle of the bubble
y = (pos[1] + pos[3])/2 # Works out the y co-ordinate of the middle of the bubble
return x, y
# Creates empty lists to store the ID, radius and speed of each bubble
bubble_id = list()
bubble_r = list()
bubble_speed = list()
# Main loop
while True:
if randint(1, bubble_chance) == 1:
create_bubble()
move_ship()
move_bubbles()
window.update() # Redraws the newly moved objects
sleep(0.01)
What i did was moving the code that creates the window to the top so the window will be created before anything else is called, then i moved the canvas.bind_all function bellow your function that it is supposed to call
编辑
为什么这个答案被否决,因为它提供了正确的代码并定位了代码中的错误?
您的问题只是您有两个同名的全局对象:一个名为 ship_direction
的变量和一个名为 ship_direction
的函数。当您创建变量时,它会覆盖函数,因此函数不再存在。
如果您将函数从 ship_direction
重命名为 change_ship_direction
(或任何其他名称),并更改绑定,您的代码将正常工作。
我一直在制作一款游戏,其中玩家控制一艘船并且必须在屏幕周围收集东西。但是,我发现船的运动不尽如人意,而且很难控制。为了解决这个问题,我想让船一直在移动,玩家可以使用箭头键改变船的方向。
我以为我找到了解决方案,但 c.bind_all 不会调用我的函数。我在 shell 中没有收到任何错误,它会调用其他函数。
from tkinter import *
from random import randint
from time import sleep, time
# Window size
window_height = 500
window_width = 800
ship_speed = 10 # Sets how many pixels to move the ship when a key is pressed
min_bubble_r = 10 # Minimum size of each bubble
max_bubble_r = 30 # Maximum size of each bubble
max_bubble_speed = 4 # Maximum speed of each bubble
gap = 100 # How far across the screen to spawn the bubbles (higher is further right)
bubble_chance = 50 # The chance of a bubble being created
# Changes the direction of the ship depending on which key is pressed
def ship_direction(event):
global ship_direction # Takes the ship direction variable from outside the function
if event.keysym == "Up":
ship_direction = "Up"
elif event.keysym == "Down":
ship_direction = "Down"
elif event.keysym == "Right":
ship_direction = "Right"
elif event.keysym == "Left":
ship_direction = "Left"
# Creates a bubble and adds its info to the lists
def create_bubble():
# Sets the bubble position on the canvas
x = window_width + gap
y = randint(0, window_height)
r = randint(min_bubble_r, max_bubble_r) # Picks a random size for the bubble between the min and max
id1 = c.create_oval(x-r, y-r, x+r, y+r, outline="white") # Creates the bubble shape
# Adds the ID, radius and speed of the bubble to the lists
bubble_id.append(id1)
bubble_r.append(r)
bubble_speed.append(randint(1, max_bubble_speed))
# Moves the ship depending on its direction
ship_direction = str() # Creates an empty string for the ship's movement direction
def move_ship():
if ship_direction == "Up":
c.move(ship_part1, 0, -ship_speed)
c.move(ship_part2, 0, -ship_speed)
elif ship_direction == "Down":
c.move(ship_part1, 0, ship_speed)
c.move(ship_part2, 0, ship_speed)
elif ship_direction == "Right":
c.move(ship_part1, ship_speed, 0)
c.move(ship_part2, ship_speed, 0)
elif ship_direction == "Left":
c.move(ship_part1, -ship_speed, 0)
c.move(ship_part2, -ship_speed, 0)
# Goes through each existing bubble and moves them
def move_bubbles():
# Runs once for each existing bubble
for i in range(len(bubble_id)):
c.move(bubble_id[i], -bubble_speed[i], 0) # Moves the bubble depending on its speed
# Gets the co-ordinates of a bubble
def get_coordinates(id_number):
pos = c.coords(id_number) # Gets the co-ordinates
x = (pos[0] + pos[2])/2 # Works out the x co-ordinate of the middle of the bubble
y = (pos[1] + pos[3])/2 # Works out the y co-ordinate of the middle of the bubble
return x, y
window = Tk() # Creates a new window
window.title("Bubble Blaster") # Title in the top bar
c = Canvas(window, width=window_width, height=window_height, bg="#4269dd") # Creates a canvas that can be drawn on
c.pack()
ship_part1 = c.create_polygon(10, 10, 10, 50, 50, 10, 50, 50, fill="white") # Creates the centre part of the ship
ship_part2 = c.create_oval(3, 3, 57, 57, outline="white") # Creates the circle part of the ship
ship_r = 27 # Sets the ship's radius (for colisions
mid_x = window_width / 2 # Sets the page midway point on the X axis
mid_y = window_height / 2 # Sets the page midway point on the Y axis
c.move(ship_part1, mid_x-ship_r, mid_y-ship_r) # Moves part 1 of the ship to the centre of the page
c.move(ship_part2, mid_x-ship_r, mid_y-ship_r) # Moves part 2 of the ship to the centre of the page
c.bind_all("<Key>", ship_direction) # Runs the ship_direction function whenever a key is pressed
# Creates empty lists to store the ID, radius and speed of each bubble
bubble_id = list()
bubble_r = list()
bubble_speed = list()
# Main loop
while True:
if randint(1, bubble_chance) == 1:
create_bubble()
move_ship()
move_bubbles()
window.update() # Redraws the newly moved objects
sleep(0.01)
your problem was that you are trying to call a function that is not yet defined. So i did some replacing of your code but did not need to add a single character to it for it to work. here you go
from tkinter import *
from random import randint
from time import sleep, time
# Window size
window_height = 500
window_width = 800
ship_speed = 10 # Sets how many pixels to move the ship when a key is pressed
min_bubble_r = 10 # Minimum size of each bubble
max_bubble_r = 30 # Maximum size of each bubble
max_bubble_speed = 4 # Maximum speed of each bubble
gap = 100 # How far across the screen to spawn the bubbles (higher is further right)
bubble_chance = 50 # The chance of a bubble being created
window = Tk() # Creates a new window
window.title("Bubble Blaster") # Title in the top bar
c = Canvas(window, width=window_width, height=window_height, bg="#4269dd") # Creates a canvas that can be drawn on
c.pack()
ship_part1 = c.create_polygon(10, 10, 10, 50, 50, 10, 50, 50, fill="white") # Creates the centre part of the ship
ship_part2 = c.create_oval(3, 3, 57, 57, outline="white") # Creates the circle part of the ship
ship_r = 27 # Sets the ship's radius (for colisions
mid_x = window_width / 2 # Sets the page midway point on the X axis
mid_y = window_height / 2 # Sets the page midway point on the Y axis
c.move(ship_part1, mid_x-ship_r, mid_y-ship_r) # Moves part 1 of the ship to the centre of the page
c.move(ship_part2, mid_x-ship_r, mid_y-ship_r) # Moves part 2 of the ship to the centre of the page
# Changes the direction of the ship depending on which key is pressed
def ship_direction(event):
global ship_direction # Takes the ship direction variable from outside the function
if event.keysym == "Up":
ship_direction = "Up"
elif event.keysym == "Down":
ship_direction = "Down"
elif event.keysym == "Right":
ship_direction = "Right"
elif event.keysym == "Left":
ship_direction = "Left"
c.bind_all("<Key>", ship_direction) # Runs the ship_direction function whenever a key is pressed
# Creates a bubble and adds its info to the lists
def create_bubble():
# Sets the bubble position on the canvas
x = window_width + gap
y = randint(0, window_height)
r = randint(min_bubble_r, max_bubble_r) # Picks a random size for the bubble between the min and max
id1 = c.create_oval(x-r, y-r, x+r, y+r, outline="white") # Creates the bubble shape
# Adds the ID, radius and speed of the bubble to the lists
bubble_id.append(id1)
bubble_r.append(r)
bubble_speed.append(randint(1, max_bubble_speed))
# Moves the ship depending on its direction
ship_direction = str() # Creates an empty string for the ship's movement direction
def move_ship():
if ship_direction == "Up":
c.move(ship_part1, 0, -ship_speed)
c.move(ship_part2, 0, -ship_speed)
elif ship_direction == "Down":
c.move(ship_part1, 0, ship_speed)
c.move(ship_part2, 0, ship_speed)
elif ship_direction == "Right":
c.move(ship_part1, ship_speed, 0)
c.move(ship_part2, ship_speed, 0)
elif ship_direction == "Left":
c.move(ship_part1, -ship_speed, 0)
c.move(ship_part2, -ship_speed, 0)
# Goes through each existing bubble and moves them
def move_bubbles():
# Runs once for each existing bubble
for i in range(len(bubble_id)):
c.move(bubble_id[i], -bubble_speed[i], 0) # Moves the bubble depending on its speed
# Gets the co-ordinates of a bubble
def get_coordinates(id_number):
pos = c.coords(id_number) # Gets the co-ordinates
x = (pos[0] + pos[2])/2 # Works out the x co-ordinate of the middle of the bubble
y = (pos[1] + pos[3])/2 # Works out the y co-ordinate of the middle of the bubble
return x, y
# Creates empty lists to store the ID, radius and speed of each bubble
bubble_id = list()
bubble_r = list()
bubble_speed = list()
# Main loop
while True:
if randint(1, bubble_chance) == 1:
create_bubble()
move_ship()
move_bubbles()
window.update() # Redraws the newly moved objects
sleep(0.01)
What i did was moving the code that creates the window to the top so the window will be created before anything else is called, then i moved the canvas.bind_all function bellow your function that it is supposed to call
编辑 为什么这个答案被否决,因为它提供了正确的代码并定位了代码中的错误?
您的问题只是您有两个同名的全局对象:一个名为 ship_direction
的变量和一个名为 ship_direction
的函数。当您创建变量时,它会覆盖函数,因此函数不再存在。
如果您将函数从 ship_direction
重命名为 change_ship_direction
(或任何其他名称),并更改绑定,您的代码将正常工作。