Skip to content

Instantly share code, notes, and snippets.

@cojoj
Created December 30, 2022 12:28
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cojoj/fc764e524fc8ed3ebd75e284631fddfe to your computer and use it in GitHub Desktop.
Save cojoj/fc764e524fc8ed3ebd75e284631fddfe to your computer and use it in GitHub Desktop.
Christmas Tree (with ornaments, star and gifts) written in Python Turtle
import random
import turtle
def initialize_screen():
screen = turtle.Screen()
screen.title = "Xmas Tree by Tomasz Kita"
screen.bgcolor("sky blue")
screen.colormode(255)
return screen
def get_user_inputs(s):
x = int(s.numinput("Xmas Tree", "Liczna poziomów choinki:", 3, minval=1, maxval=5))
y = int(s.numinput("Xmas Tree", "Liczna prezentów:", 3, minval=0, maxval=5))
z = int(s.numinput("Xmas Tree", "Liczna bombek na poziom:",
3, minval=0, maxval=5))
return (x, y, z)
def get_rand_color():
return tuple(random.randint(0, 255) for _ in range(3))
def draw_ball(x, y, size=10):
t = turtle.Turtle()
t.penup()
# Odejmujemy promień, żeby środek kółka był na krawędzi trójkąta
t.goto(x, y - size)
# Ustawiamy losowy kolor
t.color(*get_rand_color())
t.pendown()
t.begin_fill()
t.circle(size)
t.end_fill()
t.hideturtle()
def draw_balls(x, y, side_length, num_balls, radius):
for i in range(num_balls):
pos_x = x + (side_length * ((i + 1) / (num_balls + 1)))
draw_ball(pos_x, y, radius)
def draw_tree_level_with_balls(x, y, side_length, num_balls, ball_radius):
t = turtle.Turtle()
t.penup()
# Obliczamy lewy dolny narożnik trójkąta
starting_x = x - (side_length / 2)
t.goto(starting_x, y)
t.color('green')
t.pendown()
t.begin_fill()
top_y = None
for i in range(3):
# Jeżeli jesteśmy na 1 kroku, to rysujemy bombki
if i == 0:
draw_balls(
starting_x,
t.ycor(),
side_length,
num_balls,
ball_radius
)
t.forward(side_length)
t.left(120)
if i == 1:
top_y = t.ycor()
t.end_fill()
t.hideturtle()
# Zwracamy współrzędną y górnego wierzchołka trójkąta
return top_y
def calculate_tree_level_dimensions(total_height, num_levels, overlapping_factor):
level_height = total_height / (overlapping_factor * num_levels) - \
overlapping_factor + 1
return level_height, (2 * level_height) / (3 ** .5)
def draw_trunk(x, y, height):
# Szerokość pnia jest 75% wysokości
width = height * .75
t = turtle.Turtle()
t.penup()
t.goto(x - (width / 2), y)
t.color('brown')
t.pendown()
t.begin_fill()
for _ in range(2):
t.forward(width)
t.left(90)
t.forward(height)
t.left(90)
t.end_fill()
t.hideturtle()
# Zwracamy współrzędną y górnej krawędzi pnia
return t.ycor() + height
def draw_xmas_star(x, y, size):
t = turtle.Turtle()
t.penup()
t.goto(x, y)
t.color('yellow')
t.pendown()
t.begin_fill()
t.circle(size, extent=720, steps=5)
t.end_fill()
t.hideturtle()
def draw_tree(levels, balls, width, height, x=0, y=0):
trunk_height = height * .15 # Wysokość pnia to 15% wysokości canvasu
crown_height = height * .80 # Wysokość korony to 80% wysokości canvasu
levels_overlapping_factor = .5 # Nakładanie się poziomów wynosi 3/4
star_radius = height * .05 # Promień gwiazdy to 5% wysokości canvasu
ball_radius = star_radius # Promień bombki to promień gwiazdy
trunk_top_y = draw_trunk(x, y, trunk_height)
level_height, side = calculate_tree_level_dimensions(
crown_height,
levels,
levels_overlapping_factor
)
crown_y = trunk_top_y
star_y = None
for i in range(levels):
star_y = draw_tree_level_with_balls(
x,
crown_y,
side,
balls,
ball_radius
)
crown_y += level_height * levels_overlapping_factor
draw_xmas_star(x, star_y, star_radius)
def draw_gift(x, y, height):
colors = ['red', 'blue']
width = height * 1.25
t = turtle.Turtle()
t.penup()
t.goto(x, y)
t.color(random.choice(colors))
t.pendown()
t.begin_fill()
for _ in range(2):
t.forward(width)
t.left(90)
t.forward(height)
t.left(90)
t.end_fill()
t.hideturtle()
def main():
s = initialize_screen()
tree_levels, number_of_gifts, glass_balls_per_level = get_user_inputs(s)
width, height = s.screensize()
bottom_coordinate = -(height / 2)
draw_tree(
tree_levels,
glass_balls_per_level,
width,
height,
y=bottom_coordinate
)
canvas_start_x = -width / 2
canvas_end_x = width / 2
for _ in range(number_of_gifts):
x = random.randint(canvas_start_x, canvas_end_x)
draw_gift(x, bottom_coordinate, (height * .1))
s.exitonclick()
s.mainloop()
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment