Pygame Essentials
Project description
title: 'Guide: How to use PyGess'
Introduction
This document will walk you through the implementation of the PyGess library.
PyGess is a physics engine designed to manage game objects, their interactions, and their updates within a game world. It provides classes and functions to handle entities, game objects, and worlds, along with utility functions to manage these components.
We will cover:
- The
GameObjectsclass and its methods. - The
Worldclass and its methods. - The
entityandMovingEntityclasses. - Utility functions for managing worlds and entities.
- A test script to demonstrate usage.
GameObjects class
The GameObjects class is responsible for storing and updating a list of entities. It acts like a sprite group but is tailored for entities.
Initialization
The constructor initializes the list of entities.
class GameObjects:
'''
# Description
A class which stores list of Entities. Also updates them.
Basically a sprite group for entities instead.
# Functions
## Init
```
def __init__(self, entities:list) -> None:
self.entities = entities
```
Initializes entity list.
Update method
The update method ensures all entities in the list are unique and calls their update method.
## update
```
def update(self):
from . import entity as ent
self.entities = list(set(self.entities))
for entity in self.entities:
if isinstance(entity, (ent.Entity)):
entity.update()
```
Updates all entities in list.
'''
def __init__(self, entities:list) -> None:
self.entities = entities
def update(self):
from . import entity as ent
self.entities = list(set(self.entities))
for entity in self.entities:
if isinstance(entity, (ent.Entity)):
entity.update()
def append(self, *entity):
for e in entity:
if e != None:
self.entities = list(self.entities)
self.entities.append(e)
Append method
The append method adds new entities to the list.
## update
```
def update(self):
from . import entity as ent
self.entities = list(set(self.entities))
for entity in self.entities:
if isinstance(entity, (ent.Entity)):
entity.update()
```
Updates all entities in list.
'''
def __init__(self, entities:list) -> None:
self.entities = entities
def update(self):
from . import entity as ent
self.entities = list(set(self.entities))
for entity in self.entities:
if isinstance(entity, (ent.Entity)):
entity.update()
def append(self, *entity):
for e in entity:
if e != None:
self.entities = list(self.entities)
self.entities.append(e)
World class
The World class manages the game world, including gravity, time, and game objects.
Initialization
The constructor initializes the world with gravity, game objects, and other necessary attributes.
class World:
def __init__(self, grav: tuple, *game_objects) -> None:
self.gravity = pyg.math.Vector2(grav)
self.dt = 0
self.prev_time = time.time()
self.is_active = False
self.__counter = 0
self.__counter2 = 0
self.__objects = GameObjects(game_objects)
self.runtime_obj = copy.deepcopy(self.__objects)
self.__base_state = self.runtime_obj
worlds.append(self)
def update(self):
if not self.is_active:
self.__counter2 = 0
return
if self.__counter2 == 0:
self.__reset()
if self.__counter == 0:
self.__set_runtime()
Update method
The update method handles the world's update logic, including resetting and setting runtime states.
self.runtime_obj.update()
self.__counter += 1
self.__counter2 += 1
def add_gameobj(self, *gameobj):
for obj in gameobj:
self.__objects.append(obj)
def load_new_object(self, *gameobj):
for obj in gameobj:
self.runtime_obj.append(obj)
def update_delta_time(self):
Add and load game objects
The add_gameobj and load_new_object methods add game objects to the world and runtime objects, respectively.
self.runtime_obj.update()
self.__counter += 1
self.__counter2 += 1
def add_gameobj(self, *gameobj):
for obj in gameobj:
self.__objects.append(obj)
def load_new_object(self, *gameobj):
for obj in gameobj:
self.runtime_obj.append(obj)
def update_delta_time(self):
Update delta time
The update_delta_time method updates the delta time for the world.
if self.is_active:
self.dt = min(time.time() - self.prev_time, 0.1)
self.prev_time = time.time()
return
self.dt = get_active_world().dt
self.dt = min(self.dt, 0.1)
def __set_runtime(self):
ent = []
for e in self.__objects.entities:
if e.rect not in data.all_rects:
data.all_rects.append(e.rect)
en = copy.deepcopy(e)
en.id = uuid.uuid4()
en.parent = e
ent.append(copy.deepcopy(en))
self.runtime_obj = GameObjects(ent)
self.__base_state = GameObjects(copy.deepcopy(ent))
def __reset(self):
ent = []
for e in self.__base_state.entities:
if e.rect not in data.all_rects:
data.all_rects.append(e.rect)
ent.append(copy.deepcopy(e))
self.runtime_obj = GameObjects(ent)
Set runtime and reset methods
The __set_runtime and __reset methods manage the runtime state of the world.
if self.is_active:
self.dt = min(time.time() - self.prev_time, 0.1)
self.prev_time = time.time()
return
self.dt = get_active_world().dt
self.dt = min(self.dt, 0.1)
def __set_runtime(self):
ent = []
for e in self.__objects.entities:
if e.rect not in data.all_rects:
data.all_rects.append(e.rect)
en = copy.deepcopy(e)
en.id = uuid.uuid4()
en.parent = e
ent.append(copy.deepcopy(en))
self.runtime_obj = GameObjects(ent)
self.__base_state = GameObjects(copy.deepcopy(ent))
def __reset(self):
ent = []
for e in self.__base_state.entities:
if e.rect not in data.all_rects:
data.all_rects.append(e.rect)
ent.append(copy.deepcopy(e))
self.runtime_obj = GameObjects(ent)
Deactivate method
The _deactivate method deactivates the world.
def _deactivate(self):
self.is_active = False
Utility functions
Get active world
The get_active_world function returns the currently active world.
def get_active_world() -> World:
for world in worlds:
if world.is_active:
return world
Debug no active worlds
The _debug_no_active_worlds function counts the number of active worlds.
def _debug_no_active_worlds():
counter = 0
for world in worlds:
if world.is_active:
counter += 1
return counter
Set active world
The set_active_world function sets a given world as active and deactivates the current active world if any.
def set_active_world(world:World):
if _debug_no_active_worlds() > 0:
get_active_world()._deactivate()
world.is_active = True
Get all worlds
The get_all_worlds function returns all worlds.
def get_all_worlds():
return worlds
Update delta time for all worlds
The update_delta_time function updates the delta time for all worlds.
def update_delta_time():
for w in get_all_worlds():
w.update_delta_time()
Update all worlds
The update_worlds function updates all worlds.
def update_worlds():
for w in get_all_worlds():
w.update()
Prefab instance functions
The first_instance_of_prefab_in_world and all_instances_of_prefab_in_world functions find instances of a prefab entity in a world.
def first_instance_of_prefab_in_world(world, prefab_entity) -> 'entity.Entity':
for e in world.runtime_obj.entities:
if e.parent.id == prefab_entity.id:
return e
def all_instances_of_prefab_in_world(world, prefab_entity) -> list:
instances = []
for e in world.runtime_obj.entities:
if e.parent.id == prefab_entity.id:
instances.append(e)
return instances
Entity class
The entity class represents a game entity with position, dimensions, and optional color or image.
Initialization
The constructor initializes the entity with position, dimensions, and optional color or image.
class Entity(pyg.sprite.DirtySprite):
def __init__(self, position: tuple, dimensions: tuple, color=None, image_path=None) -> None:
pyg.sprite.DirtySprite.__init__(self)
self.pos = pyg.math.Vector2(position)
self.dimensions = dimensions
self.color = color
self.parent = None
self.id = uuid.uuid4()
Update method
The update method updates the entity's position, checks for collisions, and updates its sprite group.
def get_all_obj_colliding_with(self):
return self._colliding_objects
def update(self):
self.active_world = physics.get_active_world()
self.update_rect()
self.check_collisions()
if self in self.spr_group:
self.spr_group.remove(self)
self.spr_group.update()
self.spr_group.add(self)
else:
self.spr_group.update()
self.spr_group.draw(pyg.display.get_surface())
Collision methods
The update_rect, check_collisions, is_colliding_with, and get_all_obj_colliding_with methods handle collision detection and response.
self._colliding_objects = []
data.all_rects.append(self.rect)
def update_rect(self):
index = data.all_rects.index(self.rect)
data.all_rects.remove(self.rect)
self.rect.topleft = self.pos
self.rect.size = self.dimensions
data.all_rects.insert(index, self.rect)
def check_collisions(self):
self._colliding_objects = [r for r in data.all_rects if r != self.rect and self.rect.colliderect(r)]
def is_colliding_with(self, rect):
return rect in self._colliding_objects
def get_all_obj_colliding_with(self):
return self._colliding_objects
def update(self):
self.active_world = physics.get_active_world()
self.update_rect()
self.check_collisions()
if self in self.spr_group:
self.spr_group.remove(self)
self.spr_group.update()
self.spr_group.add(self)
else:
self.spr_group.update()
self.spr_group.draw(pyg.display.get_surface())
MovingEntity class
The MovingEntity class extends entity to include velocity and gravity effects.
Initialization
The constructor initializes the moving entity with position, dimensions, velocity, and optional color or image.
class MovingEntity(Entity):
def __init__(self, position: tuple, dimensions: tuple, velocity: tuple, color:tuple=None, image_path=None) -> None:
super().__init__(position, dimensions, color=color, image_path=image_path)
self.velocity = pyg.math.Vector2(velocity)
self.orignal_vel = pyg.math.Vector2(velocity)
self.is_affected_by_gravity = False
def update(self):
self.active_world = physics.get_active_world()
Update method
The update method updates the entity's position, checks for collisions, and moves the entity.
self.update_rect()
self.check_collisions()
self.move()
if self in self.spr_group:
self.spr_group.remove(self)
self.spr_group.update()
self.spr_group.add(self)
else:
self.spr_group.update()
self.spr_group.draw(pyg.display.get_surface())
def move(self):
self.pos += self.velocity * self.active_world.dt
if not self.is_affected_by_gravity:
self.velocity.y = 0
return
self.velocity += self.active_world.gravity
def set_gravitified(self, bool:bool):
self.is_affected_by_gravity = bool
Move method
The move method updates the entity's position based on its velocity and gravity.
self.update_rect()
self.check_collisions()
self.move()
if self in self.spr_group:
self.spr_group.remove(self)
self.spr_group.update()
self.spr_group.add(self)
else:
self.spr_group.update()
self.spr_group.draw(pyg.display.get_surface())
def move(self):
self.pos += self.velocity * self.active_world.dt
if not self.is_affected_by_gravity:
self.velocity.y = 0
return
self.velocity += self.active_world.gravity
def set_gravitified(self, bool:bool):
self.is_affected_by_gravity = bool
Set gravity method
The set_gravitified method enables or disables gravity for the entity.
self.update_rect()
self.check_collisions()
self.move()
if self in self.spr_group:
self.spr_group.remove(self)
self.spr_group.update()
self.spr_group.add(self)
else:
self.spr_group.update()
self.spr_group.draw(pyg.display.get_surface())
def move(self):
self.pos += self.velocity * self.active_world.dt
if not self.is_affected_by_gravity:
self.velocity.y = 0
return
self.velocity += self.active_world.gravity
def set_gravitified(self, bool:bool):
self.is_affected_by_gravity = bool
Data and colors
Data module
The data module contains a list of all rectangles for collision detection.
all_rects = []
Colors module
The colors module defines some basic colors.
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
Initialization
Init module
The __init__ module imports necessary components and sets the version.
from . import entity
from . import data
from . import colors
from . import physics
from . import entity
import time
__version__ = '1.0.1'
Test script
Here is a test script to demonstrate the usage of PyGess:
import pygess
import time
# Create entities
entity1 = pygess.entity.Entity((50, 50), (10, 10), color=pygess.colors.RED)
entity2 = pygess.entity.MovingEntity((100, 100), (10, 10), (1, 1), color=pygess.colors.BLUE)
# Create a world with gravity
world = pygess.physics.World((0, 9.8), entity1, entity2)
# Set the world as active
pygess.physics.set_active_world(world)
# Main loop
while True:
pygess.physics.update_worlds()
time.sleep(0.016) # Simulate 60 FPS
This script creates a world with two entities, sets the world as active, and continuously updates the world in a loop.
Powered by Swimm
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pygess_py-3.0.26.tar.gz.
File metadata
- Download URL: pygess_py-3.0.26.tar.gz
- Upload date:
- Size: 8.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/1.8.3 CPython/3.12.7 Linux/6.5.0-1025-azure
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
532dcbdd231fabd9e6afef1e612cc0165916a19e82da5c0dc06fe0cbf6b24adc
|
|
| MD5 |
d0de3e2a51bdf68ba628dd8f6fd4f763
|
|
| BLAKE2b-256 |
663e1cbc932b537e401f7a156039e753a4eff8268be474219f4aa9c01e7474a5
|
File details
Details for the file pygess_py-3.0.26-py3-none-any.whl.
File metadata
- Download URL: pygess_py-3.0.26-py3-none-any.whl
- Upload date:
- Size: 7.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/1.8.3 CPython/3.12.7 Linux/6.5.0-1025-azure
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6c88452f17003af3cd64bdde6bf8a78bbc94f4bd39b11350295271c29fc2807f
|
|
| MD5 |
612f9543ddada666921bfeb7c33abe7c
|
|
| BLAKE2b-256 |
11c4b713e9500a03762138ca5ec8daf6c96b4394e436d90a5b435522e67b5aac
|