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.
的边界相交后反转 x
或 y
速度
也许是这样的:
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()
这会让你入门,但你必须实现球拍、球拍移动、球与球拍的碰撞检查,并自己保持得分。
编程新手。在一个简单的乒乓球克隆上工作。启动球,但要确保 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.
的边界相交后反转x
或 y
速度
也许是这样的:
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()
这会让你入门,但你必须实现球拍、球拍移动、球与球拍的碰撞检查,并自己保持得分。