Skip to content

Commit d752db7

Browse files
committed
v3.1.1
1 parent 2707ac1 commit d752db7

52 files changed

Lines changed: 491 additions & 145 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CHANGELOG.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,22 @@
55
Формат основан на [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
и этот проект придерживается [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [3.1.1]
9+
10+
### Added
11+
- **Project template paths**`spritePro.cli --create` теперь создаёт `config.py` с готовыми путями `PROJECT_ROOT`, `ASSETS_DIR`, `AUDIO_DIR`, `IMAGES_DIR`, `SCENES_DIR` и `MAIN_LEVEL_PATH`, чтобы в новых проектах не нужно было каждый раз вручную собирать `Path(__file__).resolve()...`.
12+
- **Project template events file** — в шаблон добавлен `game_events.py` с базовым событием `game_started`, подпиской через `s.events.connect(...)`, отправкой через `s.events.get_event(...).send(...)` и логом через `s.debug_log_info(...)`.
13+
14+
### Changed
15+
- **Project template structure** — шаблон `--create` по умолчанию создаёт `main.py`, `config.py`, `game_events.py`, `scenes/main_scene.py`, `scenes/second_scene.py` и `scenes/main_level.json`. Вторая сцена остаётся почти пустой заготовкой для меню, паузы, магазина или другого уровня.
16+
- **Multiplayer entrypoint** — рекомендации, demoGames и `multiplayer_course` обновлены под единый app-level запуск через `s.run(..., multiplayer=True)`, а `s.networking.run(...)` оставлен как low-level runner.
17+
- **Версия библиотеки** — релиз обновлён до `3.1.1`.
18+
19+
### Fixed
20+
- **Editor runtime image sizing** — runtime-сцены, созданные в редакторе, снова корректно подхватывают размер image-объектов в embedded/Kivy-сценариях вместо fallback-белого прямоугольника.
21+
22+
---
23+
824
## [3.1.0]
925

1026
### Added

DOCUMENTATION_INDEX.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -427,6 +427,7 @@
427427
## 🔄 Обновления документации
428428

429429
### Последние обновления
430+
- **2026-03 (v3.1.1)**: Обновлены шаблон `spritePro.cli --create`, multiplayer docs и курс: в шаблон добавлены `config.py` с путями к проекту/ассетам, `game_events.py` с базовым событием через `EventBus`, а multiplayer-примеры переведены на единый запуск через `s.run(..., multiplayer=True)`. Обновлены [README.md](README.md), [docs/game_loop.md](docs/game_loop.md), [docs/networking.md](docs/networking.md), [multiplayer_course/README.md](multiplayer_course/README.md).
430431
- **2026-03 (v3.1.0)**: Добавлена документация по виртуальному разрешению `reference_size`: как запускать игру в маленьком окне, но держать `s.WH`, `s.WH_C`, UI, камеру и input в координатах большого логического экрана. Обновлены [README.md](README.md) и [docs/game_loop.md](docs/game_loop.md).
431432
- **2026-03 (v3.0.3)**: Обновлена mobile/Android-документация: добавлены рекомендации по preview на компактных окнах, описаны режимы ориентации `landscape`, `portrait`, `auto` для APK, уточнён workflow проверки layout на разных экранах. Обновлены [README.md](README.md), [docs/building.md](docs/building.md), [docs/mobile.md](docs/mobile.md).
432433
- **2026-03 (v3.0.2)**: Android/APK-документация уточнена по реально проверенному запуску после сборки: добавлены рекомендации по `adb logcat`, проверке ранних Python traceback и по явному включению свежего локального `spritePro` в проект игры, если тестируются непубликованные фиксы. Обновлены [README.md](README.md), [docs/building.md](docs/building.md), [docs/mobile.md](docs/mobile.md), [docs/kivy_hybrid.md](docs/kivy_hybrid.md).

README.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ s.run(
142142
-**Автолейаут (Layout)** - flex, сетка, круг, линия для автоматического размещения дочерних спрайтов ([документация](docs/layout.md))
143143
-**ScrollView** — скроллируемая область для контента (лейаут), колёсико и перетаскивание мышью, опциональная маска (клиппинг по viewport)
144144
-**Готовые сцены (readyScenes)** — подключаемые сцены: **ChatScene** (мультиплеерный чат с историей, скроллом и маской) и **ChatStyle** для настройки оформления
145-
-**Мультиплеер** — сетевые игры: TCP relay, контекст (send/poll/send_every), EventBus; быстрый старт через `s.networking.run()`. **Готовое лобби** (`run(use_lobby=True)`): один экран — имя, хост/клиент, порт, IP, список игроков; у хоста кнопки «В игру» и «Назад», у клиента — «Назад». По нажатию «В игру» игра запускается у обоих. Подробно: [Networking — лобби](docs/networking.md#подробная-инструкция-лобби-use_lobbytrue). Мини-курс в папке `multiplayer_course/` — 10 уроков от обмена сообщениями до готовой мини-игры.
145+
-**Мультиплеер** — сетевые игры: TCP relay, контекст (send/poll/send_every), EventBus; теперь можно запускать прямо через `s.run(..., multiplayer=True)` без отдельного `multiplayer_main`-runner, а `s.networking.run()` оставлен как low-level вариант. **Готовое лобби** (`s.run(..., multiplayer_use_lobby=True)`): один экран — имя, хост/клиент, порт, IP, список игроков; у хоста кнопки «В игру» и «Назад», у клиента — «Назад». По нажатию «В игру» игра запускается у обоих. Подробно: [Networking — лобби](docs/networking.md#подробная-инструкция-лобби-use_lobbytrue). Мини-курс в папке `multiplayer_course/` — 10 уроков от обмена сообщениями до готовой мини-игры.
146146
-**Mobile-рантайм** — запуск через `Kivy`: `s.run(..., platform="kivy")`, встроенный host для touch-ввода и мобильных demo
147147

148148
---
@@ -233,9 +233,13 @@ python -m spritePro.cli --create
233233
Шаблон теперь сразу современный:
234234

235235
- `main.py` запускает игру через `s.run(...)`
236-
- `scenes/main_scene.py` — основная сцена, которая грузит `scenes/main_level.json`
236+
- `config.py` — общие настройки игры и готовые пути `PROJECT_ROOT`, `ASSETS_DIR`, `AUDIO_DIR`, `IMAGES_DIR`, `SCENES_DIR`, `GAME_DIR`, `DOMAIN_DIR`, `SERVICES_DIR`
237+
- `game_events.py` — базовый файл для `EventBus`: событие старта игры, подписка и лог
238+
- `scenes/main_scene.py` — основная сцена, которая грузит `config.MAIN_LEVEL_PATH`
237239
- `scenes/second_scene.py` — вторая почти пустая сцена-заготовка, чтобы было удобно расширять проект
238240
- `scenes/main_level.json` — стартовый уровень в формате Sprite Editor
241+
- `game/domain/game_state.py` — пример domain-модели
242+
- `game/services/game_service.py` — пример сервиса для игровой логики
239243

240244
То есть новый проект после `--create` уже показывает нормальную scene-based структуру, а не только один файл с ручным циклом.
241245

docs/OVERVIEW.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ TCP + JSON‑сообщения формата `{"event": "...", "data": {...}}`
8787

8888
- **NetServer** — TCP relay (пересылает сообщения всем клиентам)
8989
- **NetClient** — клиент с `send()` и `poll()`
90-
- **s.networking.run()** — единая точка входа с разными режимами
90+
- **s.run(..., multiplayer=True)**рекомендуемая единая точка входа для современных multiplayer-игр; `s.networking.run()` оставлен как low-level runner
9191

9292
### Режимы запуска
9393

docs/game_loop.md

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,23 @@
88
python -m spritePro.cli --create MyGame
99
```
1010

11-
Шаблон создаёт `main.py`, `scenes/main_scene.py`, `scenes/second_scene.py` и `scenes/main_level.json`.
11+
Шаблон создаёт:
12+
13+
- `main.py`
14+
- `config.py`
15+
- `game_events.py`
16+
- `game/domain/game_state.py`
17+
- `game/services/game_service.py`
18+
- `scenes/main_scene.py`
19+
- `scenes/second_scene.py`
20+
- `scenes/main_level.json`
21+
22+
В шаблоне уже есть:
23+
24+
- две сцены: основная и почти пустая вторая сцена-заготовка
25+
- готовые пути к проекту, сценам, domain и services в `config.py`
26+
- базовый `EventBus`-файл с событием старта игры и логом через `s.debug_log_info(...)`
27+
- разделение структуры: `scenes/` для сцен, `game/domain/` для моделей, `game/services/` для игровой логики
1228

1329
```python
1430
import spritePro as s

docs/networking.md

Lines changed: 62 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,58 @@ TCP‑клиент, который отправляет сообщения и п
4242
- `poll(max_messages=100)` — забирает входящие сообщения.
4343
- `close()` — закрывает соединение.
4444

45-
### s.networking.run(...)
45+
### Рекомендуемый запуск: `s.run(..., multiplayer=True)`
46+
47+
Для новых игр удобнее использовать один вход через `s.run(...)`, а multiplayer
48+
включать флагом `multiplayer=True`.
49+
50+
```python
51+
import spritePro as s
52+
53+
54+
class MultiplayerScene(s.Scene):
55+
def __init__(self, net: s.NetClient, role: str):
56+
super().__init__()
57+
s.multiplayer.init_context(net, role)
58+
self.ctx = s.multiplayer_ctx
59+
self.me = s.Sprite("", (40, 40), (200, 300), scene=self)
60+
self.me.set_color((220, 70, 70) if self.ctx.is_host else (70, 120, 220))
61+
62+
def update(self, dt):
63+
pos = self.me.get_world_position()
64+
self.ctx.send_every("pos", {"pos": list(pos)}, 1.0 / 60.0)
65+
66+
67+
if __name__ == "__main__":
68+
s.run(
69+
scene=MultiplayerScene,
70+
size=(800, 600),
71+
title="My Multiplayer",
72+
fps=60,
73+
fill_color=(20, 20, 25),
74+
multiplayer=True,
75+
)
76+
```
77+
78+
Что это даёт:
79+
80+
- один и тот же `s.run(...)` для singleplayer и multiplayer
81+
- `scene` и `setup` могут принимать `net` и `role`, если они нужны
82+
- те же terminal-аргументы `--quick`, `--server`, `--host_mode`, `--host`, `--port`, `--clients` работают без отдельного вызова `s.networking.run(...)`
83+
- `--kivy` и `--pygame` тоже можно передавать в тот же запуск
84+
85+
Если нужен quick-режим на 3 окна прямо из кода:
86+
87+
```python
88+
s.run(
89+
scene=MultiplayerScene,
90+
multiplayer=True,
91+
multiplayer_clients=3,
92+
multiplayer_client_spawn_delay=2,
93+
)
94+
```
95+
96+
### Низкоуровневый запуск: `s.networking.run(...)`
4697

4798
Утилита запуска для быстрого мультиплеера с автозапуском клиента/серверов.
4899

@@ -60,7 +111,7 @@ s.networking.run(
60111
```
61112

62113
- **По умолчанию** (`use_lobby=False`): без аргументов запускается быстрый режим (два окна — хост и клиент). Удобно для разработки.
63-
- **С лобби** (`use_lobby=True`): одно окно. Сначала экран настройки: имя, выбор «Хост» / «Клиент», порт (и для клиента — IP). После подключения — список игроков (roster). У хоста: кнопки «Назад» и «В игру»; у клиента: кнопка «Назад». «Назад» отключает соединение и возвращает к настройке. По нажатию «В игру» вызывается ваша `multiplayer_main(net, role)`. Для готового приложения достаточно заменить вызов на `s.networking.run(use_lobby=True)`.
114+
- **С лобби** (`use_lobby=True`): одно окно. Сначала экран настройки: имя, выбор «Хост» / «Клиент», порт (и для клиента — IP). После подключения — список игроков (roster). У хоста: кнопки «Назад» и «В игру»; у клиента: кнопка «Назад». «Назад» отключает соединение и возвращает к настройке. По нажатию «В игру» вызывается ваша `multiplayer_main(net, role)`. Для нового кода удобнее использовать `s.run(..., multiplayer=True, multiplayer_use_lobby=True)`, а `s.networking.run(use_lobby=True)` оставить как low-level вариант.
64115

65116
Важно: `run()` нужно вызывать из файла, а не из REPL.
66117

@@ -152,9 +203,9 @@ while True:
152203
other.set_position(remote_pos)
153204
```
154205

155-
## Интеграция через s.networking.run()
206+
## Интеграция через `s.networking.run()`
156207

157-
Создайте функцию входа и вызовите `run()`:
208+
Если нужен старый или более явный low-level flow, можно оставить отдельную entry-функцию:
158209

159210
```python
160211
import pygame
@@ -201,7 +252,11 @@ s.networking.run(entry="module:function")
201252

202253
```python
203254
if __name__ == "__main__":
204-
s.networking.run(use_lobby=True)
255+
s.run(
256+
multiplayer=True,
257+
multiplayer_entry=multiplayer_main,
258+
multiplayer_use_lobby=True,
259+
)
205260
```
206261

207262
Либо запустите демо с флагом:
@@ -241,7 +296,7 @@ s.get_screen((480, 540), "Лобби")
241296
run_multiplayer_lobby(lambda net, role: your_multiplayer_main(net, role))
242297
```
243298

244-
Если сама игра уже переведена на `s.run(...)`, обычно проще оставить это внутри `your_multiplayer_main(net, role)` и считать `run_multiplayer_lobby(...)` только экраном подключения.
299+
Если игра уже запускается через `s.run(...)`, то для нового кода обычно удобнее перейти на `s.run(..., multiplayer=True)` и использовать `s.networking.run(...)` только как низкоуровневый runner.
245300

246301
- **Константа события:** `from spritePro.readyScenes import EVENT_START_GAME` — имя события `"start_game"` для согласования с своей логикой.
247302

@@ -361,7 +416,7 @@ def multiplayer_main(net: s.NetClient, role: str):
361416
# ctx.send("ready", {...})
362417
# for msg in ctx.poll(): ...
363418

364-
s.networking.run()
419+
s.run(multiplayer=True, multiplayer_entry=multiplayer_main)
365420
```
366421

367422
### Кто такой «этот процесс» (наш компьютер)

docs/readySprites.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ Ready Sprites are pre-configured sprite classes that solve common game developme
2222

2323
```python
2424
# Через run() — одно окно с лобби, затем ваша игра
25-
s.networking.run(use_lobby=True)
25+
s.run(multiplayer=True, multiplayer_entry=your_multiplayer_main, multiplayer_use_lobby=True)
2626
```
2727

2828
```python

multiplayer_course/10/example_routing.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,4 +80,4 @@ def multiplayer_main(net: s.NetClient, role: str) -> None:
8080

8181

8282
if __name__ == "__main__":
83-
s.networking.run(entry="multiplayer_main")
83+
s.run(multiplayer=True, multiplayer_entry=multiplayer_main)

multiplayer_course/10/lesson.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
В EventBus и при прямой отправке через контекст можно разделять **куда** уходит сообщение.
1919

2020
Этот урок остаётся low-level по смыслу: он про роутинг событий, а не про UI/сцены.
21-
Но сам пример ниже тоже можно удобно запускать через `s.networking.run(...)` и `s.run(...)`,
21+
Но сам пример ниже тоже можно удобно запускать через `s.run(..., multiplayer=True)` и `s.run(...)`,
2222
чтобы курс не расходился со стилем `SpritePro 3.x`.
2323

2424
### Варианты роутинга (EventBus: `route=...`)

multiplayer_course/10/practice_routing.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,4 +62,4 @@ def multiplayer_main(net: s.NetClient, role: str) -> None:
6262

6363

6464
if __name__ == "__main__":
65-
s.networking.run(entry="multiplayer_main")
65+
s.run(multiplayer=True, multiplayer_entry=multiplayer_main)

0 commit comments

Comments
 (0)