Переместите шар в Tkinter Canvas Widget (простая игра арканоид) - PullRequest
2 голосов
/ 02 ноября 2011

Я пытаюсь написать простой арканоид с помощью 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()

Почему шар отражается не так?

screenshot of program

Ответы [ 2 ]

13 голосов
/ 03 ноября 2011

Для перемещения объекта необходимо использовать метод 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() только один раз,цикл начинается.Этот же метод можно использовать для обновления более одного объекта, или вы можете использовать разные методы для разных объектов.

edit: Вы полностью изменили свой вопрос с «Как мне двигатьсячто-то на холсте?на «почему он движется в неправильном направлении?».Ответ на последний вопрос прост: вы говорите ему двигаться в неправильном направлении.Используйте отладчик или некоторые операторы печати, чтобы увидеть, где и как вы рассчитываете delta_y.

0 голосов
/ 04 ноября 2011

вот простой взлом для этой проблемы:

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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...