Skip to content

Instantly share code, notes, and snippets.

@stephengruppetta
Created May 27, 2023 20:56
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save stephengruppetta/6abc25029de2ea919ee4ae480754a2e3 to your computer and use it in GitHub Desktop.
Save stephengruppetta/6abc25029de2ea919ee4ae480754a2e3 to your computer and use it in GitHub Desktop.
import collections
import random
import time
import turtle
spawn_interval = 0.1
ball_speed = 4
increase_rotation_step = 0.25
colour_change_interval = 4
frame_rate = 20
time_per_frame = 1 / frame_rate
# Set up window
window = turtle.Screen()
window.bgcolor(0.2, 0.2, 0.2)
window.tracer(0)
window.bounce_on = False
window.title("Bouncing off edges: OFF")
spinner = turtle.Turtle()
spinner.color("white")
spinner.rotation_speed = 2
# Spawn new balls
colour = random.random(), random.random(), random.random()
balls = []
pool_of_balls = []
def spawn_ball(reference):
if pool_of_balls:
balls.append(pool_of_balls.pop())
balls[-1].showturtle()
else:
balls.append(turtle.Turtle())
balls[-1].shape("circle")
balls[-1].color(colour)
balls[-1].turtlesize(0.5)
balls[-1].penup()
balls[-1].setposition(reference.position())
balls[-1].setheading(reference.heading())
# Change speed of rotation
def increase_anticlockwise_rotation():
spinner.rotation_speed += increase_rotation_step
def decrease_anticlockwise_rotation():
spinner.rotation_speed -= increase_rotation_step
def toggle_bouncing():
window.bounce_on = not window.bounce_on
window.title(
f"Bouncing off edges: {'ON' if window.bounce_on else 'OFF'}"
)
window.onkeypress(increase_anticlockwise_rotation, "Left")
window.onkeypress(decrease_anticlockwise_rotation, "Right")
window.onkeypress(toggle_bouncing, "space")
window.listen()
# Main animation loop
spawn_timer = time.time()
ball_colour_timer = time.time()
last_100_frames = collections.deque(maxlen=100)
while True:
frame_start_time = time.time()
spinner.left(spinner.rotation_speed)
# Spawn new ball
if time.time() - spawn_timer > spawn_interval:
spawn_ball(spinner)
spawn_timer = time.time()
# Change ball colour
if time.time() - ball_colour_timer > colour_change_interval:
colour = random.random(), random.random(), random.random()
ball_colour_timer = time.time()
# Move all balls and clear balls that leave the screen
for ball in balls.copy():
ball.forward(ball_speed)
# Check if ball has hit a screen edge
if window.bounce_on:
# Check if ball has hit left or right wall
if abs(ball.xcor()) > window.window_width() / 2:
angle = 180 - ball.heading()
ball.setheading(angle)
# Check if ball has hit top or bottom wall
elif abs(ball.ycor()) > window.window_height() / 2:
angle = 360 - ball.heading()
ball.setheading(angle)
else: # bouncing is turned off
if (
abs(ball.xcor()) > window.window_width() / 2
or abs(ball.ycor()) > window.window_height() / 2
):
ball.hideturtle()
balls.remove(ball)
pool_of_balls.append(ball)
window.update()
frame_time = time.time() - frame_start_time
if frame_time < time_per_frame:
time.sleep(time_per_frame - frame_time)
last_100_frames.append(time.time() - frame_start_time)
print(sum(last_100_frames) / len(last_100_frames))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment