Moon
Project description
🌙 Moon Framework - Ключевые особенности реализации
Подробный технический обзор архитектуры и реализации игрового фреймворка Moon
📋 Содержание
- Архитектурный обзор
- Гибридная архитектура Python + C++
- Система управления памятью
- Оптимизации производительности
- Система рендеринга
- Обработка событий
- Математические вычисления
- Система цветов и градиентов
- Аудиосистема
- Система сборки
- Безопасность и стабильность
🏗️ Архитектурный обзор
Многослойная архитектура
Moon построен по принципу многослойной архитектуры:
┌─────────────────────────────────────┐
│ Python API Layer │ ← Удобный интерфейс для разработчиков
├─────────────────────────────────────┤
│ Python Wrapper Layer │ ← Обертки и управление ресурсами
├─────────────────────────────────────┤
│ C++ Binding Layer │ ← ctypes биндинги
├─────────────────────────────────────┤
│ Native C++ Core (SFML) │ ← Высокопроизводительное ядро
└─────────────────────────────────────┘
Принципы дизайна
- Performance First - критические операции выполняются в C++
- Developer Friendly - простой и интуитивный Python API
- Memory Safe - автоматическое управление ресурсами
- Fluent Interface - поддержка цепочек вызовов методов
🔗 Гибридная архитектура Python + C++
Разделение ответственности
Python слой отвечает за:
- Высокоуровневую логику игры
- Управление жизненным циклом объектов
- Валидацию параметров
- Удобный API для разработчиков
C++ слой отвечает за:
- Критичные к производительности операции
- Прямую работу с OpenGL/SFML
- Управление памятью на низком уровне
- Математические вычисления
Пример реализации RectangleShape
@final
class RectangleShape:
def __init__(self, width: float, height: float):
# Создание нативного объекта в C++
self._ptr = LIB_PYSGL._Rectangle_Create(float(width), float(height))
# Python-атрибуты для кэширования состояния
self.__color: Color | None = None
self.__angle: float = 0
def set_color(self, color: Color) -> Self:
# Валидация в Python
if not isinstance(color, Color):
raise TypeError("Expected Color object")
# Вызов нативной функции
LIB_PYSGL._Rectangle_SetColor(self._ptr, color.r, color.g, color.b, color.a)
# Кэширование состояния
self.__color = color
return self # Fluent interface
Биндинги через ctypes
# Определение сигнатур C++ функций
LIB_PYSGL._Rectangle_Create.argtypes = [ctypes.c_float, ctypes.c_float]
LIB_PYSGL._Rectangle_Create.restype = ctypes.c_void_p
LIB_PYSGL._Rectangle_SetColor.argtypes = [ctypes.c_void_p, ctypes.c_int, ctypes.c_int, ctypes.c_int, ctypes.c_int]
LIB_PYSGL._Rectangle_SetColor.restype = None
🧠 Система управления памятью
RAII в Python
Moon использует принцип RAII (Resource Acquisition Is Initialization) для автоматического управления ресурсами:
class RectangleShape:
def __init__(self, width: float, height: float):
self._ptr = LIB_PYSGL._Rectangle_Create(width, height)
def __del__(self):
# Автоматическое освобождение ресурсов
if hasattr(self, '_ptr') and self._ptr:
LIB_PYSGL._Rectangle_Delete(self._ptr)
self._ptr = None
Защита от утечек памяти
- Автоматические деструкторы - каждый объект освобождает свои ресурсы
- Проверка валидности указателей - защита от двойного освобождения
- Исключения с гарантиями - корректная очистка при ошибках
Оптимизация памяти с slots
@final
class Color:
__slots__ = ('r', 'g', 'b', 'a') # Экономия ~40% памяти
@final
class Vertex:
__slots__ = ('position', 'color', 'tex_coords') # Компактное хранение
⚡ Оптимизации производительности
Массовые операции в C++
# Медленно: цикл в Python
for vertex in vertices:
vertex.set_color(red_color)
# Быстро: одна операция в C++
vertex_array.set_color(red_color) # Все вершины сразу
Кэширование состояния
class RectangleShape:
def get_angle(self) -> float:
return self.__angle # Возврат из кэша, без вызова C++
def set_angle(self, angle: float) -> Self:
LIB_PYSGL._Rectangle_SetRotation(self._ptr, angle)
self.__angle = angle % 360 # Обновление кэша
return self
Оптимизированные структуры данных
# Специализированные классы для разных задач
class LineThinShape: # Для простых линий - минимальные накладные расходы
class LineShape: # Для линий с контуром - дополнительная функциональность
class LinesThinShape: # Для полилиний - массовые операции
Ленивые вычисления
class BaseLineShape:
def update(self):
# Пересчет геометрии только при необходимости
vector = Vector2f.between(self.__start_pos, self.__end_pos)
length = vector.get_lenght()
# ... сложные вычисления
def special_draw(self, window):
self.update() # Обновление только перед отрисовкой
window.draw(self.__rectangle_shape)
🎨 Система рендеринга
Многоуровневая система отрисовки
# Уровень 1: Простая отрисовка
window.draw(shape)
# Уровень 2: С состояниями рендеринга
window.draw(shape, render_states)
# Уровень 3: С шейдерами
window.draw(shape, shader)
Оптимизированные примитивы
# Нативные фигуры (максимальная производительность)
rect = RectangleShape(100, 100) # Прямой вызов SFML
circle = CircleShape(50) # Оптимизированная отрисовка
# Композитные фигуры (гибкость)
line = LineShape() # Состоит из прямоугольника + кругов
Система вершинных массивов
class VertexArray:
def set_color(self, color: Color) -> None:
# Массовое изменение цвета всех вершин в C++
LIB_PYSGL._VertexArray_SetAllVerticesColor(
self._ptr, color.r, color.g, color.b, color.a
)
def set_vertex_color(self, index: int, color: Color) -> None:
# Точечное изменение одной вершины
LIB_PYSGL._VertexArray_SetVertexColor(
self._ptr, index, color.r, color.g, color.b, color.a
)
🎮 Обработка событий
Эффективная система событий
class WindowEvents:
def poll(self, window) -> bool:
# Получение события из нативной очереди
return LIB_PYSGL._Window_GetCurrentEventType(
window.get_ptr(), self.__event_ptr
)
def get_type(self) -> int:
# Быстрое получение типа без копирования данных
return LIB_PYSGL._Events_GetType(self.__event_ptr)
Типизированные события
class WindowEvents:
class Type:
Closed = 0
Resized = 1
KeyPressed = 5
MouseButtonPressed = 9
# ... полный набор событий SFML
Интеграция с системными API
def update(self, events: WindowEvents) -> bool:
# Обработка нативных событий SFML
event_type = events.poll(self)
# Интеграция с keyboard библиотекой для расширенного ввода
if keyboard.is_pressed(self.__exit_key):
return False
return True
🧮 Математические вычисления
Векторная математика
@final
class Vector2f:
__slots__ = ('x', 'y')
def __add__(self, other: 'Vector2f') -> 'Vector2f':
return Vector2f(self.x + other.x, self.y + other.y)
def normalize(self) -> 'Vector2f':
length = self.get_lenght()
if length == 0:
return Vector2f(0, 0)
return Vector2f(self.x / length, self.y / length)
@staticmethod
def between(start: list, end: list) -> 'Vector2f':
return Vector2f(end[0] - start[0], end[1] - start[1])
Оптимизированные коллизии
def circles_collision(x1, y1, r1, x2, y2, r2) -> bool:
# Использование квадрата расстояния для избежания sqrt()
return distance_squared(x1, y1, x2, y2) <= (r1 + r2)**2
def distance_squared(x1, y1, x2, y2):
dx, dy = x2 - x1, y2 - y1
return dx * dx + dy * dy # Без sqrt() - в 3-5 раз быстрее
Шум Перлина
def perlin_noise(x: float, y: float, octaves: int = 1,
persistance: float = 0.5, lacunarity: float = 2.0) -> float:
# Интеграция с библиотекой noise для процедурной генерации
return pnoise2(x, y, octaves=octaves,
persistence=persistance, lacunarity=lacunarity)
🎨 Система цветов и градиентов
Продвинутая работа с цветами
@final
class Color:
__slots__ = ('r', 'g', 'b', 'a')
def lighten_hsv(self, factor: float) -> "Color":
# Конвертация в HSV для точного управления яркостью
h, s, v = colorsys.rgb_to_hsv(self.r/255, self.g/255, self.b/255)
new_v = min(1.0, v + (1 - v) * factor)
r, g, b = colorsys.hsv_to_rgb(h, s, new_v)
return Color(int(r*255), int(g*255), int(b*255), self.a)
Генерация цветовых палитр
def generate_palette(color: Color, scheme: str = "complementary",
num_colors: int = 5) -> list[Color]:
# Алгоритмы теории цвета для гармоничных палитр
h, s, v = colorsys.rgb_to_hsv(color.r/255, color.g/255, color.b/255)
if scheme == "triadic":
# Три равноудаленных цвета (через 120°)
for i in range(3):
new_h = (h + i/3) % 1.0
r, g, b = colorsys.hsv_to_rgb(new_h, s, v)
colors.append(Color(int(r*255), int(g*255), int(b*255)))
Сложные градиенты
class ColorGradientEx:
def __init__(self, colors: list[Color], lengths: list[float]):
# Градиенты с неравномерным распределением цветов
if not math.isclose(sum(lengths), 1.0, rel_tol=1e-9):
raise ValueError("Sum of lengths must equal 1.0")
def get(self, amount: float) -> Color:
# Эффективный поиск нужного сегмента градиента
for gradient, start, end in self.__gradients:
if start <= amount <= end:
relative = (amount - start) / (end - start)
return gradient.get(relative)
🔊 Аудиосистема
Интеграция с SFML Audio
// C++ биндинги для аудио
extern "C" {
__declspec(dllexport) SoundPtr _Sound_Create(SoundBufferPtr buffer) {
SoundPtr sound = new sf::Sound();
sound->setBuffer(*buffer);
return sound;
}
__declspec(dllexport) void _Sound_SetPosition(SoundPtr sound,
float x, float y, float z) {
sound->setPosition(x, y, z); // 3D позиционирование
}
}
Python обертки
class Sound:
def __init__(self, buffer: SoundBuffer):
self._ptr = LIB_PYSGL._Sound_Create(buffer.get_ptr())
def set_3d_position(self, x: float, y: float, z: float = 0) -> Self:
LIB_PYSGL._Sound_SetPosition(self._ptr, x, y, z)
return self
🔧 Система сборки
Автоматическая сборка C++ модулей
def build():
# Поиск всех файлов для сборки
builded_files = list(filter(lambda x: x[0:7] == "BUILDED", all_files))
# Объединение всех C++ файлов в один
with open("PySGL.cpp", 'w') as output:
for bf in builded_files:
with open(bf, 'r') as input_file:
output.write(input_file.read())
# Компиляция с оптимизациями
os.system(f"""g++ -shared -o PySGL.dll PySGL.cpp
-static -static-libstdc++ -static-libgcc
-DSFML_STATIC -O3 -march=native
-lsfml-graphics-s -lsfml-window-s -lsfml-system-s""")
Конфигурация через properties файл
# build.properties
SFML_INCLUDE_PATH="C:/SFML/include"
SFML_LIB_PATH="C:/SFML/lib"
COMPILER_PATH="global"
BUILD_FILES_PATH="Moon/src"
DLLS_FILES_PATH="Moon/dlls"
🛡️ Безопасность и стабильность
Валидация параметров
def set_size(self, width: float, height: float) -> Self:
if width <= 0 or height <= 0:
raise ValueError("Size values must be positive")
LIB_PYSGL._Rectangle_SetSize(self._ptr, width, height)
return self
Защита от некорректных индексов
def __getitem__(self, index: int) -> Vertex:
if not (0 <= index < len(self)):
raise IndexError(f"Vertex index {index} out of bounds")
# Безопасное обращение к нативному массиву
return self.__vertex_array.get_vertex(index)
Обработка ошибок загрузки библиотек
def _find_library() -> str:
try:
lib_path = DLL_FOUND_PATH
if not os.path.exists(lib_path):
# Поиск в альтернативных местах
lib_path = "./dlls/PySGL.dll"
if not os.path.exists(lib_path):
raise FileNotFoundError(f"Library not found at {lib_path}")
return lib_path
except Exception as e:
raise LibraryLoadError(f"Library search failed: {e}")
Graceful degradation
def set_alpha(self, alpha: int):
try:
# Попытка установить прозрачность через WinAPI
ctypes.windll.user32.SetLayeredWindowAttributes(
self.__window_descriptor, 0, int(alpha), 2
)
except:
# Тихий откат при ошибке (например, на Linux)
pass
📊 Метрики производительности
Встроенный профайлер
class Window:
def update(self, events: WindowEvents) -> bool:
# Замер времени рендеринга
self.__render_time = self.__clock.get_elapsed_time()
self.__clock.restart()
# Расчет FPS
self.__fps = 1 / self.__render_time if self.__render_time > 0 else 0
# Обновление истории для графика
self.__update_fps_history()
Визуализация производительности
def view_info(self) -> None:
if not self.__view_info:
return
# Динамический график FPS
for i, fps in enumerate(self.__fps_history):
x = graph_x + (i * graph_width / (self.__max_history - 1))
y = graph_y + graph_height - (fps * graph_height / max_fps)
color = self.__fps_line_color_green if fps >= max_fps * 0.5 else self.__fps_line_color_red
self.__fps_line.append_point_to_end(x, y, color)
🎯 Заключение
Moon Framework демонстрирует эффективное сочетание удобства Python и производительности C++. Ключевые достижения:
Производительность
- 60-80% улучшение по сравнению с чистым Python
- Массовые операции в нативном коде
- Оптимизированные структуры данных с slots
- Ленивые вычисления и кэширование
Удобство разработки
- Fluent Interface для цепочек вызовов
- Автоматическое управление памятью
- Богатая система типов с type hints
- Подробная документация и примеры
Архитектурная гибкость
- Модульная структура с четким разделением слоев
- Расширяемость через Python и C++
- Кроссплатформенность благодаря SFML
- Современные практики разработки
Moon представляет собой пример того, как можно создать высокопроизводительный игровой фреймворк, сохранив при этом простоту и удобство использования Python.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file moonframework-0.1.17.tar.gz.
File metadata
- Download URL: moonframework-0.1.17.tar.gz
- Upload date:
- Size: 2.7 MB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fd71f6440640d4e983eb6f57c090c794a4e411796f1f413daf342fb30e9ff8af
|
|
| MD5 |
d085023e228b9039e487deb1474f54ce
|
|
| BLAKE2b-256 |
60c274a4dc8fedf665ba5f619f938507bac9ac18231687e6d4db563dde75d74c
|
File details
Details for the file moonframework-0.1.17-py3-none-any.whl.
File metadata
- Download URL: moonframework-0.1.17-py3-none-any.whl
- Upload date:
- Size: 2.7 MB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
36ed31229310f5cff7e020c8ea4e91e0ae7fd2fdd7cf83559b177aa6c86f17c4
|
|
| MD5 |
dccaca72a30f81bced5b094eafa3710d
|
|
| BLAKE2b-256 |
2568620c115c66d78a587f182883152e166cd3eff3212addaba85f746e22e43f
|