Mueve una bola dentro de Tkinter Canvas Widget (juego simple Arkanoid)

Estoy tratando de escribir un Arkanoid simple con la ayuda de Python y Tkinter. El objective es hacer que la bola se refleje desde los lados superior, derecho e izquierdo. Y si el jugador pierde el balón para que toque el lado inferior, el juego se detendría.

Aquí está el código:

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('', move_right) root.bind('', move_left) root.geometry('%sx%s+%s+%s' %(640, 480, 100, 100)) root.resizable(0, 0) root.mainloop() 

¿Por qué la pelota se refleja de manera incorrecta?

captura de pantalla del programa

Para mover un objeto, debe utilizar el método de coords o el método de move , que cambia las coordenadas del objeto. Puede utilizar el método de coords para obtener las coordenadas actuales.

Para hacer la animación se puede utilizar after . Llame a una función, luego pídale que la use after de llamarse a sí misma por un corto tiempo en el futuro. Hasta qué punto en el futuro determinará su velocidad de cuadros (es decir, cada 10 ms significa aproximadamente 100 cuadros por segundo)

Por ejemplo:

 def moveit(self): # move the object    # cause this movement to happen again in 10 milliseconds self.after(10, self.moveit) 

Una vez que llama a moveit() solo una vez, el ciclo comienza. Ese mismo método puede usarse para actualizar más de un objeto, o puede tener diferentes métodos para diferentes objetos.

edición: has cambiado completamente tu pregunta de “¿cómo muevo algo en un canvas?” a “¿por qué se mueve en la dirección equivocada?”. La respuesta a este último es simple: le estás diciendo que se mueva en la dirección equivocada. Use un depurador o algunas declaraciones impresas para ver dónde y cómo está calculando delta_y.

Aquí hay un simple truco para este problema:

 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('', move_right) root.bind('', move_left)