【发布时间】:2021-05-26 11:32:28
【问题描述】:
我一直在使用 tkinter canvas 编写一个 python 蛇游戏,并且在尝试更改每个吃的苹果的滴答速度时遇到了这个错误。如果有人能提供帮助,我将不胜感激,因为我对使用 tkinter 和 python 很陌生。
文件“c:\Users\Admin\Documents\pythonsnake.py”,第 45 行,在 main root.after(滴答速度,主要) UnboundLocalError:赋值前引用了局部变量“Tickspeed”
这是我的代码:
#Python Snake Game
from tkinter import Tk, Canvas
import random
import time
# Globals
WIDTH = 800
HEIGHT = 600
SEG_SIZE = 20
IN_GAME = True
Tickspeed = 100
# Helper functions
def create_block():
""" Creates an apple to be eaten """
global BLOCK
posx = SEG_SIZE * random.randint(1, (WIDTH-SEG_SIZE) / SEG_SIZE)
posy = SEG_SIZE * random.randint(1, (HEIGHT-SEG_SIZE) / SEG_SIZE)
BLOCK = c.create_oval(posx, posy,
posx+SEG_SIZE, posy+SEG_SIZE,
fill="red")
def main():
""" Handles game process """
global IN_GAME
if IN_GAME:
s.move()
head_coords = c.coords(s.segments[-1].instance)
x1, y1, x2, y2 = head_coords
# Check for collision with gamefield edges
if x2 > WIDTH or x1 < 0 or y1 < 0 or y2 > HEIGHT:
IN_GAME = False
# Eating apples
elif head_coords == c.coords(BLOCK):
s.add_segment()
c.delete(BLOCK)
if(Tickspeed>20):
Tickspeed = Tickspeed - 5
create_block()
# Self-eating
else:
for index in range(len(s.segments)-1):
if head_coords == c.coords(s.segments[index].instance):
IN_GAME = False
root.after(Tickspeed, main)
# Not IN_GAME -> stop game and print message
else:
set_state(restart_text, 'normal')
set_state(game_over_text, 'normal')
class Segment(object):
""" Single snake segment """
def __init__(self, x, y):
self.instance = c.create_rectangle(x, y,
x+SEG_SIZE, y+SEG_SIZE,
fill="white")
class Snake(object):
""" Simple Snake class convertable """
def __init__(self, segments):
self.segments = segments
# possible moves
self.mapping = {"Down": (0, 1), "Right": (1, 0),
"Up": (0, -1), "Left": (-1, 0)}
# initial movement direction
self.vector = self.mapping["Right"]
def move(self):
""" Moves the snake with the specified vector"""
for index in range(len(self.segments)-1):
segment = self.segments[index].instance
x1, y1, x2, y2 = c.coords(self.segments[index+1].instance)
c.coords(segment, x1, y1, x2, y2)
x1, y1, x2, y2 = c.coords(self.segments[-2].instance)
c.coords(self.segments[-1].instance,
x1+self.vector[0]*SEG_SIZE, y1+self.vector[1]*SEG_SIZE,
x2+self.vector[0]*SEG_SIZE, y2+self.vector[1]*SEG_SIZE)
def add_segment(self):
""" Adds segment to the snake """
last_seg = c.coords(self.segments[0].instance)
x = last_seg[2] - SEG_SIZE
y = last_seg[3] - SEG_SIZE
self.segments.insert(0, Segment(x, y))
def change_direction(self, event):
""" Changes direction of snake """
if event.keysym in self.mapping:
self.vector = self.mapping[event.keysym]
def reset_snake(self):
for segment in self.segments:
c.delete(segment.instance)
def set_state(item, state):
c.itemconfigure(item, state=state)
def clicked(event):
global IN_GAME
s.reset_snake()
IN_GAME = True
c.delete(BLOCK)
c.itemconfigure(restart_text, state='hidden')
c.itemconfigure(game_over_text, state='hidden')
start_game()
def start_game():
global s
create_block()
s = create_snake()
# Reaction on keypress
c.bind("<KeyPress>", s.change_direction)
main()
def create_snake():
# creating segments and snake
segments = [Segment(SEG_SIZE, SEG_SIZE),
Segment(SEG_SIZE*2, SEG_SIZE),
Segment(SEG_SIZE*3, SEG_SIZE)]
return Snake(segments)
# Setting up window cause fun yeah
root = Tk()
root.title("Python Snake Game By Amiel, Amitoj and Abdullah")
c = Canvas(root, width=WIDTH, height=HEIGHT, bg="#003344")
c.grid()
# catch keypressing
c.focus_set()
game_over_text = c.create_text(WIDTH/2, HEIGHT/2, text="GAME OVER!",
font='Calibi 30', fill='red',
state='hidden')
restart_text = c.create_text(WIDTH/2, HEIGHT-HEIGHT/3,
font='Arial 30',
fill='Black',
text=" Click here to restart" + '\n Made by Amiel & Amitoj & Abdullah',
state='hidden')
c.tag_bind(restart_text, "<Button-1>", clicked)
start_game()
root.mainloop()
【问题讨论】:
-
我在你的代码中看不到
global Tickspeed。 -
正如 Sujay 所说:如果你的代码中有一个全局变量的赋值,你需要先使用
global Tickspeed。
标签: python tkinter python-3.7