tkinter python - 我可以创建 window 碰撞吗?

tkinter python - Can I create window collision?

编程新手。在一个简单的乒乓球克隆上工作。启动球,但要确保 window (500x500) 的所有边都会让球弹开。我怎么能这样做?谢谢!

P.S。如果需要,这是我当前的代码。

import threading
import random
import time
import string
import os.path
from random import randint
from tkinter import *

class Pong:
    Title = 'Pong'
    Size = '500x500'

class Ball:
    def __init__(self,canvas,x1,y1,x2,y2):
        self.x1 =x1
        self.y1 = y1
        self.x2 = x2
        self.y2 = y2
        self.canvas = canvas
        self.ball = canvas.create_oval(self.x1, self.y1, self.x2, self.y2, fill="black")
    def move_ball(self):
        deltax = randint(0,5)
        deltay = randint(0,5)
        self.canvas.move(self.ball,deltax,deltay)
        self.canvas.after(50,self.move_ball)

def PongGame():
    print("Moved to PongGame.")
    ball1 = Ball(canvas,10,10,30,30)
    ball1.move_ball()

def titleButtonClicked(event):
    print("Title screen button clicked.")
    btn.pack_forget()
    btn.place(x=600,y=600)
    msg.pack_forget()
    PongGame()

root = Tk()
root.geometry(Pong.Size)
root.title(Pong.Title)
root.resizable(False,False)
msg = Label(root, text = Pong.Title, font = ("", 50))
msg.pack()
canvas = Canvas(root, width = 500, height = 500)
canvas.pack()
btn=Button(root, text = "Start")
btn.bind('<Button-1>', titleButtonClicked)
btn.place(x=220,y=300)


root.mainloop()

碰撞不是微不足道的;最简单的是在检查球的边界框的哪条边与 canvas.

的边界相交后反转 xy 速度

也许是这样的:

import random
import tkinter as tk


WIDTH, HEIGHT = 500, 500


class Ball:
    radius = 10
    spawn_center = (250, 100)

    def __init__(self, canvas):
        self.canvas = canvas
        self.id = None
        self.create_ball()
        self.velocity = None
        self.assign_random_velocity()
        self.keep_moving = True
        self.move()

    def create_ball(self):
        xc, yc = self.spawn_center
        x0, y0, = xc - self.radius, yc + self.radius
        x1, y1, = xc + self.radius, yc - self.radius
        self.id = self.canvas.create_oval(x0, y0, x1, y1)

    def assign_random_velocity(self):
        dx = random.randrange(1, 5) * random.choice((1, -1))
        dy = random.randrange(1, 5) * random.choice((1, -1))
        self.velocity = (dx, dy)

    def move(self):
        if self.keep_moving is None:
            return
        self.check_collision()
        self.canvas.move(self.id, *self.velocity)
        self.keep_moving = self.canvas.after(10, self.move)

    def cancel_move(self):
        if self.keep_moving is not None:
            self.canvas.after_cancel(self.keep_moving)
        self.keep_moving = None

    def check_collision(self):
        x0, y0, x1, y1 = self.canvas.coords(self.id)
        dx, dy = self.velocity
        if x0 < 0:
            x0 = 0
            dx = -dx
        elif x1 > WIDTH:
            x1 = WIDTH
            dx = -dx
        if y0 < 0:
            y0 = 0
            dy = -dy
        elif y1 > HEIGHT:
            y1 = HEIGHT
            dy = -dy   
        self.velocity = dx, dy


class PongBoard(tk.Canvas):

    def __init__(self, master):
        self.master = master
        super().__init__(self.master)
        self.ball = None
        self.spawn_new_ball()

    def spawn_new_ball(self):
        if self.ball is not None:
            self.ball.cancel_move()
            self.delete(self.ball.id)
        self.ball = Ball(self)


root = Tk()
root.geometry(f'{WIDTH}x{HEIGHT+20}')
board = PongBoard(root)
new_ball_btn = tk.Button(root, text='spawn new ball', command=board.spawn_new_ball)
board.pack(expand=True, fill=tk.BOTH)
new_ball_btn.pack()

root.mainloop()

这会让你入门,但你必须实现球拍、球拍移动、球与球拍的碰撞检查,并自己保持得分。