Metadata-Version: 2.4
Name: easy2d
Version: 0.5.2
Summary: A practical 2D game framework for Python with scenes, camera, particles, multiplayer networking, CLI host/join tools, chunked tilemaps, and an in-house UI/backend
Author-email: Daniel <tolmmu979@gmail.com>
License-Expression: MIT
Project-URL: Homepage, https://pypi.org/project/easy2d/
Project-URL: Documentation, https://pypi.org/project/easy2d/
Project-URL: Source, https://pypi.org/project/easy2d/
Keywords: 2d,game,engine,networking,easy2d-backend,ui
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Games/Entertainment
Classifier: Topic :: Software Development :: Libraries
Requires-Python: >=3.8
Description-Content-Type: text/markdown

````md
# Easy2D

Easy2D is a general-purpose 2D game framework for Python with an in-house backend API.

It is designed to support many kinds of 2D games: arcade, platformer, top-down, RPG-style, puzzle, shooter, story-driven, menu-heavy, multiplayer prototypes, and experimental projects.

## Install

```bash
pip install easy2d
````

## Community

Need help, want to report a bug, or have an idea for a new feature?

Join the community Discord for support, updates, bug reports, and suggestions for Easy2D, AutoConfigPy, and other related libraries:

[https://discord.gg/BuDs8jVQUP](https://discord.gg/BuDs8jVQUP)

## Quick Start

```python
import easy2d as e

game = e.Game("My Game", 960, 540, fps=120)

class MainScene(e.Scene):
    def __init__(self):
        super().__init__()
        self.player = self.add(e.Rect(100, 100, 32, 32, gravity=0.0, floor_y=None))
        self.title = self.add(e.Text("Hello Easy2D", 20, 20))
        self.button = self.add(e.Button("Play", 100, 100, 180, 50, on_click=self.play))

    def play(self):
        print("Play clicked")

game.set_scene(MainScene())
game.run()
```

## Display and Fullscreen

```python
game = e.Game(
    "Display Demo",
    960,
    540,
    fullscreen=False,
    resizable=True,
    vsync=True,
    scale_mode="fit",  # native | fit | stretch | pixel-perfect
)

game.toggle_fullscreen()
game.set_resolution(1280, 720)
```

## UI

```python
scene.add(e.Text("Settings", 30, 20, size=30))
scene.add(e.Panel(20, 50, 420, 260))
scene.add(e.Button("Apply", 40, 80, 170, 44, on_click=apply_settings))
scene.add(e.TextInput(40, 140, 240, 40, placeholder="Player name"))
scene.add(e.Checkbox(40, 200, text="Fullscreen"))
scene.add(e.Slider(40, 250, 220, min_value=0, max_value=100, value=75))
```

## Sprites and Animation

```python
player = e.Sprite("assets/player.png", 100, 100)
player.scale = 2
player.flip_x = True
player.rotation = 8

anim = e.AnimatedSprite(200, 100)
anim.add_animation("idle", ["idle1.png", "idle2.png"], fps=6)
anim.add_animation("run", ["run1.png", "run2.png"], fps=12)
anim.play("run")
```

## Audio and Assets

```python
game.assets.load_image("player", "assets/player.png")
game.assets.load_json("level", "assets/level1.json")
game.assets.load_font("main", size=24)

game.audio.load_sound("coin", "assets/coin.wav")
game.audio.play_sound("coin")
game.audio.play_music("assets/theme.mp3", loop=True)
```

## Particles

```python
fx = e.ParticleSystem.explosion()
fx.emit_burst(200, 200, count=40)
```

## Networking Helpers

```python
server = e.MultiplayerServer(port=5000)
server.start()
server.broadcast({"type": "chat", "text": "hello"})
messages = server.get_messages()

client = e.MultiplayerClient()
client.connect("127.0.0.1", 5000)
client.send({"type": "hello"})
inbox = client.get_messages()
client.disconnect()

# Authoritative server + rollback snapshots
auth = e.AuthoritativeGameServer(port=7777, tick_rate=60)
auth.start()

# Reliable UDP channel (ack/retry)
udp = e.ReliableUDPChannel(port=7001)
udp.start()

# Built-in matchmaking queue
mm = e.MatchmakingService()
mm.enqueue("player-1", region="us", mode="duel")
mm.enqueue("player-2", region="us", mode="duel")
matches = mm.poll_matches()
```

## CLI

```bash
easy2d --help
easy2d --show-scope
easy2d --multiplayer
easy2d --multiplayer --port 7777
easy2d --host --port 5000
easy2d --join 127.0.0.1 --port 5000 --message "hello"
easy2d --net-test --port 5000
easy2d --list-examples
easy2d --write-example basic
easy2d --write-example ui
easy2d --write-example particles
easy2d --write-example multiplayer
easy2d --write-all-examples
easy2d new arcade MyGame
easy2d new topdown MyTopDown
easy2d new shooter MyShooter
```

## Current Scope

* Scene-based game loop
* Camera follow/zoom/shake
* Tilemaps with chunk caching
* UI widgets
* Sprite and basic animation classes
* Particle systems
* Audio and asset managers
* Timer and tween helpers
* Beginner-friendly multiplayer relay helpers
* Authoritative game server framework
* Reliable UDP transport with ack/retry
* Rollback snapshot buffer utilities
* Built-in matchmaking queues

## Roadmap

* Expanded physics and collision response
* Sprite atlas/animation tools
* Save/load helper utilities
* Higher-level authoritative netcode patterns
* Additional UI widgets and layout helpers

```
```
