Tkinter moving balls program creating 4 balls instead of 2

强颜欢笑 提交于 2020-01-07 04:22:22

问题


I have created a program that made a ball move around a canvas and bounce of the edge of the canvas. This worked very well so I tried to add another ball but instead of creating 2 balls it created 4, 2 of the balls move and the other two stay still. This is the code:

#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()

回答1:


The problem is that you changed the class Ball in addition to adding a second ball. The idea of object oriented programming (i.e. in simple words classes in python) is to create a class, here Ball, that defines how ONE generic ball works. You can from this class create as many objects (here ball1, ball2, etc.) as you want.

In your code you just have to

  1. remove the line

    self.ball2 = canvas.create_oval(self.x1, self.y1, self.x2, self.y2, fill="red")

  2. remove the complete move_ball2 function

  3. Change

ball2.move_ball2(x0,y0)

to

ball2.move_ball(x0,y0)

and it will work as expected.




回答2:


You are initializing two balls in your __init()__ method.

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")

When the object is created for the class two balls instead of one. So changing the init method in the class should fix it. You need to create two different objects for two different balls, rather than two different variables in the class itself.

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")

Also, you have two different methods for moving balls 1 and 2. One method should work for both balls.

ball1 = Ball(canvas, 10, 10, 30, 30)
ball2 = Ball(canvas, 60, 60, 80, 80)

When the two statements are executed they return objects of the class Ball to the variables ball1 and ball2. These objects are independent of each other and the move_ball method would be called on them individually without affecting each other. Creating two functions for two different variables defeats the purpose of creating a class.

You might want to read a little more on classes and objects from here and here. There are video tutorials on classes and objects and how they're implemented on tkinter.



来源:https://stackoverflow.com/questions/44499813/tkinter-moving-balls-program-creating-4-balls-instead-of-2

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!