canvas.bind_all(“ <​​key>”,....)没有调用我的函数

时间:2018-08-26 11:29:58

标签: python python-3.x tkinter tkinter-canvas

我一直在做一个游戏,玩家在游戏中控制飞船,并且必须在屏幕上收集东西。但是,我发现船的运动不令人满意,而且难以控制。为了解决这个问题,我希望飞船始终在移动,玩家可以在其中使用箭头键更改飞船的方向。

我以为我找到了一个解决方案,但是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)

2 个答案:

答案 0 :(得分:1)

您的问题很简单,您有两个同名的全局对象:一个名为ship_direction的变量和一个名为ship_direction的函数。创建变量时,它会覆盖函数,因此该函数不再存在。

如果您将函数从ship_direction重命名为change_ship_direction(或任何其他名称),并且还更改了绑定,则代码将起作用。

答案 1 :(得分:-2)

  

您的问题是您试图调用一个尚未定义的函数。因此,我做了一些替换您的代码的操作,但不需要在其中添加单个字符即可使用。在这里

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)
  

我所做的就是将创建窗口的代码移到顶部,以便在调用其他任何窗口之前先创建窗口,然后我将canvas.bind_all函数移动到应该调用的函数下面

编辑 为什么此答案不正确,因为它提供了正确的代码并定位了代码中的错误?