Skip to main content

My 2D Engine

A beginner-friendly 2D game engine built with Python and Pygame.

My 2D Engine is designed to make building 2D games easier without requiring you to write an entire game framework from scratch.

It provides systems for:

  • 🎮 Entities
  • ⚙️ Physics
  • 🧱 Collision
  • 🟦 One-way platforms
  • ↔️ Moving platforms
  • 🗺️ Tilemaps
  • 🎥 Cameras
  • 🎨 Rendering
  • 🎞️ Animations
  • 💥 Hitboxes
  • ✨ Particles
  • 🔊 Sound
  • 🎹 Keyboard and mouse input
  • 🖼️ Asset management
  • 🧩 Components
  • 🖥️ UI
  • 🎬 Scenes
  • 💾 Save/load
  • 🐛 Debugging

The engine is intended primarily for 2D platformers, arcade games, rhythm games, top-down games, shooters, and other small-to-medium 2D projects.


Table of Contents

  1. Requirements
  2. Installation
  3. Project Structure
  4. Quick Start
  5. Engine
  6. Entities
  7. Entity Properties
  8. Movement
  9. Physics
  10. Gravity
  11. Jumping
  12. Friction
  13. Acceleration
  14. Maximum Speed
  15. Custom Entity Updates
  16. Tags
  17. Sprites
  18. Animations
  19. Solids
  20. Collision
  21. One-Way Platforms
  22. Moving Platforms
  23. Hitboxes
  24. Particles
  25. Input
  26. Keyboard Input
  27. Mouse Input
  28. Tilemaps
  29. Tile Definitions
  30. Tilemap Layers
  31. Spawn Points
  32. Tilemap Collision
  33. Camera
  34. Rendering
  35. Components
  36. Scenes
  37. UI
  38. Asset Manager
  39. Sound
  40. Save and Load
  41. Debug Mode
  42. Complete Example
  43. Recommended Game Structure
  44. Common Mistakes
  45. Engine Architecture
  46. Current Limitations
  47. FAQ

Requirements

You need:

  • Python 3.10+
  • Pygame 2.x

Install Pygame with:

pip install pygame

Or:

python -m pip install pygame

Installation

Clone or download the engine.

Your project should contain the engine folder:

my_game/
│
├── main.py
│
└── engine/
    ├── engine.py
    ├── core/
    ├── collisions/
    ├── camera/
    ├── rendering/
    ├── scenes/
    └── tilemap/

Run your game with:

python main.py

Project Structure

The engine is separated into different systems.

engine/
│
├── engine.py
│
├── core/
│   ├── entity.py
│   ├── updater.py
│   ├── animation.py
│   ├── physics.py
│   ├── solid.py
│   ├── sound.py
│   ├── particle.py
│   ├── hitbox.py
│   ├── component.py
│   ├── input.py
│   ├── asset_manager.py
│   ├── ui.py
│   ├── save.py
│   └── debug.py
│
├── collisions/
│   └── collisions.py
│
├── camera/
│   └── camera.py
│
├── rendering/
│   └── renderer.py
│
├── scenes/
│   └── scene.py
│
└── tilemap/
    └── tilemap.py

You normally don't need to modify these files when making a game.

Your game code should primarily go into:

main.py

and your own game-specific files.


Quick Start

The smallest possible game is:

from engine.engine import Engine

game = Engine()

game.run()

This creates the game window and starts the engine.


Creating an Entity

Entities are the basic objects used in the engine.

Create one:

player = game.add_entity("player")

Set its position:

player.position = [100, 100]

Set its size:

player.size = [40, 40]

Set its color:

player.color = [255, 0, 0]

Enable collision:

player.collidable = True

Entity Properties

An entity contains several useful properties.

Position

player.position = [100, 200]

The position is:

[x, y]

Velocity

player.velocity = [5, 0]

The first value controls horizontal velocity.

The second controls vertical velocity.

player.velocity[0] = 5

moves right.

player.velocity[0] = -5

moves left.

player.velocity[1] = -10

moves upward.


Size

player.size = [50, 50]

Color

player.color = [255, 0, 0]

Colors use RGB values:

Red    = [255, 0, 0]
Green  = [0, 255, 0]
Blue   = [0, 0, 255]
White  = [255, 255, 255]
Black  = [0, 0, 0]

Visibility

player.visible = True

Hide an entity:

player.visible = False

Active State

player.active = True

Disable an entity:

player.active = False

Inactive entities are not updated.


Movement

The engine lets you directly control velocity:

player.velocity[0] = 5

Or create acceleration-based movement:

player.set_acceleration(0.5)

For a normal platformer, a custom update function is usually useful:

def update(player, keys):

    if game.input.down("left"):
        player.velocity[0] -= 0.5

    if game.input.down("right"):
        player.velocity[0] += 0.5

player.set_update(update)

Physics

Every entity has a physics system:

player.physics

The physics system supports:

  • Acceleration
  • Maximum speed
  • Friction
  • Air friction
  • Gravity scaling

Gravity

Enable gravity:

player.set_gravity(0.5)

The value controls how quickly vertical velocity increases.

Example:

player.set_gravity(0.6)

You can modify the gravity scale:

player.physics.gravity_scale = 0.5

This makes the entity experience half the normal gravity.


Jumping

Set jump strength:

player.set_jump(12)

Then:

player.jump()

The engine checks whether the entity is grounded.

You can also check:

if player.grounded:
    print("Player is standing on something")

Friction

Set ground and air friction:

player.set_friction(
    2,
    0.2
)

The first value is ground friction.

The second value is air friction.

Higher friction makes the entity stop faster.

For responsive movement, smaller values are usually preferable.


Acceleration

Enable acceleration:

player.set_acceleration(0.5)

You can also specify X and Y acceleration:

player.set_acceleration(
    0.5,
    0.2
)

Maximum Speed

Set horizontal and vertical maximum speeds:

player.set_max_speed(
    7,
    20
)

The first value is maximum X speed.

The second value is maximum Y speed.


Custom Entity Updates

Every entity can have its own update function.

def player_update(player, keys):

    if game.input.down("left"):
        player.velocity[0] -= 0.5

    if game.input.down("right"):
        player.velocity[0] += 0.5

    if game.input.pressed("jump"):
        player.jump()

player.set_update(
    player_update
)

The engine calls this function every frame.

This is where game-specific logic should normally go.


Tags

Tags allow you to categorize entities.

Add a tag:

player.add_tag("player")

Add multiple:

player.add_tag("character")
player.add_tag("friendly")

Check:

if player.has_tag("player"):
    print("This is the player")

Remove:

player.remove_tag("friendly")

Tags are useful for:

player
enemy
boss
projectile
coin
NPC
enemy_projectile
collectible

Finding Entities

Get an entity by name:

player = game.get_entity("player")

If it cannot be found, the result is:

None

Sprites

Entities can use images.

player.set_sprite(
    "assets/player.png"
)

Remove the sprite:

player.remove_sprite()

The renderer automatically uses the sprite when rendering the entity.


Animations

The engine contains an animation manager.

You can create an animation from separate images:

player.add_animation_images(
    "idle",
    [
        "assets/idle1.png",
        "assets/idle2.png",
        "assets/idle3.png"
    ],
    speed=10
)

Play it:

player.play_animation("idle")

Restart it:

player.play_animation(
    "idle",
    restart=True
)

Check whether an animation has finished:

if player.animation_finished():
    print("Animation finished")

You can use animations for:

Idle
Run
Jump
Fall
Attack
Death
Hurt
Dash

Solids

Solids are objects that entities can collide with.

Create one:

platform = game.add_solid(
    100,
    400,
    500,
    40
)

The arguments are:

x
y
width
height

You can change its color:

platform.color = [
    100,
    100,
    100
]

Collision

Enable collision on an entity:

player.collidable = True

The collision system handles movement against solid objects.

The system separates horizontal and vertical movement so basic platformer collisions can be handled independently.


One-Way Platforms

One-way platforms allow an entity to pass through from below and land on top.

Create one:

platform = game.add_one_way_platform(
    200,
    300,
    200,
    20
)

Conceptually:

        PLAYER
          ↓

    ───────────────
      PLATFORM

Player can pass upward
and land when falling.

This is useful for platformers.


Moving Platforms

Create a horizontal moving platform:

platform = game.add_moving_platform(
    400,
    350,
    150,
    25,
    velocity_x=50
)

Create a vertical moving platform:

platform = game.add_moving_platform(
    400,
    350,
    150,
    25,
    velocity_y=-50
)

Both directions can be used:

platform = game.add_moving_platform(
    400,
    350,
    150,
    25,
    velocity_x=50,
    velocity_y=-30
)

Moving platforms are useful for:

  • Platforming challenges
  • Elevators
  • Moving obstacles
  • Puzzle levels

Hitboxes

Hitboxes are areas that detect entities.

Create one:

trigger = game.add_hitbox(
    600,
    300,
    100,
    100
)

Create an event:

def entered(entity):

    print(
        entity.name,
        "entered the trigger"
    )

trigger.on_enter(
    entered
)

Hitboxes are useful for:

Triggers
Damage zones
Checkpoints
Portals
Collectibles
Boss arenas
Level transitions

Particles

The particle system can create visual effects.

Example:

game.particles.emit(
    400,
    300,
    count=30,
    color=(255, 200, 50),
    size=6,
    speed=150,
    lifetime=1,
    gravity=100
)

Parameters include:

x
y
count
color
size
speed
lifetime
gravity
image

Example explosion:

game.particles.emit(
    enemy.position[0],
    enemy.position[1],
    count=50,
    color=(255, 100, 20),
    size=5,
    speed=250,
    lifetime=0.8,
    gravity=150
)

Particles can also load animation images and sprite sheets.


Input

The input system provides keyboard and mouse controls.

Bind a key:

game.input.bind(
    "left",
    pygame.K_a
)
game.input.bind(
    "right",
    pygame.K_d
)
game.input.bind(
    "jump",
    pygame.K_SPACE
)

This means your game logic doesn't need to constantly reference raw Pygame keys.


Keyboard Input

Held

Use:

game.input.down("left")

This is True while the key is held.

Example:

if game.input.down("left"):
    player.velocity[0] -= 0.5

Pressed

Use:

game.input.pressed("jump")

This is useful for actions that should happen once per press.

Example:

if game.input.pressed("jump"):
    player.jump()

Mouse Input

Get mouse position:

mouse_x, mouse_y = game.input.mouse_pos()

Check whether a mouse button is held:

game.input.mouse_down(1)

Check whether it was pressed:

game.input.mouse_pressed(1)

Mouse button 1 is normally the left mouse button.


Tilemaps

Tilemaps let you build levels using characters.

Create a tilemap:

tilemap = Tilemap(
    game,
    50
)

The 50 means each tile is 50×50 pixels.


Defining Tiles

Define a solid tile:

tilemap.define_tile(
    "#",
    color=[80, 80, 80],
    solid=True,
    layer=0
)

Define another:

tilemap.define_tile(
    "G",
    color=[80, 180, 80],
    solid=True,
    layer=1
)

The character determines which tile gets created.


Loading a Tilemap

Example:

tilemap.load(
    """
########################
#                      #
#        GGG           #
#                      #
#   P                  #
########################
"""
)

If # is defined as a tile, every # becomes that tile.


Tilemap Layers

Tiles can be assigned layers:

tilemap.define_tile(
    "#",
    color=[100, 100, 100],
    solid=True,
    layer=0
)

Higher layers can be used for visual ordering.

A possible design is:

Layer 0 → Ground
Layer 1 → Decoration
Layer 2 → Foreground

Spawn Points

Define a spawn character:

tilemap.define_spawn(
    "P",
    "player_spawn"
)

Load the map:

tilemap.load(
    """
########
#      #
#  P   #
########
"""
)

Get the spawn:

spawn = tilemap.get_spawn(
    "player_spawn"
)

Place the player:

player.position = spawn

Tilemap Collision

Add an entity to the tilemap's collision system:

tilemap.add_collision_entity(
    player
)

Solid tiles can then interact with that entity.


Camera

The camera controls what part of the world is visible.

Create one:

camera = Camera(
    game.window_w,
    game.window_h
)

Make it follow the player:

camera.follow(
    player
)

Attach it to the engine:

game.add_camera(
    camera
)

The camera is useful for:

  • Large levels
  • Platformers
  • Scrolling games
  • Top-down games
  • Following players

Rendering

The renderer is responsible for drawing the game world.

The general rendering order is:

Background
    ↓
Solids / Tilemap
    ↓
Entities
    ↓
Particles
    ↓
UI
    ↓
Debug information

This means UI and debug information can be displayed above the game world.


Components

Components let you attach custom systems/data to entities.

Create a component:

from engine.core.component import Component


class Health(Component):

    def __init__(self, amount):
        super().__init__()
        self.health = amount

    def damage(self, amount):
        self.health -= amount

Add it:

player.add_component(
    Health(100)
)

Get a component:

health = player.get_component(
    Health
)

Check:

if player.has_component(Health):
    print("Player has health")

Remove:

player.remove_component(
    health
)

Components are useful for systems such as:

Health
Inventory
Weapons
AI
Stats
Dialogue
Abilities
Status effects

Scenes

Scenes allow different parts of a game to be separated.

Example:

from engine.scenes.scene import Scene


class Level1(Scene):

    def start(self):

        self.player = self.game.add_entity(
            "player"
        )

    def update(self, dt):

        pass

Register it:

game.scene.register(
    "level1",
    Level1(game)
)

Load it:

game.scene.load(
    "level1"
)

Possible scenes:

Main Menu
Level 1
Level 2
Boss
Game Over
Credits

Scenes can track game objects created for them and clean them up when switching scenes.


UI

The engine contains a UI system for screen-space elements.

The UI manager can create:

Text
Panels
Buttons
Sliders

Text

Example:

game.ui.text(
    "Hello World",
    20,
    20,
    size=28
)

Another:

game.ui.text(
    "A / D = Move",
    20,
    60,
    size=20
)

Panels

Create a UI panel:

panel = game.ui.panel(
    20,
    20,
    300,
    200
)

Panels are useful for:

Menus
Inventory
Settings
HUD backgrounds
Dialogue boxes

Buttons

Create a button:

def clicked():
    print("Button clicked!")


button = game.ui.button(
    "Start Game",
    100,
    100,
    200,
    50,
    clicked
)

Buttons can be used for:

Menus
Settings
Inventory
Pause screens
Level selection

Sliders

Create a slider:

slider = game.ui.slider(
    100,
    200,
    300,
    30
)

Sliders are useful for:

Volume
Brightness
Settings
Game values

Asset Manager

The asset manager handles loading and caching resources.

Access it with:

game.assets

Images

Load an image:

image = game.assets.image(
    "assets/player.png"
)

Give it a custom name:

image = game.assets.image(
    "assets/player.png",
    name="player"
)

The engine caches loaded images so the same resource does not need to be loaded repeatedly.


Sounds

Load a sound:

sound = game.assets.sound(
    "assets/jump.wav"
)

Fonts

Load a font:

font = game.assets.font(
    "assets/font.ttf",
    32
)

Asset Caching

The asset manager keeps loaded resources in memory.

This is useful because repeatedly loading the same file is inefficient.

You can clear the asset cache:

game.assets.clear()

Sound

The engine includes a sound manager.

Access it with:

game.sounds

Use the sound manager for game audio instead of creating a completely separate audio system for every object.

Typical uses include:

Jump sounds
Weapons
UI clicks
Explosions
Music
Environment sounds

Save and Load

The engine includes a JSON-based save system.

Save:

game.save(
    "save1"
)

Load:

game.load(
    "save1"
)

The engine can automatically save basic entity information such as:

Position
Velocity
Active state

You can also provide your own data:

game.save(
    "save1",
    {
        "coins": 50,
        "level": 3
    }
)

Debug Mode

Debugging can be enabled with:

game.debug = True

Press:

F3

to toggle debugging during runtime.

The debug system can display information such as:

FPS
Entity count
Solid count
Hitbox count
Particle count
Camera information
Entity collision boxes
Solid collision boxes
Physics information
Velocity visualization

Debug mode is extremely useful when developing a game.


Complete Example

Here is a small complete platformer using the engine:

import pygame

from engine.engine import Engine
from engine.camera.camera import Camera
from engine.tilemap.tilemap import Tilemap


game = Engine()

game.input.bind(
    "left",
    pygame.K_a
)

game.input.bind(
    "right",
    pygame.K_d
)

game.input.bind(
    "jump",
    pygame.K_SPACE
)


player = game.add_entity(
    "player"
)

player.position = [
    100,
    100
]

player.size = [
    40,
    40
]

player.color = [
    255,
    50,
    50
]

player.collidable = True

player.set_gravity(
    0.6
)

player.set_jump(
    12
)

player.set_friction(
    2,
    0.2
)

player.set_max_speed(
    7,
    20
)


def player_update(
    player,
    keys
):

    if game.input.down("left"):
        player.velocity[0] -= 0.5

    if game.input.down("right"):
        player.velocity[0] += 0.5

    if game.input.pressed("jump"):
        player.jump()


player.set_update(
    player_update
)


ground = game.add_solid(
    0,
    500,
    1200,
    50
)

ground.color = [
    80,
    80,
    80
]


platform = game.add_one_way_platform(
    300,
    350,
    200,
    20
)

platform.color = [
    80,
    150,
    255
]


moving = game.add_moving_platform(
    600,
    400,
    150,
    25,
    velocity_x=50
)

moving.color = [
    255,
    170,
    50
]


camera = Camera(
    game.window_w,
    game.window_h
)

camera.follow(
    player
)

game.add_camera(
    camera
)


game.ui.text(
    "A / D = Move    SPACE = Jump",
    20,
    20,
    size=22
)


game.debug = True


game.run()

Recommended Game Structure

As your game becomes larger, don't put everything in main.py.

A recommended structure is:

my_game/
│
├── main.py
│
├── engine/
│
├── game/
│   ├── player.py
│   ├── enemies.py
│   ├── weapons.py
│   ├── levels.py
│   ├── items.py
│   └── game_manager.py
│
├── assets/
│   ├── images/
│   ├── sounds/
│   ├── music/
│   └── fonts/
│
└── saves/

For example:

from game.player import create_player

Then:

player = create_player(game)

This keeps your game organized.


Recommended Architecture

Try to keep the engine and game separate.

Engine

The engine should provide:

Physics
Rendering
Input
Collision
Camera
Scenes
UI
Particles
Audio
Assets
Saving

Game

Your game should provide:

Player
Enemies
Weapons
Levels
Story
Items
Rules
Game-specific mechanics

For example, the engine should not contain:

if player.has_tag("player"):

unless that is part of a generic engine system.

Instead, your game should decide what a player is.


Engine Architecture

The basic flow of the engine is:

                 Engine
                   │
        ┌──────────┼──────────┐
        ↓          ↓          ↓
      Input      Scene      Assets
        │          │
        ↓          ↓
     Entities   Game Objects
        │
        ↓
     Updater
        │
        ├───────────────┐
        ↓               ↓
    Physics         Components
        │
        ↓
    Collision
        │
        ↓
     Camera
        │
        ↓
    Renderer
        │
        ├── Tilemap
        ├── Entities
        └── Solids
        │
        ↓
    Particles
        ↓
       UI
        ↓
      Debug
        ↓
      Screen

Game Loop

The engine continuously performs roughly this process:

Start
 ↓
Read events
 ↓
Update input
 ↓
Update moving solids
 ↓
Update entities
 ↓
Apply physics
 ↓
Resolve collisions
 ↓
Update hitboxes
 ↓
Update particles
 ↓
Update scenes
 ↓
Update UI
 ↓
Update camera
 ↓
Render world
 ↓
Render particles
 ↓
Render UI
 ↓
Render debug information
 ↓
Display frame
 ↓
Repeat

This happens every frame while:

game.running

is true.


Getting Started With Your Own Game

A good development order is:

Step 1 — Create the engine

game = Engine()

Step 2 — Create your player

player = game.add_entity(
    "player"
)

Step 3 — Add movement

player.set_update(
    player_update
)

Step 4 — Add physics

player.set_gravity(
    0.6
)

Step 5 — Add level geometry

game.add_solid(
    0,
    500,
    1000,
    50
)

Step 6 — Add camera

camera.follow(
    player
)

Step 7 — Add graphics

player.set_sprite(
    "assets/player.png"
)

Step 8 — Add game mechanics

Use:

Components
Hitboxes
Particles
Animations
Scenes

Step 9 — Add UI

Create:

Health bar
Score
Menus
Buttons

Step 10 — Enable debugging

game.debug = True

Common Mistakes

1. Forgetting to enable collision

This:

player = game.add_entity("player")

doesn't automatically make the entity collide.

Use:

player.collidable = True

2. Forgetting gravity

If your player doesn't fall:

player.set_gravity(
    0.6
)

3. Forgetting to set an update function

If you expect custom movement, make sure you have:

player.set_update(
    player_update
)

4. Using excessive friction

If your player barely moves or stops instantly:

player.set_friction(
    2,
    0.2
)

is generally more responsive than:

player.set_friction(
    8,
    1
)

5. Forgetting the camera

Create and attach it:

camera = Camera(
    game.window_w,
    game.window_h
)

camera.follow(player)

game.add_camera(camera)

6. Forgetting to start the engine

Your program needs:

game.run()

Performance Tips

Don't create expensive resources every frame.

Avoid:

def update(player, keys):

    image = pygame.image.load(
        "player.png"
    )

Instead, load assets once.

Use the asset manager:

image = game.assets.image(
    "player.png"
)

Debugging Your Game

When something doesn't work:

First enable:

game.debug = True

Then press:

F3

Check:

FPS
Entity count
Collision boxes
Hitboxes
Physics
Camera

If Python gives you a traceback, look at the last line first.

For example:

AttributeError:
'Player' object has no attribute 'something'

usually means the code is trying to use a property or method that doesn't exist.


Current Limitations

This engine is designed to be lightweight and beginner-friendly. It is not currently intended to replace full commercial engines such as Unity or Godot.

Some advanced features may require implementation in future versions.

Current areas that can be improved include:

  • Advanced slope collision
  • Continuous collision detection
  • Spatial partitioning for extremely large numbers of objects
  • More advanced tilemap optimization
  • More advanced animation systems
  • Advanced audio management
  • A visual level editor
  • Prefab systems
  • More sophisticated particle simulation
  • Advanced rendering effects
  • Networking/multiplayer
  • 3D rendering

The engine is primarily designed for 2D games.


FAQ

Is this a 3D engine?

No.

It is a 2D engine built using Pygame.


Do I need to know Pygame?

Basic Pygame knowledge helps, but the engine hides many common Pygame tasks.

You can mostly work with:

game
player
platform
camera
scene
tilemap

instead of directly managing the entire Pygame game loop yourself.


Can I make a platformer?

Yes.

The engine provides:

  • Gravity
  • Jumping
  • Collision
  • One-way platforms
  • Moving platforms
  • Camera
  • Tilemaps
  • Particles
  • Animations
  • Hitboxes

Can I make a top-down game?

Yes.

You can disable gravity:

player.gravity_enabled = False

and implement top-down movement.


Can I make a shooter?

Yes.

Entities, hitboxes, particles, input, components and collision can be used to build weapons and projectiles.


Can I make a Geometry Dash-style game?

Yes.

The engine can provide many of the underlying systems needed for a rhythm-platformer, including:

Automatic movement
Collision
Gravity
Platforms
Triggers
Particles
Camera
Animations
Tilemaps

The actual game mechanics should be implemented by your game.


Can I make menus?

Yes.

Use the UI system:

Text
Panels
Buttons
Sliders

and scenes for different screens.


Can I save games?

Yes.

Use:

game.save("save1")

and:

game.load("save1")

Minimal Template

For a new game, this is a good starting point:

import pygame

from engine.engine import Engine
from engine.camera.camera import Camera


game = Engine()


game.input.bind(
    "left",
    pygame.K_a
)

game.input.bind(
    "right",
    pygame.K_d
)

game.input.bind(
    "jump",
    pygame.K_SPACE
)


player = game.add_entity(
    "player"
)

player.position = [
    100,
    100
]

player.size = [
    40,
    40
]

player.color = [
    255,
    50,
    50
]

player.collidable = True

player.set_gravity(
    0.6
)

player.set_jump(
    12
)

player.set_friction(
    2,
    0.2
)

player.set_max_speed(
    7,
    20
)


def player_update(
    player,
    keys
):

    if game.input.down("left"):
        player.velocity[0] -= 0.5

    if game.input.down("right"):
        player.velocity[0] += 0.5

    if game.input.pressed("jump"):
        player.jump()


player.set_update(
    player_update
)


game.add_solid(
    0,
    500,
    1200,
    50
)


camera = Camera(
    game.window_w,
    game.window_h
)

camera.follow(
    player
)

game.add_camera(
    camera
)


game.run()

Final Notes

My 2D Engine is built around one main idea:

The engine provides the systems. Your game provides the rules.

You should be able to create a game without rewriting the engine every time.

For example:

ENGINE
│
├── Physics
├── Collision
├── Rendering
├── Input
├── Camera
├── Tilemaps
├── Particles
├── Audio
├── UI
├── Scenes
├── Components
└── Saving
        │
        ↓
      YOUR GAME
        │
        ├── Player
        ├── Enemies
        ├── Levels
        ├── Weapons
        ├── Items
        ├── Game rules
        └── Story

Build the engine once.

Then use it to build many different games.


License

Add your chosen license here before publicly distributing the engine.

For example:

MIT License

or another license appropriate for your project.


My 2D Engine

Python + Pygame

A lightweight, beginner-friendly foundation for creating 2D games.

Metadata

Release files for sypy-engine-beginner 0.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for sypy-engine-beginner 0.1.1
File Size Uploaded
sypy_engine_beginner-0.1.1.tar.gz 36.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for sypy-engine-beginner 0.1.1
File Interpreter ABI Platform
sypy_engine_beginner-0.1.1-py3-none-any.whl Python 3 none any Details

Total release size: 66.6 kB

Release files / sypy_engine_beginner-0.1.1.tar.gz

Download URL sypy_engine_beginner-0.1.1.tar.gz
Size 36.2 kB
Tags Source
SHA-256 checksum
How to use checksums
7d2015d70ae78c3ba73744f602108df6fa287ca44d37f7190227971811584611
BLAKE2b-256 checksum
How to use checksums
5e565878444bfa7c5dc1cda5afc6f81577750f23a59a6c5dda2798791b0b553b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.6

Release files / sypy_engine_beginner-0.1.1-py3-none-any.whl

Download URL sypy_engine_beginner-0.1.1-py3-none-any.whl
Size 30.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
d12391081563dbcfa5aaea05d4acc7d9af8a288549ae45f6942f82b982d5a44e
BLAKE2b-256 checksum
How to use checksums
8903fc0793f07a6302564a6f81654b878233ef8728cd815c051cd676ede0d415
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.6

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page