Metadata-Version: 2.4
Name: pychelonia
Version: 1.0.0rc1
Summary: A Turtle-like drawing API for pygame surfaces
Project-URL: Repository, https://github.com/Imagination12357/PyChelonia
Project-URL: Issues, https://github.com/Imagination12357/PyChelonia/issues
Project-URL: Changelog, https://github.com/Imagination12357/PyChelonia/blob/main/CHANGELOG.md
Author-email: imagination12357 <imagination12357@gmail.com>
License-Expression: MIT
License-File: LICENSE
Keywords: drawing,graphics,pygame,turtle
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Education
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Topic :: Multimedia :: Graphics
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Software Development :: Libraries :: pygame
Requires-Python: >=3.11
Requires-Dist: pygame>=2.1.3
Provides-Extra: dev
Requires-Dist: pytest>=8.0.0; extra == 'dev'
Description-Content-Type: text/markdown

# PyChelonia

PyChelonia brings a familiar Turtle-style drawing API to
`pygame.Surface`. It is designed for pygame applications that want simple
position, heading, line, circle, fill, dot, and text commands without giving
up control of their window, event loop, composition, or shutdown lifecycle.

PyChelonia is a selected reimplementation, not a drop-in replacement for the
complete Python `turtle` module.

![Animated sea turtle drawn on a PyChelonia Surface and composed onto a pygame-owned canvas](https://raw.githubusercontent.com/Imagination12357/PyChelonia/main/docs/assets/pychelonia-showcase.gif)

The sea turtle is drawn on one transparent Chelonia Surface and composed with
a pygame-owned background, layout, text, display, and frame loop.

## Why PyChelonia?

- Draw with Turtle-style movement instead of calculating rotation matrices
  for every line.
- Use the result as a normal pygame Surface alongside sprites, UI, and other
  application rendering.
- Redraw in real time while the host application keeps control of timing and
  events.
- Test drawing offscreen without creating a pygame window.
- Keep each drawing object isolated on one dedicated Surface.

## Quick Start

```python
from pychelonia import Chelonia

turtle = Chelonia((800, 600), alpha=True)
turtle.pencolor(20, 40, 220)
turtle.pensize(3)
turtle.forward(100)
turtle.left(90)
turtle.forward(50)

surface = turtle.surface
```

`Turtle` is an alias for `Chelonia`:

```python
from pychelonia import Chelonia, Turtle

assert Turtle is Chelonia
```

## Requirements

- Python 3.11 or newer
- pygame 2.1.3 or newer

## Installation

PyChelonia `1.0.0rc1` is prepared but has not been published to PyPI. Install
the current source from a local checkout:

```bash
git clone https://github.com/Imagination12357/PyChelonia.git
cd PyChelonia
python -m pip install .
```

After publication, the release candidate is intended to be installable with:

```bash
python -m pip install --pre pychelonia==1.0.0rc1
```

That command is not a current availability claim.

For development with uv:

```bash
uv sync --extra dev
```

See the
[changelog](https://github.com/Imagination12357/PyChelonia/blob/main/CHANGELOG.md)
and
[draft `1.0.0rc1` release notes](https://github.com/Imagination12357/PyChelonia/blob/main/docs/release-notes-v1.0.0rc1.md)
for release status and compatibility details.

## Pygame Integration

The host application owns pygame initialization, its window and event loop,
and composition of the dedicated Chelonia Surface:

```python
import pygame

from pychelonia import Chelonia

pygame.init()
screen = pygame.display.set_mode((800, 600))
clock = pygame.time.Clock()

turtle = Chelonia(screen.get_size(), alpha=True)
turtle.pencolor("navy")
turtle.forward(100)
turtle.left(90)
turtle.forward(50)

running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

    screen.fill("white")
    screen.blit(turtle.surface, (0, 0))
    pygame.display.flip()
    clock.tick(60)

pygame.quit()
```

PyChelonia only updates `turtle.surface`. It does not initialize pygame,
create the display, process events, blit to the window, update the display, or
shut pygame down.

## Surface Ownership

The `1 Chelonia = 1 dedicated Surface` rule is part of the current contract.
Do not attach multiple instances to the same Surface or concurrently modify a
Chelonia-owned Surface from other drawing code.

Three construction forms are supported:

```python
import pygame

from pychelonia import Chelonia

supplied = pygame.Surface((800, 600))

direct = Chelonia(supplied)
from_tuple = Chelonia((800, 600))
from_dimensions = Chelonia(800, 600)

assert direct.surface is supplied
```

The `surface` property is getter-only and preserves object identity. The
returned pygame Surface remains mutable because the host must be able to blit
and inspect it.

Internally created surfaces can use per-pixel alpha:

```python
import pygame

from pychelonia import Chelonia

turtle = Chelonia((800, 600), alpha=True)

assert turtle.surface.get_flags() & pygame.SRCALPHA
```

- Opaque internal surfaces default to white.
- Alpha surfaces default to transparent.
- Every constructor clears the complete active Surface, including a directly
  supplied Surface.
- `background_color` changes the color used by future `clear()` and `reset()`
  calls; assigning it does not repaint immediately.
- `alpha=True` is only valid for internally created surfaces. A supplied
  Surface keeps its existing pixel format.

## Coordinate Model

PyChelonia uses centered, y-up Turtle coordinates:

- `(0, 0)` is the center of the Surface.
- Heading `0` points right.
- Heading `90` points up.
- Positive `y` moves upward.

Conversion to pygame's top-left, y-down coordinates happens internally.

## Supported API

| Area | Methods and properties |
| --- | --- |
| Movement | `forward/fd`, `backward/back/bk`, `goto/setpos/setposition`, `teleport`, `setx`, `sety`, `home` |
| Rotation | `left/lt`, `right/rt`, `setheading/seth`, `heading`, `towards` |
| Drawing | `circle`, `dot`, `begin_fill`, `filling`, `end_fill`, `write` |
| Position | `position/pos`, `xcor`, `ycor`, `distance` |
| Pen | `penup/up/pu`, `pendown/down/pd`, `isdown`, `pen`, `pencolor`, `pensize/width` |
| Style | `fillcolor`, `color` |
| Identity | `getpen/getturtle` |
| Visibility state | `showturtle/st`, `hideturtle/ht`, `isvisible` |
| Surface | `surface`, `background_color`, `clear`, `reset` |

### Colors and Width

Color setters accept one pygame-compatible color value or fixed-range
`red, green, blue` integer channels. Getters return copied `pygame.Color`
values.

```python
turtle.pencolor("navy")
turtle.fillcolor(40, 190, 120)
turtle.color("black", "orange")
turtle.color(20, 40, 220)
```

`color()` returns the pen and fill colors. Setter changes are atomic: if any
supplied color is invalid, neither stored color changes. Explicit `None` is an
invalid setter value.

Pen widths accept positive integer-valued real numbers and are stored as
integer pixel widths.

### Position and Teleport

`position()` and `pos()` return the exported tuple-compatible `Vec2D`.
Constructor position, `goto`, `towards`, and `distance` accept exact-two
point-like iterables such as tuples, lists, `Vec2D`, and `pygame.Vector2`.

`teleport(x=None, y=None, *, fill_gap=False)` moves without drawing or changing
persistent pen state. During an active fill, the default commits the current
polygon and begins another at the destination. `fill_gap=True` keeps one fill
path across the invisible movement.

### Fill and Text

Polygon filling uses the familiar lifecycle:

```python
turtle = Chelonia((200, 200), fillcolor="orange")
turtle.begin_fill()
for _ in range(4):
    turtle.forward(60)
    turtle.left(90)
turtle.end_fill()
```

Fill paths include pen-up movement and sampled circle points. The public
Surface object remains stable throughout fill composition.

Text requires a caller-created `pygame.font.Font`:

```python
import pygame

pygame.font.init()
font = pygame.font.Font(None, 24)
turtle.write("PyChelonia", align="center", font=font)
```

PyChelonia does not initialize or shut down the font subsystem. Text remains
unrotated and uses the current pen color. `write(move=True)` moves normally to
the rendered text's right edge.

### Clear, Reset, and Visibility

`clear()` fills the dedicated Surface with `background_color` while preserving
persistent Turtle state. `reset()` also restores library defaults. Both
cancel an unfinished fill without replacing the Surface object.

Visibility is logical state only. PyChelonia does not render a turtle cursor.

## Compatibility and Limits

The current compatibility matrix contains 32 selected rows:

- 17 `Match`
- 10 `Partial`
- 5 `Intentional difference`
- 0 `Unsupported`

Important current limits:

- Tk color modes and the complete Tk color-name database are not reproduced.
- Fractional pixel widths are not rendered.
- pygame and Tk Canvas do not produce pixel-identical geometry.
- Direct external Surface mutation during an active fill cannot be guaranteed
  to survive final fill composition.
- Cursor shapes, stamps, cursor events, animation, undo history, and pygame
  lifecycle ownership are outside the active scope.
- `degrees()` and `radians()` are deferred until after `1.0.0`.

See the
[selected compatibility matrix](https://github.com/Imagination12357/PyChelonia/blob/main/docs/compatibility-matrix.md)
and
[known differences from Python Turtle](https://github.com/Imagination12357/PyChelonia/blob/main/docs/known-differences.md)
for exact behavior and test evidence.

## Example

The looping
[README showcase](https://github.com/Imagination12357/PyChelonia/blob/main/examples/readme_showcase.py)
focuses on visual Surface composition:

```bash
uv run python examples/readme_showcase.py
```

The original
[interactive timer demo](https://github.com/Imagination12357/PyChelonia/blob/main/examples/pychelonia_demo.py)
shows real-time redraw and rotation without manual matrix calculations:

```bash
uv run python examples/pychelonia_demo.py
```

Both demos open a pygame window and are manual visual examples. Regenerate the
README animation without opening a window:

```bash
uv run --with pillow python tools/render_readme_gif.py
```

## Development

Run the smoke check and test suite from a checkout:

```bash
uv run python main.py
uv run --extra dev pytest
```

The automated suite uses in-memory pygame surfaces and must not create an
application window.

## Support

Review the compatibility matrix and known differences before reporting a
problem. Bugs and focused compatibility requests can be filed in
[GitHub Issues](https://github.com/Imagination12357/PyChelonia/issues).
Include the Python and pygame versions, a minimal reproduction, and whether
the Surface uses per-pixel alpha.

## License and Maintainer

PyChelonia is maintained by
[@imagination12357](https://github.com/Imagination12357) and distributed under
the [MIT License](https://github.com/Imagination12357/PyChelonia/blob/main/LICENSE).
