# PyGame-S — PyGame Simplified

PyGame-S is a beginner-friendly wrapper around [Pygame](https://www.pygame.org/) that simplifies game development without limiting what you can build. Write less boilerplate, focus more on your game.

---

## Installation

Place the `pygames` folder inside your project or install it into your Python environment's `site-packages`. Or on your terminal type pip install pygames-simplified

Then import based on the complexity level you need:

```python
from pygames.medium import *    # Physics only
from pygames.advanced import *  # Physics + Player
```

---

## Complexity Tiers

| Import | What you get |
|---|---|
| `medium` | Core engine + physics (no player input) |
| `advanced` | Core engine + physics + controllable player |

---

## Quick Start

```python
from pygames.advanced import *

game = pygames(800, 600, "My Game")

player = Player(game, 100, 300)
ground = SSprites(game, 0, 550, source=Surface((800, 50)))
ground.image.fill("green")

game.start(player)
game.make_solid(ground)

def logic():
    game.background("skyblue")
    player.tick()

game.mainloop(logic)
```

---

## Core — `pygames`

```python
game = pygames(w=800, h=600, title="My Game", icon_path=None)
```

| Method | Description |
|---|---|
| `game.background(color)` | Fill the screen with a color each frame |
| `game.start(*objects)` | Register objects to be drawn and updated |
| `game.make_solid(*objects)` | Mark objects as collidable |
| `game.key(name)` | Check if a key is pressed — e.g. `"left"`, `"space"`, `"w"` |
| `game.start_score_counter()` | Display score on screen |
| `game.score` | Set or update the score value |
| `game.start_garbage_collecter()` | Auto-remove off-screen objects |
| `game.load_image(name, path)` | Load an image by name |
| `game.image(name, x, y, w, h)` | Draw a loaded image |
| `game.load_sound(name, path)` | Load a sound by name |
| `game.play_sound(name)` | Play a loaded sound |
| `game.mainloop(logic)` | Start the game loop |
| `game.zoom(factor)` | Resize the window by a multiplier |

---

## Base Sprite — `SSprites`

```python
obj = SSprites(game, x, y, image_path=None, source=None)
```

The base class for all game objects. Accepts an image path, a raw `Surface`, or defaults to a white square.

| Method | Description |
|---|---|
| `obj.draw()` | Draws the object to the screen |
| `obj.move(dx, dy)` | Moves the object by an offset |

---

## Physics — `PhysicSprite` (medium)

```python
obj = PhysicSprite(game, x, y, width=50, height=50, color="red")
```

Extends `SSprites` with gravity, collision, and velocity.

| Attribute | Description |
|---|---|
| `obj.vel_x` | Horizontal velocity |
| `obj.vel_y` | Vertical velocity |
| `obj.gravity` | Gravity strength (default `0.8`) |
| `obj.max_fall_speed` | Max fall speed to prevent tunneling (default `20`) |
| `obj.on_ground` | `True` if standing on a solid |

| Method | Description |
|---|---|
| `obj.apply_physics(solids)` | Apply gravity and collision — called automatically |
| `obj.jump(force=15)` | Jump if on the ground |

---

## Player — `Player` (advanced)

```python
player = Player(game, x, y, width=40, height=60, color="blue", speed=5,
                left="left", right="right", jump="space")
```

Extends `PhysicSprite` with keyboard input. Key bindings are fully customizable.

| Method | Description |
|---|---|
| `player.tick()` | Process input — call this in your game logic function |
| `player.handle_input()` | Handles left, right, and jump keys |

---

## Supported Keys

Pass any of these strings to `game.key()` or as custom key bindings:

`"left"`, `"right"`, `"up"`, `"down"`, `"space"`, `"esc"`, `"enter"`, `"shift"`, `"ctrl"`, `"tab"`, `"backspace"`, or any letter/number like `"a"`, `"w"`, `"1"`

---
## Animator 

The **Animator** is a lightweight, non-blocking animation controller for the PyGame-S engine. It handles state-based image swapping and mathematical transformations without using `time.sleep()`.

### Features
* **Non-Blocking**: Uses `time.time()` for frame timing so the game loop never freezes.
* **State-Aware**: Automatically detects the target's current state to play the correct animation sequence.
* **Math Effects**: Built-in support for sine-wave hovering and continuous rotation.
* **Decoupled**: Works on any object with a `.state` and an `.animations` dictionary.

### Requirements
* `pygame`
* `time`
* `math`

### Functions

#### refresh()
Updates the `target.image` to the next frame based on `animation_speed`.

#### hover(amplitude=5, speed=5)
Creates a vertical bobbing effect using `math.sin()`.
* **amplitude**: Height of the motion.
* **speed**: Frequency of the motion.

#### rotate_loop(speed=100)
Continuously rotates the sprite's image.

#### set_speed(speed)
Updates the animation delay.

## Quick Start
```python
anim = Animator(player, 0.1)

# In Loop
anim.refresh()
anim.hover(10, 2)

## Native Pygame

Since PyGame-S uses `from pygame import *` internally, all Pygame features are available directly:

```python
from pygames.advanced import *

mixer.music.load("background.mp3")
mixer.music.play(-1)

draw.rect(game.screen, "red", (100, 100, 50, 50))
```
---

## Error Handling

PyGame-S raises clear errors to help you debug:

| Error | Cause |
|---|---|
| `NameError` | Invalid file path or missing sound/image |
| `TypeError` | Wrong type passed to width, height, speed, or jump force |
| `ValueError` | Negative speed value |

---

## Version
Current release: **v1.8.1**

Inspired by [Pygame Zero](https://pygame-zero.readthedocs.io/), built to be more Pythonic, flexible, and extensible.

## Links
- GitHub: https://github.com/manupolice12-sketch/pygames
- Bug Reports: https://github.com/manupolice12-sketch/pygames/issues

[![PyPI version](https://badge.fury.io/py/pygames-simplified.svg)](https://pypi.org/project/pygames-simplified/)

## Requirements
pygames-simplified uses pygame-ce (Community Edition) for better performance and active maintenance.

## Note
If you have the original pygame installed, uninstall it first:
pip uninstall pygame
pip install pygames-simplified