Skip to main content

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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

jwarol-0.10.0.tar.gz (18.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

jwarol-0.10.0-cp312-cp312-win_amd64.whl (193.4 kB view details)

Uploaded CPython 3.12Windows x86-64

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

Hashes for jwarol-0.10.0.tar.gz
Algorithm Hash digest
SHA256 b675717e2c9f272a23fc7457d20fdc04926a153baee9b0dffda5f94398c1b801
MD5 b8833d1b69cb77406ce3c8aa6488aced
BLAKE2b-256 9dcee516887208f02f4eedfbd64a1fe541ba37f8aa7e008d8ceea00769e94b75

See more details on using hashes here.

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

Hashes for jwarol-0.10.0-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 5a8e86525a91e658179e42509ce809d73124e08ab399dd71df081be8011cf3cb
MD5 6535c6c252d2c04b5ad8b6ffd6348ac2
BLAKE2b-256 64ef11199d8f8c7715f5d966429142facf2215a215b9c6789e8bbb3297f95e10

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page