Speaking of the movie “The Matrix”, I believe that most of you have seen or heard of the movie, there is a scene in the movie number rain, if you have seen the movie, should be impressed by this classic scene, in this article we use Python to achieve this effect in the form of numbers, letters, and pictures.

1. Digital

First, let’s implement digital rain, we need to create a window to display content, window creation using PyGame library, code implementation is as follows:

FONT_PX = 15
pygame.init()
winSur = pygame.display.set_mode((500.600))
font = pygame.font.SysFont('fangsong'.20)
bg_suface = pygame.Surface((500.600), flags=pygame.SRCALPHA)
pygame.Surface.convert(bg_suface)
bg_suface.fill(pygame.Color(0.0.0.13))
winSur.fill((0.0.0))
# Numbers
texts = [font.render(str(i), True, (0.255.0)) for i in range(10)]
colums = int(500 / FONT_PX)
drops = [0 for i in range(colums)]
while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            exit()
    pygame.time.delay(33)
    winSur.blit(bg_suface, (0.0))
    for i in range(len(drops)):
        text = random.choice(texts)
        winSur.blit(text, (i * FONT_PX, drops[i] * FONT_PX))
        drops[i] += 1
        if drops[i] * 10 > 600 or random.random() > 0.95:
            drops[i] = 0
    pygame.display.flip()
Copy the code

The implementation effect is as follows:

2. The letter

Then, we will realize the letter rain, the basic way is to realize the above digital rain number into letters, the code is as follows:

PANEL_width = 400
PANEL_highly = 500
FONT_PX = 15
pygame.init()
Create a window
winSur = pygame.display.set_mode((PANEL_width, PANEL_highly))
font = pygame.font.SysFont('123.ttf'.22)
bg_suface = pygame.Surface((PANEL_width, PANEL_highly), flags=pygame.SRCALPHA)
pygame.Surface.convert(bg_suface)
bg_suface.fill(pygame.Color(0.0.0.28))
winSur.fill((0.0.0))
letter = ['q'.'w'.'e'.'r'.'t'.'y'.'u'.'i'.'o'.'p'.'a'.'s'.'d'.'f'.'g'.'h'.'j'.'k'.'l'.'z'.'x'.'c'.'v'.'b'.'n'.'m']
texts = [
    font.render(str(letter[i]), True, (0.255.0)) for i in range(26)]You can put several columns of coordinates on the artboard and generate a list
column = int(PANEL_width / FONT_PX)
drops = [0 for i in range(column)]
while True:
    Get the event from the queue
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            exit()
        elif event.type == pygame.KEYDOWN:
            chang = pygame.key.get_pressed()
            if (chang[32]):
                exit()
    # pause the given number of milliseconds
    pygame.time.delay(30)
    # Re-edit the image
    winSur.blit(bg_suface, (0.0))
    for i in range(len(drops)):
        text = random.choice(texts)
        # Reedit the image of each coordinate point
        winSur.blit(text, (i * FONT_PX, drops[i] * FONT_PX))
        drops[i] += 1
        if drops[i] * 10 > PANEL_highly or random.random() > 0.95:
            drops[i] = 0
    pygame.display.flip()
Copy the code

The implementation effect is as follows:

Picture 3.

Finally, we use the image to achieve this effect, the image let’s use the raindrop, here we use tkinter to create the window, the code implementation is as follows:

# ordinate of initial raindrop
INIT_HEIGHT = 10
# raindrop create
def rainmake(canvas, imagefile) :
    rainlist = []
    for i in range(5) :# Create a row of raindrops based on the picture
        rainlist.append(canvas.create_image(100 + 80 * i, INIT_HEIGHT, anchor=NE, image=imagefile))
    return rainlist

# Raindrops fall
def raindown(tk, canvas, imagefile, sec) :
    # wait between threads
    time.sleep(sec)
    rainlist = rainmake(canvas, imagefile)
    # The ordinate value of each drop
    height = [INIT_HEIGHT] * 10
    while True:
        # Wait a little before each move
        time.sleep(0.2)
        # 5 raindrops moving together
        for i in range(5) :# If the raindrop word reaches the bottom, do not continue to move
            if not height[i] == 0:
                Set the fall pace
                rnd = random.randint(5.50)
                canvas.move(rainlist[i], 0, rnd)
                height[i] = height[i] + rnd
                tk.update()
        for i,h in enumerate(height):
            if h > 400:
                Delete the raindrop word when it reaches the bottom
                canvas.delete(rainlist[i])
                tk.update()
                # Empty the height of the raindrop
                height[i] = 0
                print(i,h,height)
        # all to the end, then out of the loop
        if height == [0] * 5:
            print('break:',threading.current_thread().name)
            break

def lookloop(tk, canvas, thread) :
    aliveflg = False
    while True:
        # 5s test once
        time.sleep(5)
        for th in thread:
            if th.is_alive():
                aliveflg = True
            else:
                aliveflg = False
        if aliveflg == False:
            break
    canvas.create_text(100 , 200, text='The rain has stopped... ', fill='red')
    canvas.pack()
    time.sleep(5)
    tk.destroy()
Copy the code

The implementation effect is as follows:

The source code is available in Python 200513.