pythonscrollpygameweather

How would I create side scrolling text in PyGame?


I am currently working on a weather application using the PyGame framework and it needs to have side scrolling text at the bottom, but I wouldn't know how to do it. I have looked for tutorials online and I have found things similar but not quite what I would like.

This is my code around the end, where all of the text is initalized.

desc_text = desc.render(description, True, (255, 255, 255))
desc_rect = desc_text.get_rect()
desc_rect.center = (238, 740)

screen = pygame.display.set_mode((960, 720), pygame.FULLSCREEN, vsync=1)

while running:
    try:
        for event in pygame.event.get():
            if event.type == KEYDOWN:
                if event.key == K_ESCAPE:
                    running = False
            elif event.type == QUIT:
                running = False
        screen.fill((0, 0, 125))
        screen.blit(header_text, header_rect)
        screen.blit(temperature_text, temperature_rect)
        screen.blit(wind_text, wind_rect)
        screen.blit(desc_text, desc_rect)
        pygame.display.update()
    except KeyboardInterrupt:
        print("Quitting...")
        running = False

This is the text.

I want it to be like a marquee, scrolling left to right endlessly.


Solution

  • I don't understand what is the problem.

    The simplest version which moves to left and when all text leave screen on left side then it shows it again on right need

    and you should start with this - and later try to create more complex version which repeat text at once after when there is space text.

    import pygame
    
    # --- constants ---  # PEP8: `UPPER_CASE_NAMES`; directly after import
    
    FPS = 30
    
    # --- main ---
    
    pygame.init()
    screen = pygame.display.set_mode((960, 720))#, pygame.FULLSCREEN, vsync=1)
    screen_rect = screen.get_rect()
    
    font = pygame.font.SysFont(None, 50)
    
    description = " How would I create side scrolling text in PyGame? "
    
    desc_text = font.render(description, True, (255, 255, 255))
    desc_rect = desc_text.get_rect(left=screen_rect.right)
    
    clock = pygame.time.Clock()
    running = True
    while running:
        try:
            for event in pygame.event.get():
                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_ESCAPE:
                        running = False
                elif event.type == pygame.QUIT:
                    running = False
                    
            # --- updates (without draws) ---
            
            desc_rect.x -= 5
            if desc_rect.right <= 0:            # if leave on left side
                desc_rect.x = screen_rect.right # then move to right side
                
            # --- draws (without updates) ---
            
            screen.fill((0, 0, 125))
    
            screen.blit(desc_text, desc_rect)
            
            pygame.display.update()
            
            clock.tick(FPS)   # slowdown to 30 FPS
        except KeyboardInterrupt:
            print("Quitting...")
            running = False
    
    pygame.quit()
    

    To make more complex version you have to repeate the same text 2 or 3 times - so it needs to create 2 or 3 rect with offsets. First starts at rect.x second starts at rect.x + rect.width and third starts at rect.x + rect.width + rect.width. And for all of then you have to repeat (almost) the same code as in previous version. If you put all rect on list then it can be simpler.

    Difference is: when it leave on left side then move to right by rect.width * 3

    import pygame
    
    # --- constants ---  # PEP8: `UPPER_CASE_NAMES`; directly after import
    
    FPS = 30
    
    # --- main ---
    
    pygame.init()
    screen = pygame.display.set_mode((960, 720))#, pygame.FULLSCREEN, vsync=1)
    screen_rect = screen.get_rect()
    
    font = pygame.font.SysFont(None, 50)
    
    description = " How would I create side scrolling text in PyGame? "
    
    desc_text = font.render(description, True, (255, 255, 255))
    
    # because text is short so I need 3 copies (with different offsets)
    desc_rects = []
    
    for i in range(3):
        rect = desc_text.get_rect(left=screen_rect.right)
        rect.x += rect.width * i  # add offset
        desc_rects.append(rect)
    
    clock = pygame.time.Clock()
    running = True
    while running:
        try:
            for event in pygame.event.get():
                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_ESCAPE:
                        running = False
                elif event.type == pygame.QUIT:
                    running = False
                    
            # --- updates (without draws) ---
            
            for rect in desc_rects:
                rect.x -= 5
                if rect.right <= 0:
                    rect.x += rect.width * 3
                
            # --- draws (without updates) ---
            
            screen.fill((0, 0, 125))
    
            for rect in desc_rects:
                screen.blit(desc_text, rect)
            
            pygame.display.update()
    
            clock.tick(FPS)   # slowdown to 30 FPS        
        except KeyboardInterrupt:
            print("Quitting...")
            running = False
    
    pygame.quit()