如何使物体从画布边框反弹?

时间:2018-08-10 20:51:22

标签: python python-3.x tkinter collision tkinter-canvas

我正在使用tkinter中的canvas小部件创建一个椭圆,并使其在画布中四处移动。

但是,当椭圆与边界接触时,它会粘在墙上而不是弹起。

我正在努力调试代码,在此先感谢您!

from tkinter import *
from time import *
import numpy as np
root = Tk()
root.wm_title("Bouncing Ball")
canvas = Canvas(root, width=400, height=400, bg="black")
canvas.grid()
size=10
x = 50
y = 50
myBall = canvas.create_oval(x-size, y-size, x+size, y+size, fill = "red")
while True:
    root.update()
    root.after(50)
    dx = 5
    dy = 0
#separating x and y cooridnates from tuple of canvas.coords
    x = canvas.coords(myBall)[0]+10
    y = canvas.coords(myBall)[1]+10
    coordinates = np.array([x, y], dtype = int)
#Checking boundaries
    if coordinates[0]-size <= 0:
        dx = -1*dx
    if coordinates[0]+size >= 400:
        dx = -1*dx
    if coordinates[1]-size <= 0:
        dy = -1*dy
    if coordinates[1]+size >= 400:
        dy = -1*dy
    print(coordinates) #Used to see what coordinates are doing
    canvas.move(myBall, dx, dy) #Move ball by dx and dy

2 个答案:

答案 0 :(得分:0)

这只是基础数学。当您从x坐标减去一些量时,球将向左移动。如果它碰到左墙,并且您希望它向右反弹,则需要停止从x减去并开始加到x。 y坐标也是如此。

答案 1 :(得分:0)

这是组织弹跳球程序并使您开始使用GUI编程的简单方法:

  • 虽然循环无法与GUI主循环配合使用;也不必调用updatemainloop会处理它。

  • 重复的操作是root.after的最佳处理方式。

  • 我在函数bounce中提取了跳动逻辑,该函数使用root.after进行自我调用。您会看到我简化了逻辑。

  • 我还参数化了画布的大小。

  • 初始速度成分dxdy是从可能的值列表中随机选择的,因此游戏不会太无聊。

这是它的外观:

import tkinter as tk   # <-- avoid star imports
import numpy as np
import random

WIDTH = 400
HEIGHT = 400
initial_speeds = [-6, -5, -4, 4, 5, 6]
dx, dy = 0, 0
while dx == dy:
    dx, dy = random.choice(initial_speeds), random.choice(initial_speeds) 

def bounce():
    global dx, dy
    x0, y0, x1, y1 = canvas.coords(my_ball)
    if x0 <= 0 or x1 >= WIDTH:    # compare to left of ball bounding box on the left wall, and to the right on the right wall
        dx = -dx
    if y0 <= 0 or y1 >= HEIGHT:   # same for top and bottom walls
        dy = -dy
    canvas.move(my_ball, dx, dy)
    root.after(50, bounce)

if __name__ == '__main__':

    root = tk.Tk()
    root.wm_title("Bouncing Ball")
    canvas = tk.Canvas(root, width=400, height=400, bg="black")
    canvas.pack(expand=True, fill=tk.BOTH)

    size=10
    x = 50
    y = 50
    my_ball = canvas.create_oval(x-size, y-size, x+size, y+size, fill="red")

    bounce()
    root.mainloop()