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(或任何其他名称),并更改绑定,您的代码将正常工作。