Foxvoid Engine
Foxvoid Engine est un moteur 2D. Développé en C++ et Raylib, il se démarque par son architecture data-driven, son éditeur visuel intégré (ImGui) et son API de scripting native en Python, offrant ainsi un pont entre performances bas niveau et prototypage rapide.
Introduction au Foxvoid Engine : C++, ECS et Scripting Python
L'objectif de ce moteur est de fournir une base solide pour le développement 2D, en combinant la rapidité d'exécution du C++ avec la souplesse du langage Python.
Architecture et Fonctionnalités Clés
Le moteur repose sur une architecture stricte, séparant la boucle principale des sous-systèmes de rendu et de l'éditeur :
- Entity Component System (ECS) : Une architecture hiérarchique permettant de lier des
GameObjectsà des composants modulaires (Physique, Audio, Rendu). - Éditeur ImGui Intégré : Un espace de travail complet offrant une vue de la scène, un inspecteur, une palette de tiles et un historique de commandes non destructif.
- Moteur Physique 2D : Résolution de collisions AABB personnalisée, corps rigides cinématiques ou dynamiques et raycasting global.
- Sérialisation JSON : Les scènes et les prefabs sont entièrement pilotés par les données, facilitant la gestion de versions.
Le pont entre C++ et Python
La véritable force du Foxvoid Engine réside dans son API Python propulsée par pybind11. Il est possible de manipuler le moteur physique ou de jouer des effets sonores sans overhead visible, avec une autocomplétion native.
Voici un aperçu de l'API avec un contrôleur de joueur basique :
from foxvoid import *
from typing import Optional
class PlayerController(Component):
def __init__(self):
super().__init__()
self.speed = 400.0
self.jump_force = -700.0
self._rb: Optional[RigidBody2d] = None
self._audio: Optional[AudioSource] = None
def start(self):
# Retrieve native C++ components attached to the GameObject
self._rb = self.game_object.get_component(RigidBody2d)
self._audio = self.game_object.get_component(AudioSource)
if self._audio:
# Load the sound effect into the engine's memory
self._audio.load_sfx("jump", "assets/sounds/jump.wav")
def update(self, delta_time: float):
# Ensure the rigid body exists before applying logic
if not self._rb: return
# Handle horizontal velocity based on user input
if Input.is_action_down("walk_right"):
self._rb.velocity.x = self.speed
elif Input.is_action_down("walk_left"):
self._rb.velocity.x = -self.speed
else:
self._rb.velocity.x = 0.0
# Handle jumping logic and trigger audio
if Input.is_action_pressed("jump") and self._rb.is_grounded:
self._rb.velocity.y = self.jump_force
if self._audio:
self._audio.play_sfx("jump")