How to make an ASCII spinning Donut in Python - Python PyGame tutorial

  Idea

This article will teach you how you can make a spinning donut with Python. It is a popular project in programming. The spinning donut is made in the languages such as C or C++. In this article, you'll learn how you can make the same with python.

 Prerequisites

Basic knowleddge of Python, knowledge of Classes and Functions in Python, how to install Python packages with pip, Knowledge about PyGame, math module and colorsys.

 Install Modules

  pip install pygame  

Type this command in your terminal: cmd, bash, etc.. and press enter (run).

  Code

Import modules

import pygame, colorsys, math

The logic

pygame.init()

white = (255, 255, 255)
black = (0, 0, 0)
hue = 0

WIDTH = 1920
HEIGHT = 1080

x_co, y_co = 0, 0

x_sep = 10
y_sep = 20

rows = HEIGHT // y_sep
columns = WIDTH // x_sep
screen_size = rows * columns

x_offset = columns / 2
y_offset = rows / 2

A, B = 0, 0  # rotating animation

theta_spacing = 10
phi_spacing = 1

big_chars = ".,-~:;=!*#$@"

screen = pygame.display.set_mode((WIDTH, HEIGHT))

display_surface = pygame.display.set_mode((WIDTH, HEIGHT))
# display_surface = pygame.display.set_mode((0, 0), pygame.FULLSCREEN)
pygame.display.set_caption('Donut')
font = pygame.font.SysFont('Arial', 18, bold=True)

def hsv2rgb(h, s, v):
    return tuple(round(i * 255) for i in colorsys.hsv_to_rgb(h, s, v))


def text_display(letter, x_co, y_co):
    text = font.render(str(letter), True, hsv2rgb(hue, 1, 1))
    display_surface.blit(text, (x_co, y_co))

# def text_display(letter, x_co, y_co):
#     text = font.render(str(letter), True, white)
#     display_surface.blit(text, (x_co, y_co))


run = True
while run:

    screen.fill((black))

    z = [0] * screen_size  # Donut. Fills donut space
    b = [' '] * screen_size  # Background. Fills empty space

    for j in range(0, 628, theta_spacing):  # from 0 to 2pi
        for i in range(0, 628, phi_spacing):  # from 0 to 2pi
            c = math.sin(i)
            d = math.cos(j)
            e = math.sin(A)
            f = math.sin(j)
            g = math.cos(A)
            h = d + 2
            D = 1 / (c * h * e + f * g + 5)
            l = math.cos(i)
            m = math.cos(B)
            n = math.sin(B)
            t = c * h * g - f * e
            x = int(x_offset + 40 * D * (l * h * m - t * n))  # 3D x coordinate after rotation
            y = int(y_offset + 20 * D * (l * h * n + t * m))  # 3D y coordinate after rotation
            o = int(x + columns * y)  
            N = int(8 * ((f * e - c * d * g) * m - c * d * e - f * g - l * d * n))  # luminance index
            if rows > y and y > 0 and x > 0 and columns > x and D > z[o]:
                z[o] = D
                b[o] = big_chars[N if N > 0 else 0]

    if y_co == rows * y_sep - y_sep:
        y_co = 0

    for i in range(len(b)):
        A += 0.00002 # for faster rotation change to bigger value
        B += 0.00001 # for faster rotation change to bigger value
        if i == 0 or i % columns:
            text_display(b[i], x_co, y_co)
            x_co += x_sep
        else:
            y_co += y_sep
            x_co = 0
            text_display(b[i], x_co, y_co)
            x_co += x_sep


    pygame.display.update()

    hue += 0.005

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_ESCAPE:
                running = False

 Output

Now your game is ready. Just run the program and see the magic...



 Summary

In this article you learnt about making an app to display a rotating Donut in Python with PyGame module. You learnt about PyGame module.

Thanks for reading. Hope you liked the idea and project. Do comment down you opinions. Also, share this project with your friends and programmers.


Comments