08 August 2009 ~ 5 Comments

PyGame – Parallax Scrolling in 2D games

Hi fellow reader, to start this article let me define what Parallax Scrolling is :

Parallax scrolling is a special scrolling technique in computer graphics, seen first in the 1982 arcade game Moon Patrol. In this pseudo-3D technique, background images move by the “camera” slower than foreground images, creating an illusion of depth in a 2D video game and adding to the immersion. The technique grew out of the multiplane camera technique used in traditional animation since the 1940s

I will reuse and adapt the AnimatedSprite Class from my previous article PyGame and Animated Sprites – Take 2 and create a new Class named Parallax that inherits from AnimatedSprite.

class AnimatedSprite(pygame.sprite.Sprite):
    def __init__(self, images, fps = 10):
      pygame.sprite.Sprite.__init__(self)

      # Animation
      self._start       = pygame.time.get_ticks()
      self._delay       = 1000 / fps
      self._last_update = 0
      self._frame       = 0
      self._images      = images

      self.image        = self._images[self._frame]

      # Movement
      self.location     = (0,0)
      self.destination  = (0,0)
      self.heading      = None
      self.speed        = 0.

    def process(self, t):
      if self.speed > 0. and self.location != self.destination:
          destination              = self.destination - self.location
          distance                 = destination.get_length()
          self.heading             = destination.get_normalized()
          most_accurate_distance   = min(distance, t * self.speed)
          self.location           += most_accurate_distance * self.heading

    def update(self, t):
      if t - self._last_update > self._delay:
        self._frame += 1
        if self._frame >= len(self._images):
          self._frame = 0

        self.image = self._images[self._frame]
        self._last_update = t

    def render(self, screen):
      screen.blit(self.image, self.location)

To handle movements of our parallax layers, we need to add some members to the base class. A movement is defined by the following variables :

Location, that will be continuously updated when in movement. Destination, in our case it will always be the same. Heading to face the right direction, in our case the direction will never change, finally the movement’s Speed in pixel by second.

To update all these values we need a process method that will update each element to it’s new location according to it’s speed.

For an analogy I’d say that a parallax is an image loop. To implement this loop we will override the default render method in a Parallax Class.

class Parallax(AnimatedSprite):
    def __init__(self, images, fps = 30):
        AnimatedSprite.__init__(self, images, fps)

    # Overridding the default render method
    def render(self, screen):
      w,h = self.image.get_size()
      x,y = self.location
      W,H = RESOLUTION

      # Reseting original image location
      if abs(x) == w:
          self.location = Vector2(0, y)
          x = 0

      # Blitting the image loop
      if x - w < W:
        location = Vector2(x+w, y)
        screen.blit(self.image, location)

      screen.blit(self.image, self.location)

Here is a quick schema to illustrate what is happening int the Parallax.render method :

Precisely when image A’s right edge enters screen’s clipping, blit another A image named A prime at location A.x + A.width.

Image Loop

Image Loop

When A’s right edge is outside the screen clipping, reset it’s location to initial position. A prime will automatically follow it.

Resetting the Loop

Resetting the Loop

We are done. A image will repeat itself continuously.

Now to implement a parallax, you need at least two layers. So you’ll add layers with an increased speed setting following this simple rule :

The closer an element is from the point of view, the faster it moves.

I bundled a Pygame application for you to download. My implementation is far from being perfect and I’d be interested in knowing about how you do it.

Pygame Parallax Scrolling Demo
Pygame Parallax Scrolling Demo

Dependencies:

Demo Preview:

Spread the word:
  • del.icio.us
  • Reddit
  • StumbleUpon
  • Technorati
  • Twitter
  • DZone
  • Facebook
  • FriendFeed
  • HackerNews

4 Tweets

5 Responses to “PyGame – Parallax Scrolling in 2D games”


Additional comments powered by BackType