Created
December 30, 2022 12:28
-
-
Save cojoj/fc764e524fc8ed3ebd75e284631fddfe to your computer and use it in GitHub Desktop.
Christmas Tree (with ornaments, star and gifts) written in Python Turtle
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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