Tiavina.engine
Moteur de jeu 2D pixel art, construit sur Pygame.
Fonctionne avec un écran virtuel (résolution logique) mis à l'échelle entière vers la fenêtre d'affichage.
Installation
pip install Tiavina.engine
from Engine import engine as e
e.init(200, 200, "Mon Jeu", fps=60, display_scale=4)
def update():
if e.btn(e.KEY_ESCAPE):
e.quit()
def draw():
e.cls((30, 30, 40))
e.rect(10, 10, 20, 20, (255, 0, 0))
e.run(update, draw)
Table des matières
Architecture
Engine/
├── __init__.py ← réexporte l'API
├── engine.py ← le moteur (tout-en-un)
└── fonts/
└── PressStart2P.ttf ← police pixel embarquée
Le moteur expose une API globale : on importe from Engine import engine as e et on appelle e.init(), e.cls(), e.btn(), etc.
Sous le capot :
App— classe principale qui gère la fenêtre Pygame, l'horloge FPS, levirtual_screen(Surface logique), et la boucle d'événements.Graphics— dessin sur l'écran virtuel avec support de caméra, clipping, et alpha.Input— gestion clavier, souris, joystick.Resources— chargement d'images, sons, musiques.Audio— lecture son/musique via les canaux Pygame.
Initialisation
e.init(width, height, title="T.engine", fps=30, display_scale=1)
Crée la fenêtre et initialise tous les sous-systèmes.
| Paramètre | Type | Description |
|---|---|---|
width |
int |
Largeur logique de l'écran virtuel (ex: 200) |
height |
int |
Hauteur logique (ex: 200) |
title |
str |
Titre de la fenêtre |
fps |
int |
Images par seconde cibles |
display_scale |
int |
Facteur d'échelle entier (ex: 5 → fenêtre 1000×1000 pour 200×200) |
L'écran virtuel fait width × height pixels. Chaque frame, il est scaled par display_scale et affiché dans la fenêtre système.
e.init(200, 200, "Mon Jeu", 60, 5)
e.run(update, draw)
Lance la boucle de jeu. update() est appelée à chaque frame pour la logique, draw() pour le rendu.
def update():
pass
def draw():
e.cls((0, 0, 0))
e.run(update, draw)
e.quit()
Ferme Pygame et termine le processus.
e.width(), e.height()
Retourne la largeur/hauteur logique définies dans init().
e.frame_count()
Retourne le nombre de frames écoulées depuis init().
Graphismes — Graphics
Toutes les fonctions de dessin sont affectées par la caméra (sauf si camera() est réinitialisée).
Les coordonnées sont en pixels logiques.
Primitives de dessin
| Fonction | Description |
|---|---|
cls(color) |
Remplit tout l'écran virtuel avec une couleur |
pset(x, y, color) |
Dessine un pixel |
pget(x, y) → Color |
Lit la couleur d'un pixel |
line(x1, y1, x2, y2, color) |
Ligne |
rect(x, y, w, h, color) |
Rectangle plein |
rectb(x, y, w, h, color) |
Rectangle vide (1px de bord) |
circ(x, y, r, color) |
Cercle plein |
circb(x, y, r, color) |
Cercle vide (1px de bord) |
elli(x, y, w, h, color) |
Ellipse pleine |
ellib(x, y, w, h, color) |
Ellipse vide (1px de bord) |
tri(x1, y1, x2, y2, x3, y3, color) |
Triangle plein |
trib(x1, y1, x2, y2, x3, y3, color) |
Triangle vide (1px de bord) |
Couleurs avec alpha (RGBA)
Toutes les primitives sauf text() et pget() acceptent des couleurs RGBA (4 valeurs).
L'alpha est géré via un blending additif sur une surface temporaire.
# Rectangle semi-transparent
e.rect(10, 10, 50, 50, (255, 0, 0, 128))
Blit d'image
blt(x, y, img, u, v, w, h, colkey=None, rotate=0)
| Paramètre | Type | Description |
|---|---|---|
x, y |
int |
Position de destination (coin supérieur gauche) |
img |
pygame.Surface |
Image source |
u, v |
int |
Coordonnées source (coin supérieur gauche dans l'image) |
w, h |
int |
Dimensions de la région source |
colkey |
Color ou None |
Couleur de transparence (optionnelle) |
rotate |
float |
Rotation en degrés horaire (pivot au centre) |
e.blt(100, 100, img, 0, 0, 16, 16) # blit simple
e.blt(100, 100, img, 0, 0, 16, 16, rotate=45) # rotation
Texte
text(x, y, s, color, font=None)
| Paramètre | Type | Description |
|---|---|---|
x, y |
int |
Position |
s |
str |
Texte à afficher |
color |
tuple |
Couleur RGB (pas de support alpha) |
font |
pygame.Font ou None |
Police personnalisée (None = police pixel par défaut) |
La police par défaut est PressStart2P.ttf taille 6px, rendu sans anti-aliasing pour un aspect pixel art.
e.text(5, 5, "Score: 42", (255, 255, 255))
# Avec une police différente
big = e.default_font(16)
e.text(5, 20, "Titre", (255, 200, 0), font=big)
Caméra
camera(dx, dy) # Applique un décalage à tout le dessin suivant
camera() # Réinitialise le décalage à (0, 0)
La caméra est cumulative : tous les appels camera() s'ajoutent.
Pour un système plus avancé, voir la classe Camera.
e.camera(-player.x + 100, -player.y + 100) # suit le joueur
Clipping
clip(x, y, w, h) # Active un rectangle de clipping
clip() # Désactive le clipping
Le clipping est appliqué après la caméra.
Caméra intelligente — Camera
cam = e.Camera(target, screen_width, screen_height,
mouse_influence=0.2, mouse_limit=10)
Classe réutilisable avec suivi de cible, offset souris, tremblement et flash.
Paramètres du constructeur
| Paramètre | Défaut | Description |
|---|---|---|
target |
— | Objet suivi (doit avoir .x, .y) |
screen_width |
— | Largeur de l'écran logique |
screen_height |
— | Hauteur de l'écran logique |
mouse_influence |
0.2 |
Sensibilité du regard vers la souris (0.0–1.0) |
mouse_limit |
10 |
Décalage maximal dû à la souris (en pixels logiques) |
Méthodes
| Méthode | Description |
|---|---|
update() |
Calcule la nouvelle position de la caméra (target + souris + shake) |
apply() |
Applique le décalage au moteur graphique (e.camera(cam.cam_x, cam.cam_y)) |
shake(duration, intensity) |
Déclenche un tremblement d'écran |
flash(color, alpha, duration) |
Déclenche un flash d'écran |
Attributs
| Attribut | Description |
|---|---|
cam_x, cam_y |
Position calculée de la caméra (en pixels logiques) |
flash_color |
Couleur du flash actif |
flash_alpha |
Opacité courante du flash |
shake_intensity |
Intensité du tremblement actuel |
Le flash doit être dessiné manuellement dans draw() :
if cam.flash_alpha > 0:
surf = pygame.Surface((e.width(), e.height()), pygame.SRCALPHA)
surf.fill((*cam.flash_color, cam.flash_alpha))
e.graphics.screen.blit(surf, (0, 0))
Entrées — Input
Clavier
btn(key) # → True si la touche est maintenue
btnp(key) # → True le frame où la touche est pressée (pas de répétition)
btnr(key) # → True le frame où la touche est relâchée
if e.btn(e.KEY_SPACE):
player.jump()
if e.btnp(e.KEY_E):
player.interact()
Souris
mouse_x(), mouse_y() # → Position logique (divisée par display_scale)
mouse_btn(button) # → True si le bouton est maintenu
mouse_btnp(button) # → True le frame du clic
mouse_btnr(button) # → True le frame du relâchement
mouse(visible=True) # → Affiche ou cache le curseur système
Boutons : MOUSE_BUTTON_LEFT (1), MOUSE_BUTTON_MIDDLE (2), MOUSE_BUTTON_RIGHT (3)
if e.mouse_btnp(e.MOUSE_BUTTON_LEFT):
print(f"Clic à ({e.mouse_x()}, {e.mouse_y()})")
Joystick
joy(joy_id, button) # → True si le bouton du joystick est pressé
joy_axis(joy_id, axis) # → Valeur de l'axe (-1.0 à 1.0)
Les joysticks sont détectés et initialisés automatiquement au lancement.
Ressources — Resources
resources.image(bank, path, colkey=None) # → pygame.Surface ou None
resources.sound(bank, path) # → pygame.mixer.Sound ou None
resources.music(bank, path) # → None (enregistre le chemin)
resources.tilemap(bank) # → None (non implémenté)
resources.load(filename) # → lève NotImplementedError
Images
image() charge une image dans resources.images[bank].
bank: index numérique (int)path: chemin relatif ou absolucolkey: couleur de transparence optionnelle (ex:(255, 0, 255))
e.resources.image(0, "./sprites/player.png")
e.resources.image(1, "./sprites/tiles.png", (255, 0, 255))
# Utilisation
img = e.resources.images[1]
Sons
e.resources.sound(0, "./sfx/jump.wav")
e.audio.play(0, 0) # joue sur le canal 0
Audio — Audio
8 canaux (0–7) pour les effets sonores, 1 flux pour la musique.
audio.play(channel, sound_key, loop=False) # joue un son
audio.playm(music_key, loop=False) # joue une musique
audio.stop(channel=None) # stop (tout si channel=None)
audio.play_pos(channel) # → True si le canal est actif
e.audio.play(2, 0) # son index 0 sur canal 2
e.audio.playm("boss_music") # musique
e.audio.stop() # coupe tout
Police pixel — default_font
default_font(size=6) → pygame.Font
Charge et met en cache la police PressStart2P.ttf.
Si le fichier TTF est introuvable, tombe sur pygame.font.Font(None, size).
La police est stockée dans un cache global _pixel_font_cache : chaque taille n'est chargée qu'une fois.
petite = e.default_font(6)
moyenne = e.default_font(8)
grande = e.default_font(16)
Constantes
Touches clavier
KEY_A–KEY_Z, KEY_0–KEY_9,
KEY_SPACE, KEY_UP, KEY_DOWN, KEY_LEFT, KEY_RIGHT,
KEY_ESCAPE, KEY_RETURN, KEY_TAB, KEY_BACKSPACE,
KEY_LSHIFT, KEY_RSHIFT, KEY_LCTRL, KEY_RCTRL,
KEY_LALT, KEY_RALT
Toutes sont des constantes Pygame (pygame.K_*) réexportées par le module.
Boutons souris
| Constante | Valeur |
|---|---|
MOUSE_BUTTON_LEFT |
1 |
MOUSE_BUTTON_MIDDLE |
2 |
MOUSE_BUTTON_RIGHT |
3 |
Fonctions globales
Le module engine expose des fonctions globales qui délèguent aux sous-systèmes internes :
| Fonction | Délègue à |
|---|---|
cls(c) |
graphics.cls(c) |
pset(x,y,c) |
graphics.pset(x,y,c) |
pget(x,y) |
graphics.pget(x,y) |
line(x1,y1,x2,y2,c) |
graphics.line(...) |
rect(x,y,w,h,c) |
graphics.rect(...) |
rectb(x,y,w,h,c) |
graphics.rectb(...) |
circ(x,y,r,c) |
graphics.circ(...) |
circb(x,y,r,c) |
graphics.circb(...) |
elli(x,y,w,h,c) |
graphics.elli(...) |
ellib(x,y,w,h,c) |
graphics.ellib(...) |
tri(x1,y1,x2,y2,x3,y3,c) |
graphics.tri(...) |
trib(x1,y1,x2,y2,x3,y3,c) |
graphics.trib(...) |
text(x,y,s,c,font) |
graphics.text(...) |
blt(x,y,img,u,v,w,h,...) |
graphics.blt(...) |
bltm(x,y,tm,u,v,w,h,...) |
graphics.bltm(...) |
clip(x,y,w,h) |
graphics.clip(...) |
camera(x,y) |
graphics.camera(...) |
pal(c1,c2) |
graphics.pal(...) (stub) |
dither(a) |
graphics.dither(...) (stub) |
mouse_btn(b) |
input.mouse_btn(b) |
mouse_btnp(b) |
input.mouse_btnp(b) |
mouse_btnr(b) |
input.mouse_btnr(b) |
btn(k) |
input.btn(k) |
btnp(k) |
input.btnp(k) |
btnr(k) |
input.btnr(k) |
Exemple complet
import pygame
from Engine import engine as e
from random import randint
# ── Initialisation ─────────────────────────────────────
e.init(200, 200, "Aventurier", fps=60, display_scale=5)
# ── Ressources ─────────────────────────────────────────
e.resources.image(0, "./sprites/player.png")
e.resources.image(1, "./sprites/tiles.png")
# ── Joueur ─────────────────────────────────────────────
class Player:
def __init__(self):
self.x = 100
self.y = 100
self.w = 8
self.h = 8
self.vie = 100
player = Player()
# ── Caméra ─────────────────────────────────────────────
cam = e.Camera(player, e.width(), e.height(),
mouse_influence=0.3, mouse_limit=12)
# ── Boucle ─────────────────────────────────────────────
def update():
# Déplacements
if e.btn(e.KEY_LEFT): player.x -= 1
if e.btn(e.KEY_RIGHT): player.x += 1
if e.btn(e.KEY_UP): player.y -= 1
if e.btn(e.KEY_DOWN): player.y += 1
if e.btn(e.KEY_ESCAPE): e.quit()
# Clic pour shake
if e.mouse_btnp(e.MOUSE_BUTTON_LEFT):
cam.shake(10, 6)
cam.flash((255, 255, 200), 60, 4)
cam.update()
cam.apply()
def draw():
e.cls((30, 30, 40))
# Sol (en coordonnées monde)
for i in range(-2, 30):
for j in range(-2, 20):
e.rect(i * 8, j * 8, 8, 8, (40, 45, 55))
# Joueur
e.rect(player.x, player.y, player.w, player.h,
(100, 200, 255) if player.vie > 0 else (255, 50, 50))
# Flash overlay (dessiné avant la réinitialisation caméra)
if cam.flash_alpha > 0:
surf = pygame.Surface((e.width(), e.height()), pygame.SRCALPHA)
surf.fill((*cam.flash_color, cam.flash_alpha))
e.graphics.screen.blit(surf, (0, 0))
# ── HUD (coordonnées écran) ──
e.camera() # ← réinitialise la caméra
e.text(4, 4, f"Vie: {player.vie}", (255, 255, 255))
e.text(4, 12, f"Pos: {player.x},{player.y}", (200, 200, 200))
# Curseur
e.circb(e.mouse_x(), e.mouse_y(), 3, (255, 255, 255, 80))
e.run(update, draw)
Release files for Tiavina.engine 0.3.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| tiavina_engine-0.3.0-py3-none-any.whl | Python 3 | none | any | Details |
Release files / tiavina_engine-0.3.0-py3-none-any.whl
| Download URL | tiavina_engine-0.3.0-py3-none-any.whl |
|---|---|
| Size | 44.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
5b25e21f26303ca284604f7b7f8caf476f2d7ed46def17ae87bf4f85deb37a7d
|
|
BLAKE2b-256 checksum How to use checksums |
3d4567752b5e43c36c2f5c31d551860463b34d332a6973383e799ff9a45850a5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.3
|