Переместите шар в 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.

Другие вопросы по тегам