Skip to main content

A simple yet featureful framework for simplifying pygame game creation.

Project description

Contributors Forks Stargazers Issues MIT License


Pyrite

The Simple Game Framework
Explore the docs »

Report Bug · Request Feature

Table of Contents
  1. About The Project
  2. Getting Started
  3. Usage
  4. Roadmap
  5. License
  6. Contact
  7. Acknowledgments

About The Project

Pyrite is a framework for eliminating much of the boilerplate of setting up a pygame project and getting running, while encouraging good project architecture with proper seperation of responsibilities among game elements. It includes several built-in systems to get development up and going.

(back to top)

Getting Started

Pyrite is written in pure python, with no system dependencies, and should be OS-agnostic.

Installation

Pyrite can be installed from the PyPI using pip:

pip install pyrite-framework

and can be imported for use with:

import pyrite

Pyrite additionally is built for pygame-ce, which must also be installed.

(back to top)

Usage

At its core, Pyrite is built around a single main class: the Game class. Game is useable as-is in its default state, or it can be subclassed to allow for more specific behaviors.

Using Game

A game can be started in multiple ways.

  1. Traditional way
import pyrite

my_game = pyrite.Game()  # Creating with default settings
# ----------------------
#
# Game setup stuff here
#
# ----------------------
my_game.main()

This will create a window with a black background, at the default size (800x600), with a caption of "Game"

Keep in mind, anything after calling main() will be on hold until after the game stops running.

  1. Context Manager

Alternatively, we can use python's with syntax to create a game.

import pyrite

with pyrite.Game() as my_game:
    # ----------------------
    #
    # Game setup stuff here
    #
    # ----------------------

As with the above example, this will start a game with default settings. As a context manager, Game will start itself once the context ends.

Using context manager syntax offers a couple benefits.

  1. Avoids needing to manually call main().

    This is minor, but it's an additional step that needs to be minded otherwise.

  2. Indentation helps make it clear what code is being used to set up the game.

  3. Errors are captured.

    Any error that occurs during the set up will be captured by the context manager, and Game has a setting to suppress these errors.

(back to top)

Game Settings

Game has several data classes that hold information for it. You can construct the yourself and pass them to the game instance, or you can pass their parameters as keywords into the Game constructor.

# This:
display_settings = DisplaySettings((400, 300))
with Game(display_settings=display_settings) as my_game:
    ...

# Is the same as this
with Game(resolution=(400, 300)) as my_game:
    ...

(back to top)

Loop Phases

A game is built around a loop, and that loop has certain phases. The pyrite game loop offers these phases:

  1. Events: The pygame event queue is processed

  2. Const_update: Runs at a fixed rate, regardless of frame rate. Useful for time-invariant things, like physics.

  3. Pre_update: Runs earlier than the main update phase.

  4. Update: Main update phase. Most logic is run here.

  5. Post-update: Runs after the main update phase.

  6. Render: For drawing to the screen.

The basic Game class will call each of the phases after Events on all active Entities and Renderables, but also has these available as methods to allow for more specific behavior when subclassed.

(back to top)

Entities and Renderables

These are the core feature of Pyrite. All game objects should inherit from at least one of these. They allow you to define behaviors, and render out images onto the screen.

Entity

An entity is any object that has behavior. They can be typical objects, like an enemy, or obstacle, or they can be systems and services, like a physics service. To use, simply subclass Entity, and overwrite at least one of the four update-phase methods. Then, when the entity is created, it will automatically have those methods called each frame.

class MyEntity(Entity):

    def __init__(self, game_instance=None, enabled=True):
        super().__init__(game_instance, enabled)
        self.position: tuple[int, int] = (0, 0)


    def update(self, delta_time: float):
        keys = pygame.key.get_pressed()
        x = y = 0
        if keys[pygame.K_w]:
            y -= 1
        if keys[pygame.K_s]:
            y += 1
        if keys[pygame.K_a]:
            x -= 1
        if keys[pygame.K_d]:
            x += 1
        self.move((x, y))

    
    def move(self, direction: tuple[int, int]):
        self.position = (
            self.position[0] + direction[0], self.position[1] + direction[1]
        )

This will create a simple entity that will move with the WASD keys. Note, however, that it does not show anything on screen, as it is not renderable.

Renderables

Renderables are anything that needs to be drawn to the screen. They must implement the render method, which must return a ready-to-draw surface, and the get_rect method, which returns a pygame Rectangle, with the position and size of the renderable. Classes can inherit from both Entity and Renderable, to allow them to both be drawn and have behavior.

class MyRenderable(Renderable):

    # __init__ here

    def get_rect(self) -> pygame.Rect:
        return pygame.Rect(100, 50, 10, 10)

    def render(self, delta_time: float):
        surface = Surface((10, 10))
        surface.fill(Color("fuchsia"))
        return surface

This will draw a small fuchsia square at a world position of 100, 50.

UI Elements

There's a special layer in the the render system, the UI layer. Renderables in the UI layer are always drawn in screen space, not world space.

(back to top)

Forget About Screen Space

It's all about world space, now.

Pyrite features a camera system as part of its default renderer. Cameras are moveable and zoomable, and automatically ignore any renderables they can't see, speeding up your game when items are offscreen.

You can even have multiple cameras, rendered to different parts of the screen!

Renderables have layers and draw indexes to ensure that everything is drawn in the desired order. You can even add additional layers, and have cameras ignore layers, as needed.

Cameras are even optional. Pyrite will treat your world space just like screen space, if you don't want/need cameras for your project.

(back to top)

Roadmap

  • Add a world space conversion for clicking.
  • (Eternal) Improve the renderer. Faster rendering means more renderables!

See the open issues for a full list of proposed features (and known issues).

(back to top)

License

Distributed under the MIT License. See LICENSE.txt for more information.

(back to top)

Contact

Better Built Fool - betterbuiltfool@gmail.com

Bluesky - @betterbuiltfool.bsky.social

Project Link: https://github.com/BetterBuiltFool/pyrite_framework

(back to top)

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pyrite_framework-0.10.0.tar.gz (32.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pyrite_framework-0.10.0-py3-none-any.whl (29.4 kB view details)

Uploaded Python 3

File details

Details for the file pyrite_framework-0.10.0.tar.gz.

File metadata

  • Download URL: pyrite_framework-0.10.0.tar.gz
  • Upload date:
  • Size: 32.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/5.1.1 CPython/3.12.4

File hashes

Hashes for pyrite_framework-0.10.0.tar.gz
Algorithm Hash digest
SHA256 5f86be5f179aa1d90b97ad3961b44baffea6e8aff976a3fc349c4c15833654fa
MD5 296a8aa404e15706108ea273fde614e1
BLAKE2b-256 bd2925d82ba616bab74111e2a4d039e7b5e3940d9d5bfe00488adbcd27bf67f1

See more details on using hashes here.

File details

Details for the file pyrite_framework-0.10.0-py3-none-any.whl.

File metadata

File hashes

Hashes for pyrite_framework-0.10.0-py3-none-any.whl
Algorithm Hash digest
SHA256 83d90914354654e13be10632f9ebbd2b47959d6ee9ecba109902600099c5aeca
MD5 8d72b633ec7cfe94b9fd87c8ab7ac0ff
BLAKE2b-256 47f5572aed1476b49a6516fb6bf65567652e4cbb7f9e09f71e3fe0289a33c06d

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page