High-performance creative engine (Win32/OpenGL/Python)
Project description
jwarol
Движок на C++ для 2D-игр на Python. Win32 API + сырой OpenGL (и X11 на Linux). Включено: рендеринг, шейдеры, текстуры, физика, звук .wav, игровые объекты, шифрование ассетов.
Возможности
| Функция | Описание |
|---|---|
| Window | Создание окна с OpenGL-контекстом (Win32 / X11) |
| Shader | Компиляция GLSL-шейдеров из строк или отдельных .glsl файлов |
| Renderer | Рендеринг прямоугольников и текстур через GPU |
| Texture | Загрузка PNG/JPG/BMP, процедурные текстуры, наложение |
| Input | Клавиатурный ввод (GetAsyncKeyState) |
| Camera | Следование за игроком, скроллинг мира, smooth-камера |
| Sprite/Animation | Спрайт-листы, анимация по кадрам, генерация анимаций |
| Physics | Verlet-интеграция, гравитация, коллизии, типы тел |
| Sound | Воспроизведение .wav (winmm) |
| Object/Player/Character/GUI/Detail | Система игровых объектов |
| Texture.encrypt | Шифрование текстур для скомпилированных игр |
| Clock | Замер дельта-тайма |
| Vec2/Rect | 2D-математика |
Установка
pip install jwarol
Быстрый старт
import jwarol as jl
jl.init_graphics()
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()
Текстуры
# Загрузка из файла (PNG/JPG/BMP на Windows, BMP на Linux)
tex = jl.Texture("sprite.png")
# Процедурная текстура из пикселей (RGBA)
import struct
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)
# Текстура с прозрачностью
renderer.draw_texture(tex, 100, 100, 200, 200, alpha=0.5)
# Спрайт из tileset'а (draw_texture_ex)
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
# Verlet-точки
p = world.add_point(400, 100) # падает вниз
# Физические тела (прямоугольники)
body = world.add_body(300, 0, 50, 50, jl.BodyType.DYNAMIC)
static = world.add_body(0, 650, 800, 50, jl.BodyType.STATIC)
# Исключение из физики
body.enabled = False # не участвует в симуляции
# Шаг физики
dt = clock.tick()
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
layout(location = 0) in vec2 aPos;
void main() { gl_Position = vec4(aPos, 0.0, 1.0); }
""", """
#version 330 core
uniform vec4 uColor;
out vec4 FragColor;
void main() { FragColor = uColor; }
""")
shader.use()
# Из отдельных файлов (любые названия)
shader = jl.Shader.from_file("shaders/vertex.glsl", "shaders/fragment.glsl")
shader = jl.Shader.from_file("custom.vert", "custom.frag")
# Из одного файла с маркерами (#shader vertex / #shader fragment)
shader = jl.Shader.from_single_file("shader.glsl")
# Ошибки обрабатываются без краша:
# - файл не найден → RuntimeError
# - файл пустой → RuntimeError
# - ошибка компиляции → RuntimeError с логом
try:
s = jl.Shader.from_file("bad.glsl", "empty.glsl")
except RuntimeError as e:
print("Shader error:", e)
Звук
# Из папки
sound = jl.Sound("assets/sounds/effect.wav")
sound.play()
sound.set_volume(500) # 0-1000
sound.stop()
# Быстрое воспроизведение без создания объекта
jl.Sound.play_file("assets/sounds/click.wav")
Камера
cam = jl.Camera(800, 600)
# Следование за игроком (с плавностью)
cam.follow(player)
cam.smooth = 0.1 # 0 = мгновенно, 1 = очень плавно
# Применить к рендереру перед отрисовкой
cam.update(dt)
cam.apply_to(renderer)
# Все draw_rect/draw_texture теперь сдвинуты камерой
# Объекты за экраном не рисуются (FPS не проседает)
renderer.draw_rect(0, 0, 2000, 2000, 0.2, 0.2, 0.3) # большой мир
Спрайты и анимация
# Загрузка спрайт-листа (одна картинка с кадрами)
sheet = jl.Texture("player_walk.png") # 4 колонки x 2 строки = 8 кадров
sprite = jl.Sprite()
sprite.set_texture(sheet, 4, 2) # 4 колонки, 2 строки
# Анимация из последовательности кадров
anim = jl.Animation()
anim.from_range(0, 3) # кадры 0,1,2,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)
# Генерация простых анимаций
idle = jl.Animation.generate("idle", 8)
walk = jl.Animation.generate("walk", 8)
run = jl.Animation.generate("run", 8)
# Рендерер сам обрезает невидимые объекты
renderer.set_camera(cam.x, cam.y)
renderer.is_visible(x, y, w, h) # проверка видимости вручную
Игровые объекты
# Базовый объект
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-элемент
gui = jl.GUI(10, 10, 200, 30)
gui.text = "Score: 0"
# Мелкая деталь
detail = jl.Detail(500, 400, 16, 16)
detail.alpha = 0.5
Шифрование текстур
# Зашифровать текстуру (создаёт .enc файл)
jl.Texture.encrypt("sprite.png", "my_secret_key")
# Загрузить зашифрованную текстуру
tex = jl.Texture.load_encrypted("sprite.png.enc", "my_secret_key")
Сборка из исходников
# Windows (MSVC)
python setup.py build
# Linux (GCC)
python setup.py build
Репозиторий
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 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 jwarol-0.10.0.tar.gz.
File metadata
- Download URL: jwarol-0.10.0.tar.gz
- Upload date:
- Size: 18.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b675717e2c9f272a23fc7457d20fdc04926a153baee9b0dffda5f94398c1b801
|
|
| MD5 |
b8833d1b69cb77406ce3c8aa6488aced
|
|
| BLAKE2b-256 |
9dcee516887208f02f4eedfbd64a1fe541ba37f8aa7e008d8ceea00769e94b75
|
File details
Details for the file jwarol-0.10.0-cp312-cp312-win_amd64.whl.
File metadata
- Download URL: jwarol-0.10.0-cp312-cp312-win_amd64.whl
- Upload date:
- Size: 193.4 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 |
5a8e86525a91e658179e42509ce809d73124e08ab399dd71df081be8011cf3cb
|
|
| MD5 |
6535c6c252d2c04b5ad8b6ffd6348ac2
|
|
| BLAKE2b-256 |
64ef11199d8f8c7715f5d966429142facf2215a215b9c6789e8bbb3297f95e10
|