在Tkinter画布控件中移动球(简单的打砖块游戏)
我正在尝试用Python和Tkinter写一个简单的打砖块游戏。我的目标是让球能够从顶部、右侧和左侧反弹。如果玩家没有接住球,导致球碰到底部,游戏就会结束。
这是我的代码:
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()
为什么球的反弹方向不对呢?
2 个回答
13
要移动一个物体,你需要使用 coords
方法或者 move
方法,这两个方法都可以改变物体的位置。你可以用 coords
方法来获取物体当前的位置。
如果你想做动画,可以使用 after
。你可以先调用一个函数,然后让这个函数在短时间后再次调用自己。你设置的时间间隔会影响动画的帧率(比如每10毫秒调用一次,大约就是每秒100帧)。
举个例子:
def moveit(self):
# move the object
<get the existing coordinates using the coords method>
<adjust the coordinates relative to the direction of travel>
<give the object new coordinates using the coords method>
# cause this movement to happen again in 10 milliseconds
self.after(10, self.moveit)
只要你调用一次 moveit()
,这个循环就会开始。这个方法可以用来更新多个物体,或者你也可以为不同的物体使用不同的方法。
补充: 你已经完全改变了问题,从“我怎么在画布上移动东西?”变成了“为什么它移动的方向不对?”。后者的答案很简单:你告诉它朝错误的方向移动。可以使用调试工具或者一些打印语句,看看你是怎么计算 delta_y
的。
-2
这里有一个简单的解决办法:
delta_x = delta_y = 3
while True:
objects = canv.find_overlapping(canv.coords(ball)[0], canv.coords(ball)[1], canv.coords(ball)[2], canv.coords(ball)[3])
for obj in objects:
if obj == 1:
delta_y = -delta_y
if obj == 2:
delta_x = -delta_x
if obj == 3:
delta_x = -delta_x
if obj == 4:
delta_y = -delta_y
new_x, new_y = delta_x, delta_y
canv.move(ball, new_x, new_y)
canv.update()
time.sleep(0.025)
root.bind('<Right>', move_right)
root.bind('<Left>', move_left)