• Stars
    star
    163
  • Rank 231,141 (Top 5 %)
  • Language
    Python
  • License
    GNU Lesser Genera...
  • Created over 10 years ago
  • Updated about 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

make scrolling games with animated maps in pygame

pyscroll

For Python 3.7+ and pygame 2.0+

A simple and fast module for animated scrolling maps for your new or existing game.

If you find this useful, please consider making a donation to help support it https://liberapay.com/ltheden/donate

Discord! https://discord.gg/2taTP4aYR6

Introduction

pyscroll is a generic module for making a fast scrolling image with pygame. It uses a lot of magic to get great framerates out of pygame. It only exists to draw a map. It doesn't load images or data, so you can use your own custom data structures, tile storage, ect.

pyscroll is compatible with pytmx (https://github.com/bitcraft/pytmx), so you can use your Tiled maps. It also has out-of-the-box support for pygame sprites.

Features

  • Reload the map tiles and data without closing the game
  • Sprites or plain surfaces can be drawn in layers
  • Animated tiles
  • Zoom in and out
  • Includes optional drop-in replacement for pygame LayeredGroup
  • Pixel alpha and colorkey tilesets are supported
  • Drawing and scrolling shapes
  • Fast and small footprint
  • Speed is not affected by map size
  • Support for pytmx loaded maps from Tiled Map Editor

Use It Like a Camera

In order to further simplify using scrolling maps, pyscroll includes a pygame sprite group that will render all sprites on the map and will correctly draw them over or under tiles. Sprites can use their rect in world coordinates, and the group will work like a camera, translating world coordinates to screen coordinates while rendering sprites and map layers.

It's also useful to make minimaps or create simple chunky graphics.

Installation

Install from pip

pip install pyscroll

You can also manually install it from source

python setup.py install

New Game Tutorial

This is a quick guide on building a new game with pyscroll and pygame. It uses the PyscrollGroup for efficient rendering. You are free to use any other pygame techniques and functions.

Open apps/tutorial/quest.py for a gentle introduction to pyscroll and the PyscrollGroup for pygame. There are plenty of comments to get you started.

The Quest demo shows how you can use a pyscroll group for drawing, how to load maps with pytmx, and how pyscroll can quickly render layers. Moving under some tiles will cause the Hero to be covered.

The repo wiki has more in-depth explanations of the tutorial code, including one way to implement sprite animation. Be sure to check it out. Anyone is welcome to make additions or improvements.

https://github.com/bitcraft/pyscroll/wiki

Example Use with pytmx

pyscroll and pytmx can load your maps from Tiled and use your pygame sprites. The following is a very basic way to load a map onto the screen.

from pytmx.util_pygame import load_pygame
import pygame
import pyscroll


class Sprite(pygame.sprite.Sprite):
    """
    Simple Sprite class for on-screen things
    
    """
    def __init__(self, surface):
        self.image = surface
        self.rect = surface.get_rect()


# Load TMX data
tmx_data = load_pygame("desert.tmx")

# Make the scrolling layer
map_layer = pyscroll.BufferedRenderer(
    map_data=pyscroll.TiledMapData(tmx_data),
    screen_size=(400,400),
)

# make the pygame SpriteGroup with a scrolling map
group = pyscroll.PyscrollGroup(map_layer=map_layer)

# Add sprite(s) to the group
surface = pygame.image.load("my_surface.png").convert_alpha()
sprite = Sprite(surface)
group.add(sprite)

# Center the camera on the sprite
group.center(sprite.rect.center)

# Draw map and sprites using the group
# Notice I did not `screen.fill` here!  Clearing the screen is not
# needed since the map will clear it when drawn
group.draw(screen)

Adapting Existing Games / Map Data

pyscroll can be used with existing map data, but you will have to create a class to interact with pyscroll or adapt your data handler. Try to make it follow the same API as the TiledMapData adapter and you should be fine.

Give pyscroll surface to layer into the map

pyscroll can use a list of surfaces and render them on the map, taking account their layer position.

map_layer = pyscroll.BufferedRenderer(map_data, map_size)

# just an example for clarity.  here's a made up game engine:

def game_engine_draw():
   surfaces = list()
   for game_object in my_game_engine:

      # pyscroll uses normal pygame surfaces.
      surface = game_object.get_surface()

      # pyscroll will draw surfaces in screen coordinates, so translate them
      # you need to use a rect to handle tiles that cover surfaces.
      rect = game_object.get_screen_rect()

      # the list called 'surfaces' is required for pyscroll
      # notice the layer.  this determines which layers the sprite will cover.
      # layer numbers higher than this will cover the surface
      surfaces.append((surface, rect, game_object.layer))

   # tell pyscroll to draw to the screen, and use the surfaces supplied
   map_layer.draw(screen, screen.get_rect(), surfaces)

FAQ

Why are tiles repeating while scrolling?

Pyscroll by default will not handle maps that are not completely filled with tiles. This is in consideration of drawing speed. To clarify, you can have several layers, some layers without tiles, and that is fine; the problem is when there are empty spaces in all the layers, leaving gaps in the entire map. There are two ways to fix this issue with the 1st solution being the best performance wise:

1. In Tiled (or your data), fill in the empty spots with a tile

For best performance, you must have a tile in each part of the map. You can create a simple background layer, and fill with single color tiles where there are gaps. Pyscroll is very fast even with several layers, so there is virtually no penalty.

2. Pass "alpha=True" to the BufferedRenderer constructor.

All internal buffers will now support 'per-pixel alpha' and the areas without tiles will be fully transparent. You may still have graphical oddities depending on if you clear the screen or not, so you may have to experiment here. Since per-pixel alpha buffers are used, overall performance will be reduced by about 33%

Why are there obvious/ugly 'streaks' when scrolling?

Streaks are caused by missing tiles. See the above answer for solutions.

Can I blit anything 'under' the scrolling map layer?

Yes! There are two ways to handle this situation...both are experimental, but should work. These options will cause the renderer to do more housekeeping, actively clearing empty spaces in the buffer, so overall performance will be reduced.

1. Pass "alpha=True" to the constructor.

When drawing the screen, first blit what you want to be under the map (like a background, or parallax layer), then draw the pyscroll renderer or group. Since per-pixel alpha buffers are used, overall performance will be reduced.

2. Set a colorkey.

Pass "colorkey=theColorYouWant" to the BufferedRenderer constructor. In theory, you can now blit the map layer over other surfaces with transparency, but beware that it will produce some nasty side effects:

  1. Overall, performance will be reduced, as empty ares are being filled.
  2. If mixing 'per-pixel alpha' tilesets, tile edges may show the colorkey.

Does the map layer support transparency?

Yes...and no. By default, pyscroll handles all transparency types very well for the tiles and you should not have issues with that. However, if you are trying to blit/draw the map over existing graphics and "see through" transparent areas under the map, then you will have to use the "alpha", or "colorkey" methods described above.

Does pyscroll support parallax layers?

Not directly. However, you can build you own parallax effects by passing "alpha=True" to the BufferedRenderer constructor and using one renderer for each layer. Then it is just a matter of scrolling at different speeds.

More Repositories

1

pytmx

Python library to read Tiled Map Editor's TMX maps.
Python
360
star
2

mugen-tools

various tools i've made for using mugen
Python
24
star
3

tailor

Cross platform photo booth project.
Python
19
star
4

pygoap

Simple AI for python games. In very early stages of development. Uses concepts of Goal Orientated Action Planing (GOAP).
Python
17
star
5

animation

animation helper for pygame projects (and more!)
Python
17
star
6

mh

adventure game + library for pygame
Python
13
star
7

pyglet

Python
12
star
8

PURIKURA

'purukura' is a term used in Japan for their ubiquitous style of photo booth. This project is a DIY photo booth for weddings.
Python
10
star
9

retrogamelib

Automatically exported from code.google.com/p/retrogamelib
Python
7
star
10

mode7

simple 'mode7' like effects in pygame
Python
7
star
11

storymaker

ai framework to build narrative stories. WIP
Python
6
star
12

world_gen

Python
5
star
13

matrix

Python
5
star
14

360-connect

Python script to configure linux firewall to route xbox live traffic through a ssh tunnel
Python
4
star
15

opendaisy

Arduino project for daisywheel typewriters
C++
4
star
16

fighter-framework

Python
3
star
17

kindle-signage

Using an old Kindle Touch as digital signage
Python
2
star
18

polerunner

2d side scroller with advanced input handling, ai, and physics
Python
2
star
19

lpc1

entry for liberated pixel cup
Python
2
star
20

pyweek19

Python
2
star
21

shutter

modern libgphoto2 binding for python
Python
2
star
22

eXoDOS

my personal notes and code related to eXoDOS
Python
2
star
23

minebot

botbotbotbot
Python
2
star
24

simplefsm

Small FSM for python
Python
2
star
25

mcproxy

minecraft proxy
Python
2
star
26

dcdrop

Utility to transfer Sega Dreamcast VMU saves to computer
Python
1
star
27

pyweek14

Sidescrolling retro platform game with pygame. Try to disarm the bomb before time runs out and stay alive!
Python
1
star
28

yarpgml

Yet Another RPG Markup Language
Python
1
star
29

pyweek25

A Patchwork Orange
Python
1
star