首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Bubble Blaster Python代码的麻烦?

Bubble Blaster Python代码的麻烦?
EN

Stack Overflow用户
提问于 2016-08-11 13:31:16
回答 2查看 2.9K关注 0票数 0

我正在做一个项目,并且已经完成了代码,但是仍然出现了一个错误,尽管我确信我的代码是正确的。

以下是不断出现的错误:

代码语言:javascript
复制
Traceback (most recent call last):
  File "C:\Python33\bubblee blaster.py", line 61, in <module>
    clean_up_bubs()
NameError: name 'clean_up_bubs' is not defined

下面是我的python代码:

代码语言:javascript
复制
from tkinter import *
HEIGHT = 500
WIDTH = 800
window = Tk()
window.title('bubble blaster')
c = Canvas(window, width=WIDTH, height=HEIGHT, bg='darkblue')
c.pack()
ship_id = c.create_polygon(5, 5, 5, 25, 30, 15, fill='red')
ship_id2 = c.create_oval(0, 0, 30, 30, outline='red')
SHIP_R = 15
MID_X = WIDTH / 2
MID_Y = HEIGHT / 2
c.move(ship_id, MID_X, MID_Y)
c.move(ship_id2, MID_X, MID_Y)
SHIP_SPD = 10
def move_ship(event):
    if event.keysym == 'Up':
        c.move(ship_id, 0, -SHIP_SPD)
        c.move(ship_id2, 0, -SHIP_SPD)
    elif event. keysym == 'Down':
        c.move(ship_id, 0, SHIP_SPD)
        c.move(ship_id2, 0, SHIP_SPD)
    elif event.keysym == 'Left':
        c.move(ship_id, -SHIP_SPD, 0)
        c.move(ship_id2, -SHIP_SPD, 0)
    elif event.keysym == 'Right':
        c.move(ship_id, SHIP_SPD, 0)
        c.move(ship_id2, SHIP_SPD, 0)
c.bind_all('<Key>' , move_ship)
from random import randint
bub_id = list()
bub_r = list()
bub_speed = list()
MIN_BUB_R = 10
MAX_BUB_R = 30
MAX_BUB_SPD = 110
GAP = 100
def create_bubble():
    x = WIDTH + GAP
    y = randint(0, HEIGHT)
    r = randint(MIN_BUB_R, MAX_BUB_R)
    id1 = c.create_oval(x - r, y - r, x +  r, y + r, outline='white')
    bub_id.append(id1)
    bub_r.append(r)
    bub_speed.append(randint(1, MAX_BUB_SPD))
def move_bubbles():
    for i in range(len(bub_id)):
        c.move(bub_id[i], -bub_speed[i], 0)
from time import sleep, time
BUB_CHANCE = 10
TIME_LIMIT = 30
BONUS_SCORE = 1000
score = 0
bonus = 0
end = time() + TIME_LIMIT
#MAIN GAME LOOP
while time() < end:
    if randint(1, BUB_CHANCE) == 1:
        create_bubble()
        move_bubbles()
        clean_up_bubs()
        score += collision()
        if (int(score / BONUS_SCORE)) > bonus:
            bonus += 1
            end += TIME_LIMIT
            show_score(score)
            show_time(int(end - time()))
        print(score)
        window.update()
        sleep(0.01)
def get_coords(id_num):
    pos = c.coords(id_num)
    x = (pos[0] + pos[2])/2
    y = (pos[1] + pos[3])/2
    return x, y
def del_bubble(i):
    del bub_r[i]
    del bub_speed[i]
    c.delete(bub_id[i])
    del bub_id[i]
def clean_up_bubs():
   for i in range(len(bub_id)-1, -1, -1):
       x, y = get_coords(bub_id[i])
       if x < -GAP:
          del_bubble(i)
from math import sqrt
def distance(id1, id2):
    x1, y1 = get_coords(id1)
    x2, y2 = get_coords(id2)
    return sqrt((x2 - x1)**2 + (y2 - y1)**2)
def collision():
    points = 0
    for bub in range(len(bub_id)-1, -1, -1):
        if distance(ship_id2, bub_id[bub]) < (SHIP_R + bub_r[bub]):
            points += (bub_r[bub] + bub_speed[bub])
            del_bubble(bub)
    return points
c.create_text(50, 30, text='TIME' , fill='white' )
c.create_text(150, 30, text='SCORE' , fill='white' )
time_text = c.create_text(50, 50, fill='white' )
score_text = c.create_text(150, 50, fill='white' )
def show_score(score):
    c.itemconfig(score_text, text=str(score))
def show_time(time_left):
    c.itemconfig(time_text, text=str(time_left))
c.create_text(MID_X, MID_Y, \
     text='GAME OVER', fill='white', font=('Helvetica' ,30))
c.create_text(MID_X, MID_Y + 30, \
              text='Score: '+ str(score), fill='white')
c.create_text(MID_X, MID_Y + 45, \
              text='Bonus time: '+ str(bonus*TIME_LIMIT), fill='white')
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-08-11 14:04:59

那代码简直是不可读的乱七八糟!

您应该将所有的导入放在脚本的顶部。

接下来,定义您的全局常量(以及全局变量,但是如果您可以重新组织代码以最小化全局变量的使用,情况会更好)。

接下来,定义您的函数。

然后将调用这些函数的代码放在末尾。

这样做的原因是,您需要在使用它们之前定义它们。Python自上而下地扫描脚本,通过执行定义来创建各种对象(包括函数)。函数定义可以引用尚未定义的全局事物(包括其他函数)。但是,当您实际调用函数时,它所引用的必须已经定义好了。

此外,在函数周围放置(至少)一个空行,以便更容易地查看它们的开始和结束位置。并在其他地方使用空行,使程序的结构更加明显。

我试图实现这些更改,并运行生成的代码,但我不确定它是否能实现您想要的功能。

代码语言:javascript
复制
from tkinter import *
from random import randint
from time import sleep, time
from math import sqrt

HEIGHT = 500
WIDTH = 800

SHIP_R = 15
MID_X = WIDTH / 2
MID_Y = HEIGHT / 2

SHIP_SPD = 10

bub_id = list()
bub_r = list()
bub_speed = list()
MIN_BUB_R = 10
MAX_BUB_R = 30
MAX_BUB_SPD = 110
GAP = 100

BUB_CHANCE = 10
TIME_LIMIT = 30
BONUS_SCORE = 1000

score = 0
bonus = 0
end = time() + TIME_LIMIT

def move_ship(event):
    if event.keysym == 'Up':
        c.move(ship_id, 0, -SHIP_SPD)
        c.move(ship_id2, 0, -SHIP_SPD)
    elif event.keysym == 'Down':
        c.move(ship_id, 0, SHIP_SPD)
        c.move(ship_id2, 0, SHIP_SPD)
    elif event.keysym == 'Left':
        c.move(ship_id, -SHIP_SPD, 0)
        c.move(ship_id2, -SHIP_SPD, 0)
    elif event.keysym == 'Right':
        c.move(ship_id, SHIP_SPD, 0)
        c.move(ship_id2, SHIP_SPD, 0)

def create_bubble():
    x = WIDTH + GAP
    y = randint(0, HEIGHT)
    r = randint(MIN_BUB_R, MAX_BUB_R)
    id1 = c.create_oval(x - r, y - r, x +  r, y + r, outline='white')
    bub_id.append(id1)
    bub_r.append(r)
    bub_speed.append(randint(1, MAX_BUB_SPD))

def move_bubbles():
    for i in range(len(bub_id)):
        c.move(bub_id[i], -bub_speed[i], 0)

def get_coords(id_num):
    pos = c.coords(id_num)
    x = (pos[0] + pos[2])/2
    y = (pos[1] + pos[3])/2
    return x, y

def del_bubble(i):
    del bub_r[i]
    del bub_speed[i]
    c.delete(bub_id[i])
    del bub_id[i]

def clean_up_bubs():
   for i in range(len(bub_id)-1, -1, -1):
       x, y = get_coords(bub_id[i])
       if x < -GAP:
          del_bubble(i)

def distance(id1, id2):
    x1, y1 = get_coords(id1)
    x2, y2 = get_coords(id2)
    return sqrt((x2 - x1)**2 + (y2 - y1)**2)

def collision():
    points = 0
    for bub in range(len(bub_id)-1, -1, -1):
        if distance(ship_id2, bub_id[bub]) < (SHIP_R + bub_r[bub]):
            points += (bub_r[bub] + bub_speed[bub])
            del_bubble(bub)
    return points

def show_score(score):
    c.itemconfig(score_text, text=str(score))

def show_time(time_left):
    c.itemconfig(time_text, text=str(time_left))

window = Tk()
window.title('bubble blaster')
c = Canvas(window, width=WIDTH, height=HEIGHT, bg='darkblue')
c.pack()
ship_id = c.create_polygon(5, 5, 5, 25, 30, 15, fill='red')
ship_id2 = c.create_oval(0, 0, 30, 30, outline='red')

c.bind_all('<Key>' , move_ship)

c.move(ship_id, MID_X, MID_Y)
c.move(ship_id2, MID_X, MID_Y)

c.create_text(50, 30, text='TIME' , fill='white' )
c.create_text(150, 30, text='SCORE' , fill='white' )
time_text = c.create_text(50, 50, fill='white' )
score_text = c.create_text(150, 50, fill='white' )

#MAIN GAME LOOP
while time() < end:
    if randint(1, BUB_CHANCE) == 1:
        create_bubble()
        move_bubbles()
        clean_up_bubs()
        score += collision()
        if (int(score / BONUS_SCORE)) > bonus:
            bonus += 1
            end += TIME_LIMIT
            show_score(score)
            show_time(int(end - time()))
        #print(score)
        window.update()
        sleep(0.01)

c.create_text(MID_X, MID_Y, \
     text='GAME OVER', fill='white', font=('Helvetica' ,30))
c.create_text(MID_X, MID_Y + 30, \
              text='Score: '+ str(score), fill='white')
c.create_text(MID_X, MID_Y + 45, \
              text='Bonus time: '+ str(bonus*TIME_LIMIT), fill='white')

FWIW,在使用window.updatesleep的循环中,使用Tkinter并不常见。使用window.mainloop和事件驱动编程更正常。

票数 1
EN

Stack Overflow用户

发布于 2016-08-11 13:37:03

现在,clean_up_bubs在第61行以下。你必须在它被调用之前就拥有它。您将注意到move_bubblescreate_bubbles在while循环之前,对于clean_up_bubs也必须如此。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38897822

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档