High-performance creative engine (Win32/OpenGL/Python)
Project description
jwarol
Движок на C++ для 2D-игр на Python. Win32 API + сырой OpenGL (X11 на Linux). Рендеринг, шейдеры, текстуры, физика, звук .wav, игровые объекты, шифрование ассетов, скелетная анимация из Blender, сборка в .exe через PyInstaller.
Возможности
| Функция | Описание |
|---|---|
| Window | Окно с OpenGL-контекстом (Win32 / X11) + glViewport |
| Shader | GLSL-шейдеры из строк/файлов, проверка ошибок, move-семантика |
| Renderer | 2D-рендеринг с ортографической проекцией, камерой, culling |
| Texture | PNG/JPG/BMP (WIC), процедурные, наложение, шифрование |
| Input | Клавиатурный ввод (Win32 GetAsyncKeyState / X11 XQueryKeymap) |
| Camera | Следование за объектом, zoom, smooth-интерполяция |
| Sprite/Animation | Спрайт-листы, покадровая анимация |
| DetailGroup | Батч-рендеринг тысяч объектов за 1 draw call |
| AnimatedSprite2D | Скелетная 2D-анимация из Blender |
| Physics | Verlet-интеграция, гравитация, коллизии, STATIC/DYNAMIC/KINEMATIC |
| Sound | .wav через winmm (Windows) |
| GameObjects | Object, Player, Character, GUI, Detail с рабочими draw/update |
| PyInstaller Build | Сборка игры в .exe |
Установка
pip install jwarol
Сборка из исходников
python setup.py build
Быстрый старт
import jwarol as jl
win = jl.Window(800, 600, "Hello jwarol")
renderer = jl.Renderer(800, 600)
while win.is_open:
win.poll_events()
win.clear(0.1, 0.1, 0.2)
renderer.draw_rect(100, 100, 200, 150, 1.0, 0.3, 0.5)
renderer.draw_rect(350, 200, 100, 100, 0.2, 0.7, 1.0)
win.swap_buffers()
Текстуры
tex = jl.Texture("sprite.png")
# Процедурная текстура
w, h = 64, 64
pixels = bytearray()
for y in range(h):
for x in range(w):
pixels.extend([255, 0, 0, 255])
tex = jl.Texture(w, h, bytes(pixels), 4)
renderer.draw_texture(tex, 100, 100, 200, 200, alpha=0.5)
renderer.draw_texture_ex(tileset, 0, 0, 32, 32, 0, 0, 32, 32)
# Загрузка всех текстур из папки
textures = jl.Texture.load_all("assets/textures/")
# Наложение
combined = tex.overlay(other_tex, 10, 10, alpha=0.7)
Физика
world = jl.World()
world.gravity = 980.0
body = world.add_body(300, 0, 50, 50, jl.BodyType.DYNAMIC)
static = world.add_body(0, 650, 800, 50, jl.BodyType.STATIC)
# STATIC-тела не двигаются при коллизиях
world.step(dt)
x, y = body.pos.x, body.pos.y
Ввод и время
input = jl.Input()
clock = jl.Clock()
while win.is_open:
dt = clock.tick()
input.update()
if input.is_down(ord('W')): pass
if input.is_pressed(ord(' ')): pass
if input.is_released(ord('A')): pass
Шейдеры
shader = jl.Shader("#version 330 core\n...", "#version 330 core\n...")
shader.use()
shader = jl.Shader.from_file("vertex.glsl", "fragment.glsl")
shader = jl.Shader.from_single_file("shader.glsl")
# Ошибки компиляции → RuntimeError с логом
try:
s = jl.Shader.from_file("bad.glsl", "empty.glsl")
except RuntimeError as e:
print("Shader error:", e)
Камера
cam = jl.Camera(800, 600)
cam.follow(player)
cam.smooth = 0.1
cam.zoom = 2.0 # приближение
cam.update(dt)
cam.apply_to(renderer)
Спрайты и анимация
sheet = jl.Texture("player_walk.png")
sprite = jl.Sprite()
sprite.set_texture(sheet, 4, 2)
anim = jl.Animation()
anim.from_range(0, 3)
anim.speed = 0.1
anim.loop = True
sprite.set_animation(anim)
sprite.update(dt)
sprite.draw_at(renderer, player.x, player.y, 64, 64)
Группа деталей (DetailGroup)
details = jl.DetailGroup()
details.add(100, 200, 32, 32, 1.0, 0.5, 0.0, 0.8)
tileset = jl.Texture("tileset.png")
details.set_texture(tileset, 4, 4)
details.add_frame(100, 100, 32, 32, 0, 0)
details.set_max_distance(500)
details.draw(cam.x, cam.y, 800, 600)
Скелетная анимация (AnimatedSprite2D)
hero = jl.AnimatedSprite2D.from_blender("character.json", "character.png")
hero.play("idle")
hero.anim_loop = True
while win.is_open:
dt = clock.tick()
hero.update(dt)
hero.draw(renderer, player.x, player.y, scale=1.0)
Программное создание скелета
skel = jl.SkeletonData()
skel.add_bone("root")
skel.add_bone("body", 0)
skel.add_bone("head", 1)
skel.add_bone("arm_l", 1)
skel.add_bone("arm_r", 1)
skel.bones[1].y = -30
skel.bones[2].y = -30
skel.bones[3].x = -20
skel.bones[4].x = 20
walk = jl.SkeletalAnimation()
walk.name = "walk"
walk.duration = 1.0
walk.loop = True
track = jl.BoneTrack()
track.bone_index = 3
kf1 = jl.BoneKeyframe(); kf1.time = 0.0; kf1.rotation = -30
kf2 = jl.BoneKeyframe(); kf2.time = 0.5; kf2.rotation = 30
kf3 = jl.BoneKeyframe(); kf3.time = 1.0; kf3.rotation = -30
track.keyframes = [kf1, kf2, kf3]
walk.tracks = [track]
sprite = jl.AnimatedSprite2D()
sprite.skeleton = skel
sprite.add_animation(walk)
sprite.set_texture(jl.Texture("character.png"))
sprite.play("walk")
# В цикле:
sprite.update(dt)
sprite.draw(renderer, x, y)
Игровые объекты
obj = jl.Object(100, 100, 64, 64)
obj.active = True
obj.set_texture(texture)
player = jl.Player(400, 300, 32, 32)
player.speed = 250.0
char = jl.Character(200, 200, 32, 48)
char.hp = 100
gui = jl.GUI(10, 10, 200, 30)
gui.text = "Score: 0"
detail = jl.Detail(500, 400, 16, 16)
detail.alpha = 0.5
Шифрование текстур
jl.Texture.encrypt("sprite.png", "my_secret_key")
tex = jl.Texture.load_encrypted("sprite.png.enc", "my_secret_key")
# Расшифровка в памяти, без временного файла
Сборка в .exe (PyInstaller)
python build_exe.py game.py
python build_exe.py game.py --onefile --icon icon.ico --name "MyGame"
python build_exe.py game.py --assets assets/ --console
Результат в папке dist/.
Структура проекта
jwarol/
├── include/ # C++ заголовки
│ ├── Window.hpp # Окно (Win32 / X11)
│ ├── Shader.hpp # GLSL-шейдеры (move-семантика, деструктор)
│ ├── Renderer.hpp # 2D-рендерер (ортографическая проекция)
│ ├── Texture.hpp # Текстуры (PNG/JPG/BMP/WIC)
│ ├── Input.hpp # Клавиатурный ввод (Win32 / X11)
│ ├── Physics.hpp # Verlet-физика (STATIC fix)
│ ├── Sound.hpp # WAV-звук (winmm)
│ ├── Camera.hpp # Камера с follow + zoom
│ ├── Sprite.hpp # Спрайты и анимация
│ ├── DetailGroup.hpp# Батч-рендеринг
│ ├── Anim2D.hpp # Скелетная 2D-анимация
│ ├── GameObject.hpp # Игровые объекты
│ ├── Math.hpp # Vec2, Rect, Mat3
│ ├── Clock.hpp # Дельта-таймер
│ └── GLFunctions.hpp# OpenGL-функции (кросс-платформа)
├── src/ # C++ исходники
├── tools/
│ └── blender_export.py
├── build_exe.py # PyInstaller сборщик
├── setup.py
└── README.md
Репозиторий
https://github.com/r9441887-collab/jwarol-code-new
Лицензия
MIT License — Руслан (r9441887@gmail.com)
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 Distributions
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 jwarol-0.15.1-cp312-cp312-win_amd64.whl.
File metadata
- Download URL: jwarol-0.15.1-cp312-cp312-win_amd64.whl
- Upload date:
- Size: 239.6 kB
- Tags: CPython 3.12, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b919aeef74fbc947c8be2e6366614a4543d3163a1bc0d4898b7ebc6dd4956605
|
|
| MD5 |
f2f4dbedfc51d21392dc4c4aa05cdba9
|
|
| BLAKE2b-256 |
29ab81c44d09dd22b37e21fd10b1b86e7f0da1fa48f0848cc28e30d1be831650
|