Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Issue while creating a parallax background in pygame

I’m trying to create a parallax background effect in pygame i.e., each layer of the background will move at different speeds.

Here is the code I’ve written,

import pygame
pygame.init()
surface_width=576
surface_height=200
screen=pygame.display.set_mode((surface_width,surface_height))
clock=pygame.time.Clock()
dx=0
dy=0

bg=[]
for i in range(1,6):
    back=pygame.image.load(f'{i}.png').convert_alpha()
    bg.append(back)
width=bg[0].get_width()
height=surface_height-bg[0].get_height()


run=True
while run:
    clock.tick(60)
    for x in range(-3,3):
        speed=1
        for layer in bg:
            screen.blit(layer,((x*width)-dx*speed,height+dy*speed))
            speed+=0.8

    for event in pygame.event.get():
        if event.type==pygame.QUIT:
            run=False

    keys=pygame.key.get_pressed()
    if keys[pygame.K_LEFT] == True and dx>-3*width:
        dx-=2
    if keys[pygame.K_RIGHT] == True:
        dx+=2
    if keys[pygame.K_UP] == True and dy<surface_height:
        dy+=2
    elif keys[pygame.K_DOWN] == True and dy>0:
        dy-=2

    pygame.display.update()

This works fine, when the range is in positive values i.e., the x coordinates are positive. But when they are negative as in the above code, I start facing issues when trying to move left to the negative x coordinate.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

I suspected it to be an issue with the sequence of blitting and tweaked things a bit but I couldn’t get any successful results.

Another thing, I’ve observed is that I only face this issue when the layers are moving at different speeds. If I removed the speed+=0.8 part, the code works as intended (obviously without the parallax effect)

Moving to the left with the same layer speed

Moving to the left with different layer speed

>Solution :

Your problem is the nested loops. Iterate through the layers first and then through the tiles:

run=True
while run:
    clock.tick(60)
    
    for i, layer in enumerate(bg):
        speed = 1 + i * 0.8
        for x in range(-3,3):
            screen.blit(layer,((x*width)-dx*speed,height+dy*speed))

    # [...]

In addition, I suggest using the modulo operator (%) to calculate the beginning of the endless background and draw as many tiles as will fit on the screen:

run=True
while run:
    clock.tick(60)
    
    for i, layer in enumerate(bg):
        speed = 1 + i * 0.8
        x = ((-dx*speed) % width) - width
        while x < surface_width:
            screen.blit(layer, (x, height+dy*speed))
            x += width

    # [...]

See also How to make parallax scrolling work properly with a camera that stops at edges pygame

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading