【发布时间】:2011-12-20 13:02:28
【问题描述】:
我正在尝试在 Python 和 Tkinter 的帮助下编写一个简单的 Arkanoid。目标是使球从顶部、右侧和左侧反射。如果球员错过了球,所以球触到了底边,比赛就会停止。
代码如下:
from Tkinter import *
import time
root = Tk()
canv = Canvas(root, highlightthickness=0)
canv.pack(fill='both', expand=True)
top = canv.create_line(0, 0, 640, 0, fill='green', tags=('top'))
left = canv.create_line(0, 0, 0, 480, fill='green', tags=('left'))
right = canv.create_line(639, 0, 639, 480, fill='green', tags=('right'))
bottom = canv.create_line(0, 478, 640, 478, fill='red', tags=('bottom'))
rect = canv.create_rectangle(270, 468, 365, 478, outline='black', fill='gray40', tags=('rect'))
ball = canv.create_oval(0, 20, 20, 40, outline='black', fill='gray40', tags=('ball'))
delta_x = delta_y = 3
new_x, new_y = delta_x, -delta_y
while True:
time.sleep(0.025)
if canv.find_overlapping(canv.coords(ball)[0], canv.coords(ball)[1], canv.coords(ball)[2], canv.coords(ball)[3])[0] == 1:
new_x, new_y = delta_x, -delta_y
canv.move(ball, new_x, new_y)
print 'fitst if', new_x, new_y
if canv.find_overlapping(canv.coords(ball)[0], canv.coords(ball)[1], canv.coords(ball)[2], canv.coords(ball)[3])[0] == 2:
new_x, new_y = delta_x, delta_y
canv.move(ball, new_x, new_y)
print '2nd if', new_x, new_y
if canv.find_overlapping(canv.coords(ball)[0], canv.coords(ball)[1], canv.coords(ball)[2], canv.coords(ball)[3])[0] == 3:
new_x, new_y = -delta_x, delta_y
canv.move(ball, new_x, new_y)
if canv.find_overlapping(canv.coords(ball)[0], canv.coords(ball)[1], canv.coords(ball)[2], canv.coords(ball)[3])[0] == 4:
new_x, new_y = delta_x, -delta_y
canv.move(ball, new_x, new_y)
print new_x, new_y
canv.move(ball, new_y, new_y)
canv.update()
def move_right(event):
canv.move(rect, 7, 0)
pass
def move_left(event):
canv.move(rect, -7, 0)
pass
root.bind('<Right>', move_right)
root.bind('<Left>', move_left)
root.geometry('%sx%s+%s+%s' %(640, 480, 100, 100))
root.resizable(0, 0)
root.mainloop()
为什么球会以错误的方式反射?
【问题讨论】:
-
“反射”不意味着运动吗?您需要先移动球,根据速度定期更新其位置。让球移动后,当它的边界框与矩形相交时,根据相交发生在哪一侧,反转速度的符号(例如 x 速度从 +5 到 -5)。另外,如果这是家庭作业,请添加“家庭作业”标签。
-
你真的应该避免使用
while True和time.sleep。这些都不适用于事件循环。使用我向您展示的代码,使用after更新屏幕。 -
您的代码没有运行。完全没有。它有缩进错误,并且它引用了从未在任何地方设置过的“self”。
-
@BryanOakley,我刚刚更正了代码。它现在应该可以工作了。