Code Examples

Learn Xengine through practical examples. Each example includes complete, runnable code.

Basics

01 - Hello Cube

Beginner
public class SpinningCube : Component
{
    private Vector3 _startPos;
    
    protected override void OnStart()
    {
        _startPos = Transform.Position;
    }
    
    protected override void OnUpdate()
    {
        var pos = _startPos;
        pos.Y += MathF.Sin(Time.Now * 2f) * 0.5f;
        Transform.Position = pos;
    }
    
    protected override void OnRender(RaylibRenderer r)
    {
        r.DrawCube(Transform.Position, Vector3.One, Color.Red);
    }
}

02 - Cube Renderer

Beginner
public class CubeRenderer : Component
{
    public Vector3 Size { get; set; } = Vector3.One;
    public Color Color { get; set; } = Color.White;
    
    protected override void OnRender(RaylibRenderer r)
    {
        r.DrawCube(Transform.Position, Size, Color);
    }
}

03 - Sphere Renderer

Beginner
public class SphereRenderer : Component
{
    public float Radius { get; set; } = 0.5f;
    public Color Color { get; set; } = Color.White;
    
    protected override void OnRender(RaylibRenderer r)
    {
        r.DrawSphere(Transform.Position, Radius, Color);
    }
}

Movement

04 - WASD Movement

Beginner
public class PlayerMovement : Component
{
    public float Speed = 5f;
    
    protected override void OnUpdate()
    {
        var move = Vector3.Zero;
        
        if (RaylibInput.IsKeyDown(KeyCode.W)) move.Z += 1;
        if (RaylibInput.IsKeyDown(KeyCode.S)) move.Z -= 1;
        if (RaylibInput.IsKeyDown(KeyCode.A)) move.X -= 1;
        if (RaylibInput.IsKeyDown(KeyCode.D)) move.X += 1;
        
        if (move.LengthSquared > 0)
        {
            move = move.Normalized * Speed * Time.Delta;
            Transform.Position += move;
        }
    }
}

05 - Smooth Follow

Intermediate
public class SmoothFollower : Component
{
    public float FollowSpeed = 3f;
    public float MinDistance = 2f;
    
    protected override void OnUpdate()
    {
        var target = Scene?.FindByName("Player");
        if (target == null) return;
        
        var targetPos = target.Transform.Position;
        var currentPos = Transform.Position;
        
        float dist = currentPos.DistanceTo(targetPos);
        if (dist > MinDistance)
        {
            Transform.Position = Vector3.Lerp(
                currentPos, targetPos, FollowSpeed * Time.Delta);
        }
    }
}

06 - Orbit Motion

Intermediate
public class OrbitMotion : Component
{
    public float Radius = 5f;
    public float Speed = 1f;
    private float _angle;
    
    protected override void OnUpdate()
    {
        _angle += Speed * Time.Delta;
        Transform.Position = new Vector3(
            MathF.Cos(_angle) * Radius,
            0.5f,
            MathF.Sin(_angle) * Radius
        );
    }
}

07 - Camera Follow

Intermediate
public class FollowCamera : Component
{
    public Vector3 Offset = new Vector3(0, 8, -10);
    public float SmoothSpeed = 5f;
    private Vector3 _currentPos;
    
    protected override void OnStart()
    {
        _currentPos = Offset;
    }
    
    protected override void OnUpdate()
    {
        var target = Scene?.FindByName("Player");
        if (target == null) return;
        
        var targetPos = target.Transform.Position + Offset;
        _currentPos = Vector3.Lerp(_currentPos, targetPos, 
            SmoothSpeed * Time.Delta);
        
        RaylibRenderer.Instance?.SetCamera(
            _currentPos, target.Transform.Position, 60f);
    }
}

Physics

08 - Bouncing Ball

Intermediate
public class BouncingBall : Component
{
    private float _velocityY;
    private Color _color;
    
    protected override void OnStart()
    {
        _color = new XRandom().Color();
    }
    
    protected override void OnUpdate()
    {
        _velocityY -= 15f * Time.Delta; // Gravity
        
        var pos = Transform.Position;
        pos.Y += _velocityY * Time.Delta;
        
        if (pos.Y < 0.5f)
        {
            pos.Y = 0.5f;
            _velocityY = -_velocityY * 0.8f; // Bounce
        }
        
        Transform.Position = pos;
    }
    
    protected override void OnRender(RaylibRenderer r)
    {
        r.DrawSphere(Transform.Position, 0.5f, _color);
    }
}

09 - Falling Cube

Beginner
public class FallingCube : Component
{
    public Color Color = Color.White;
    private float _velocityY;
    
    protected override void OnUpdate()
    {
        _velocityY -= 10f * Time.Delta;
        var pos = Transform.Position;
        pos.Y += _velocityY * Time.Delta;
        
        if (pos.Y < 0.5f)
        {
            pos.Y = 0.5f;
            _velocityY = 0;
        }
        Transform.Position = pos;
    }
    
    protected override void OnRender(RaylibRenderer r)
    {
        r.DrawCube(Transform.Position, new Vector3(0.8f), Color);
    }
}

Gameplay

10 - Collectible

Intermediate
public class Collectible : Component
{
    public static int Score;
    private Vector3 _basePos;
    
    protected override void OnStart()
    {
        _basePos = Transform.Position;
    }
    
    protected override void OnUpdate()
    {
        // Bob animation
        var pos = _basePos;
        pos.Y += MathF.Sin(Time.Now * 3f) * 0.2f;
        Transform.Position = pos;
        
        // Check collision with player
        var player = Scene?.FindByName("Player");
        if (player != null && 
            pos.DistanceTo(player.Transform.Position) < 1f)
        {
            Score += 10;
            GameObject.Destroy();
        }
    }
    
    protected override void OnRender(RaylibRenderer r)
    {
        r.DrawSphere(Transform.Position, 0.3f, Color.Yellow);
    }
}

11 - Health System

Intermediate
public class HealthComponent : Component
{
    public int MaxHealth = 100;
    public int CurrentHealth;
    
    protected override void OnStart()
    {
        CurrentHealth = MaxHealth;
    }
    
    public void TakeDamage(int amount)
    {
        CurrentHealth -= amount;
        if (CurrentHealth <= 0)
        {
            CurrentHealth = 0;
            Log.Info("DEAD!");
        }
    }
    
    public void Heal(int amount)
    {
        CurrentHealth += amount;
        if (CurrentHealth > MaxHealth) 
            CurrentHealth = MaxHealth;
    }
}

12 - Shooting

Intermediate
public class Shooter : Component
{
    public float Speed = 5f;
    private float _cooldown;
    
    protected override void OnUpdate()
    {
        // Movement
        var pos = Transform.Position;
        if (RaylibInput.IsKeyDown(KeyCode.A)) 
            pos.X -= Speed * Time.Delta;
        if (RaylibInput.IsKeyDown(KeyCode.D)) 
            pos.X += Speed * Time.Delta;
        Transform.Position = pos;
        
        // Shooting
        _cooldown -= Time.Delta;
        if (RaylibInput.IsKeyPressed(KeyCode.Space) 
            && _cooldown <= 0)
        {
            _cooldown = 0.2f;
            var bullet = Scene.CreateGameObject("Bullet", 
                pos + new Vector3(0, 0, 0.5f));
            bullet.AddComponent<Bullet>();
        }
    }
}

public class Bullet : Component
{
    public float Speed = 20f;
    
    protected override void OnUpdate()
    {
        Transform.Position += new Vector3(0, 0, Speed * Time.Delta);
        if (Transform.Position.Z > 15f)
            GameObject.Destroy();
    }
    
    protected override void OnRender(RaylibRenderer r)
    {
        r.DrawSphere(Transform.Position, 0.15f, Color.Yellow);
    }
}

13 - Proximity Trigger

Intermediate
public class ProximityTrigger : Component
{
    public float TriggerRadius = 3f;
    private bool _playerInside;
    
    protected override void OnUpdate()
    {
        var player = Scene?.FindByName("Player");
        if (player == null) return;
        
        float dist = Transform.Position
            .DistanceTo(player.Transform.Position);
        bool wasInside = _playerInside;
        _playerInside = dist < TriggerRadius;
        
        if (_playerInside && !wasInside)
            Log.Info("Player entered trigger!");
        else if (!_playerInside && wasInside)
            Log.Info("Player left trigger!");
    }
    
    protected override void OnRender(RaylibRenderer r)
    {
        var color = _playerInside ? Color.Green : Color.Red;
        r.DrawCube(Transform.Position, 
            new Vector3(TriggerRadius * 2, 0.1f, TriggerRadius * 2), 
            color.WithA(0.5f));
    }
}

Visual Effects

14 - Color Cycling

Beginner
public class ColorCycler : Component
{
    public float CycleSpeed = 0.3f;
    public float HueOffset = 0f;
    private float _hue;
    
    protected override void OnUpdate()
    {
        _hue += CycleSpeed * Time.Delta;
        if (_hue > 1f) _hue -= 1f;
    }
    
    protected override void OnRender(RaylibRenderer r)
    {
        float h = (_hue + HueOffset) % 1f;
        var color = Color.FromHSV(h, 1f, 1f);
        r.DrawCube(Transform.Position, Vector3.One, color);
    }
}

15 - Sine Wave

Intermediate
public class SineWavePoint : Component
{
    public int Index;
    public float Amplitude = 2f;
    public float WaveSpeed = 3f;
    private float _baseX;
    
    protected override void OnStart()
    {
        _baseX = Transform.Position.X;
    }
    
    protected override void OnUpdate()
    {
        float y = MathF.Sin(Time.Now * WaveSpeed + Index * 0.3f) 
            * Amplitude;
        Transform.Position = new Vector3(_baseX, y + 2f, 0);
    }
    
    protected override void OnRender(RaylibRenderer r)
    {
        float t = (Transform.Position.Y) / (Amplitude * 2f) + 0.5f;
        var color = Color.Lerp(Color.Blue, Color.Red, t);
        r.DrawSphere(Transform.Position, 0.2f, color);
    }
}

Running Examples

All examples are available in the demo_tests/ folder. To run them:

cd Xengine/demo_tests
dotnet run

Select the example number when prompted.