Переместите шар в Tkinter Canvas Widget (простая игра арканоид)
Я пытаюсь написать простой арканоид с помощью 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 ответа
Вот простое решение этой проблемы:
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)
Для перемещения объекта вам необходимо использовать coords
метод или move
метод, который изменяет координаты объекта. Вы можете использовать coords
метод, чтобы получить текущие координаты.
Для анимации вы можете использовать after
, Вызовите функцию, затем используйте ее 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.