Game Loop

Pyxen exécute votre jeu à un rythme fixe de 30 frames par seconde. Vous n’écrivez pas de boucle principale — vous définissez deux fonctions et Pyxen les appelle pour vous.

start() et update()

def start():
    # appelée une fois, au début
    pass

def update():
    # appelée à chaque frame, 30 fois par seconde
    pass

start() est l’endroit où vous configurez votre monde : créer des entités, les placer, configurer la scène.

update() est l’endroit où s’exécute la logique de votre jeu : lire les entrées, déplacer les entités, vérifier les conditions, mettre à jour l’état. Après chaque appel à update(), le moteur effectue le rendu de la frame.

Fréquence fixe

Chaque frame dure exactement le même temps : 1/30e de seconde (~33ms). Cela signifie :

Vous pouvez toujours utiliser time.dt (delta time) si vous préférez un mouvement basé sur le temps, mais il vaudra toujours 1/30.

Ordre d’exécution d’une frame

À chaque frame, Pyxen exécute ces étapes dans l’ordre :

  1. Entrées — lecture de l’état du clavier, de la souris, du tactile et du gamepad
  2. update() — votre code s’exécute
  3. Collision — le moteur résout les grid bodies et appelle les callbacks de collision
  4. Rendu — le moteur dessine toutes les entités visibles

Cela signifie que lorsque vous lisez les entrées dans update(), les valeurs sont fraîches. Lorsque vous déplacez une entity, la résolution des collisions se fait juste après.

Callbacks de collision

Si vous définissez on_collision ou on_tile_collision au niveau global, le moteur les appelle durant l’étape de collision :

def on_collision(entity, other):
    # deux grid bodies se chevauchent
    pass

def on_tile_collision(entity, tile):
    # un grid body a touché une tile de tilemap
    pass

Ces fonctions s’exécutent après update() mais avant le rendu.

Temporisation

Le module pyxen.time vous fournit :

PropriétéValeurUtilisation
time.frame0, 1, 2, ...Compteur de frames depuis le début
time.dt0.0333...Delta time (toujours 1/30)
time.t0.0, 0.033, 0.066, ...Temps écoulé en secondes
time.fps30Frames par seconde

Pour les événements temporisés, vous pouvez utiliser les deux approches :

# Basé sur les frames : déclencher toutes les 60 frames (2 secondes)
if time.frame % 60 == 0:
    fire()

# Basé sur le temps : même chose
if int(time.t * 30) % 60 == 0:
    fire()

Le comptage de frames est généralement plus simple et plus prévisible.