Tkinter 移动球程序创建 4 个球而不是 2 个
Tkinter moving balls program creating 4 balls instead of 2
我创建了一个程序,可以让球绕 canvas 移动并在 canvas 的边缘弹跳。这非常有效,所以我尝试添加另一个球,但不是创建 2 个球,而是创建 4 个球,其中 2 个球移动,另外两个保持静止。
这是代码:
#imports
from tkinter import *
import random
from random import randint
#Creating random x and y for the balls to move along
x = random.randint(1,10)
y = random.randint(1,10)
print(x, " Ball 1y")
print(y, " Ball 1x")
x0 = random.randint(1,10)
y0 = random.randint(1,10)
print(y0," Ball2y")
print(x0, " Ball2x")
class Ball:
#creates balls
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="red")
self.ball2 = canvas.create_oval(self.x1, self.y1, self.x2, self.y2, fill="red")
def move_ball(self, x, y):
#function to move ball
coords = canvas.coords(self.ball)
#Because coord is stored in a list I need to call which coord is bigger than the edge of the canvas
if coords[0] >= 280:
#multiplying by a negative number makes the ball "bounce"
x *= -1
if coords[0] <= 0:
x *= -1
if coords[3] <= 20:
y *= -1
if coords[3] >= 300:
y *= -1
print(coords, " Ball1")
#makes ball move
self.canvas.move(self.ball, x, y)
self.canvas.after(50, self.move_ball, x, y)
def move_ball2(self, x0, y0):
#same as previous different variables
coords2 = canvas.coords(self.ball2)
if coords2[0] >= 280:
x0 *= -1
if coords2[0] <= 0:
x0 *= -1
if coords2[3] <= 20:
y0 *= -1
if coords2[3] >= 300:
y0 *= -1
print(coords2, " Ball2")
self.canvas.move(self.ball2, x0, y0)
self.canvas.after(50, self.move_ball2, x0, y0)
#changes window titles etc.
root = Tk()
root.title("Balls")
root.resizable(False, False)
canvas = Canvas(root, width = 300, height = 300)
canvas.pack()
#creates ball with dimensions of the ball
ball1 = Ball(canvas, 10, 10, 30, 30)
ball2 = Ball(canvas, 60, 60, 80, 80)
#calls move ball function
ball1.move_ball(x, y)
ball2.move_ball2(x0,y0)
root.mainloop()
问题是除了添加第二个球之外,您还更改了 class Ball。面向对象编程的想法(即简单地说 classes in python)是创建一个 class,这里是 Ball,它定义了一个通用球的工作方式。您可以根据此 class 创建任意数量的对象(这里是 ball1、ball2 等)。
在您的代码中,您只需
删除行
self.ball2 = canvas.create_oval(self.x1, self.y1, self.x2, self.y2, fill="red")
删除完整的 move_ball2 函数
改变
ball2.move_ball2(x0,y0)
到
ball2.move_ball(x0,y0)
它将按预期工作。
您正在 __init()__
方法中初始化两个球。
self.ball = canvas.create_oval(self.x1, self.y1, self.x2, self.y2, fill="red")
self.ball2 = canvas.create_oval(self.x1, self.y1, self.x2, self.y2,fill="red")
创建对象时 class 两个球而不是一个。因此,更改 class 中的 init
方法应该可以修复它。您需要为两个不同的球创建两个不同的对象,而不是在 class 本身中创建两个不同的变量。
class Ball:
#creates balls
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="red")
此外,您有两种不同的方法来移动球 1 和 2。一种方法应该适用于两个球。
ball1 = Ball(canvas, 10, 10, 30, 30)
ball2 = Ball(canvas, 60, 60, 80, 80)
当执行这两个语句时,它们 return 对象的 class Ball 到变量 ball1 和 ball2。这些对象彼此独立, move_ball
方法将单独调用它们而不会相互影响。为两个不同的变量创建两个函数违背了创建 class.
的目的
您可能想阅读更多关于 classes 和来自 here and here. There are video tutorials 的 classes 和对象以及它们如何在 tkinter 上实现的对象。
我创建了一个程序,可以让球绕 canvas 移动并在 canvas 的边缘弹跳。这非常有效,所以我尝试添加另一个球,但不是创建 2 个球,而是创建 4 个球,其中 2 个球移动,另外两个保持静止。 这是代码:
#imports
from tkinter import *
import random
from random import randint
#Creating random x and y for the balls to move along
x = random.randint(1,10)
y = random.randint(1,10)
print(x, " Ball 1y")
print(y, " Ball 1x")
x0 = random.randint(1,10)
y0 = random.randint(1,10)
print(y0," Ball2y")
print(x0, " Ball2x")
class Ball:
#creates balls
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="red")
self.ball2 = canvas.create_oval(self.x1, self.y1, self.x2, self.y2, fill="red")
def move_ball(self, x, y):
#function to move ball
coords = canvas.coords(self.ball)
#Because coord is stored in a list I need to call which coord is bigger than the edge of the canvas
if coords[0] >= 280:
#multiplying by a negative number makes the ball "bounce"
x *= -1
if coords[0] <= 0:
x *= -1
if coords[3] <= 20:
y *= -1
if coords[3] >= 300:
y *= -1
print(coords, " Ball1")
#makes ball move
self.canvas.move(self.ball, x, y)
self.canvas.after(50, self.move_ball, x, y)
def move_ball2(self, x0, y0):
#same as previous different variables
coords2 = canvas.coords(self.ball2)
if coords2[0] >= 280:
x0 *= -1
if coords2[0] <= 0:
x0 *= -1
if coords2[3] <= 20:
y0 *= -1
if coords2[3] >= 300:
y0 *= -1
print(coords2, " Ball2")
self.canvas.move(self.ball2, x0, y0)
self.canvas.after(50, self.move_ball2, x0, y0)
#changes window titles etc.
root = Tk()
root.title("Balls")
root.resizable(False, False)
canvas = Canvas(root, width = 300, height = 300)
canvas.pack()
#creates ball with dimensions of the ball
ball1 = Ball(canvas, 10, 10, 30, 30)
ball2 = Ball(canvas, 60, 60, 80, 80)
#calls move ball function
ball1.move_ball(x, y)
ball2.move_ball2(x0,y0)
root.mainloop()
问题是除了添加第二个球之外,您还更改了 class Ball。面向对象编程的想法(即简单地说 classes in python)是创建一个 class,这里是 Ball,它定义了一个通用球的工作方式。您可以根据此 class 创建任意数量的对象(这里是 ball1、ball2 等)。
在您的代码中,您只需
删除行
self.ball2 = canvas.create_oval(self.x1, self.y1, self.x2, self.y2, fill="red")
删除完整的 move_ball2 函数
改变
ball2.move_ball2(x0,y0)
到
ball2.move_ball(x0,y0)
它将按预期工作。
您正在 __init()__
方法中初始化两个球。
self.ball = canvas.create_oval(self.x1, self.y1, self.x2, self.y2, fill="red")
self.ball2 = canvas.create_oval(self.x1, self.y1, self.x2, self.y2,fill="red")
创建对象时 class 两个球而不是一个。因此,更改 class 中的 init
方法应该可以修复它。您需要为两个不同的球创建两个不同的对象,而不是在 class 本身中创建两个不同的变量。
class Ball:
#creates balls
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="red")
此外,您有两种不同的方法来移动球 1 和 2。一种方法应该适用于两个球。
ball1 = Ball(canvas, 10, 10, 30, 30)
ball2 = Ball(canvas, 60, 60, 80, 80)
当执行这两个语句时,它们 return 对象的 class Ball 到变量 ball1 和 ball2。这些对象彼此独立, move_ball
方法将单独调用它们而不会相互影响。为两个不同的变量创建两个函数违背了创建 class.
您可能想阅读更多关于 classes 和来自 here and here. There are video tutorials 的 classes 和对象以及它们如何在 tkinter 上实现的对象。