|
| 1 | +from tkinter import * # Import tkinter |
| 2 | +from random import randint |
| 3 | + |
| 4 | +# Return a random color string in the form #RRGGBB |
| 5 | +def getRandomColor(): |
| 6 | + color = "#" |
| 7 | + for j in range(6): |
| 8 | + color += toHexChar(randint(0, 15)) # Add a random digit |
| 9 | + return color |
| 10 | + |
| 11 | +# Convert an integer to a single hex digit in a character |
| 12 | +def toHexChar(hexValue): |
| 13 | + if 0 <= hexValue <= 9: |
| 14 | + return chr(hexValue + ord('0')) |
| 15 | + else: # 10 <= hexValue <= 15 |
| 16 | + return chr(hexValue - 10 + ord('A')) |
| 17 | + |
| 18 | +# Define a Ball class |
| 19 | +class Ball: |
| 20 | + def __init__(self): |
| 21 | + self.x = 0 # Starting center position |
| 22 | + self.y = 0 |
| 23 | + self.dx = 2 # Move right by default |
| 24 | + self.dy = 2 # Move down by default |
| 25 | + self.radius = 3 # The radius is fixed |
| 26 | + self.color = getRandomColor() # Get random color |
| 27 | + |
| 28 | +class BounceBalls: |
| 29 | + def __init__(self): |
| 30 | + self.ballList = [] # Create a list for balls |
| 31 | + |
| 32 | + window = Tk() # Create a window |
| 33 | + window.title("Bouncing Balls") # Set a title |
| 34 | + |
| 35 | + self.width = 350 # Width of the self.canvas |
| 36 | + self.height = 150 # Width of the self.canvas |
| 37 | + self.canvas = Canvas(window, bg = "white", |
| 38 | + width = self.width, height = self.height) |
| 39 | + self.canvas.pack() |
| 40 | + |
| 41 | + frame = Frame(window) |
| 42 | + frame.pack() |
| 43 | + btStop = Button(frame, text = "Stop", command = self.stop) |
| 44 | + btStop.pack(side = LEFT) |
| 45 | + btResume = Button(frame, text = "Resume", |
| 46 | + command = self.resume) |
| 47 | + btResume.pack(side = LEFT) |
| 48 | + btAdd = Button(frame, text = "+", command = self.add) |
| 49 | + btAdd.pack(side = LEFT) |
| 50 | + btRemove = Button(frame, text = "-", command = self.remove) |
| 51 | + btRemove.pack(side = LEFT) |
| 52 | + |
| 53 | + self.sleepTime = 100 # Set a sleep time |
| 54 | + self.isStopped = False |
| 55 | + self.animate() |
| 56 | + |
| 57 | + window.mainloop() # Create an event loop |
| 58 | + |
| 59 | + def stop(self): # Stop animation |
| 60 | + self.isStopped = True |
| 61 | + |
| 62 | + def resume(self): # Resume animation |
| 63 | + self.isStopped = False |
| 64 | + self.animate() |
| 65 | + |
| 66 | + def add(self): # Add a new ball |
| 67 | + self.ballList.append(Ball()) |
| 68 | + |
| 69 | + def remove(self): # Remove the last ball |
| 70 | + self.ballList.pop() |
| 71 | + |
| 72 | + def animate(self): # Move the message |
| 73 | + while not self.isStopped: |
| 74 | + self.canvas.after(self.sleepTime) # Sleep |
| 75 | + self.canvas.update() # Update self.canvas |
| 76 | + self.canvas.delete("ball") |
| 77 | + |
| 78 | + for ball in self.ballList: |
| 79 | + self.redisplayBall(ball) |
| 80 | + |
| 81 | + def redisplayBall(self, ball): |
| 82 | + if ball.x > self.width or ball.x < 0: |
| 83 | + ball.dx = -ball.dx |
| 84 | + |
| 85 | + if ball.y > self.height or ball.y < 0: |
| 86 | + ball.dy = -ball.dy |
| 87 | + |
| 88 | + ball.x += ball.dx |
| 89 | + ball.y += ball.dy |
| 90 | + self.canvas.create_oval(ball.x - ball.radius, |
| 91 | + ball.y - ball.radius, ball.x + ball.radius, |
| 92 | + ball.y + ball.radius, fill = ball.color, tags = "ball") |
| 93 | + |
| 94 | +BounceBalls() # Create GUI |
0 commit comments