using Voile; using Voile.Resources; using Voile.Utils; using Voile.Input; using Voile.Systems.Particles; using System.Numerics; using System.Diagnostics.CodeAnalysis; using System.Diagnostics; public class TestGame : BaseGame { public override string ResourceRoot => "Resources/"; protected override void LoadResources() { ResourceManager.AddResourceLoaderAssociation(new ParticleEmitterSettingsResourceLoader()); if (!ResourceManager.TryLoad("fonts/Inter-Regular.ttf", out _font)) { } ResourceManager.TryLoad("icon.png", out _icon); if (!ResourceManager.TryLoad("fire_effect.toml", out _fireEffect)) { throw new Exception("Failed to load emitter settings!"); } } protected override void Ready() { _particleSystem = new ParticleSystem(); Input.AddInputMapping("reload", new InputAction[] { new KeyInputAction(KeyboardKey.R) }); _particleSimStopwatch = new Stopwatch(); _emitterId = _particleSystem.CreateEmitter(Renderer.WindowSize / 2, _fireEffect); } protected override void Update(double deltaTime) { _particleSimStopwatch = Stopwatch.StartNew(); _particleSystem!.Update(deltaTime); _particleSimStopwatch.Stop(); } protected override void Render(double deltaTime) { if (Input.IsActionPressed("reload")) { ResourceManager.Reload(); _particleSystem!.RestartEmitter(_emitterId); } if (Input.KeyboardKeyJustPressed(KeyboardKey.One)) { _particleSystem.CreateEmitter(Input.GetMousePosition(), _fireEffect); } if (Input.IsMouseButtonDown(MouseButton.Left)) { _particleSystem.SetEmitterPosition(_emitterId, Input.GetMousePosition()); } Renderer.ClearBackground(Color.Black); foreach (var emitter in _particleSystem!.Emitters) { DrawEmitter(emitter); } Renderer.ResetTransform(); Renderer.DrawText(_font, $"Particle Sim: {TimeSpan.FromTicks(_particleSimStopwatch.ElapsedTicks).TotalMilliseconds} ms", Color.White); Renderer.SetTransform(new Vector2(0.0f, 16.0f), Vector2.Zero); Renderer.DrawText(_font, $"Render: {RenderFrameTime.TotalMilliseconds:F1} ms", Color.White); Renderer.SetTransform(new Vector2(0.0f, 32.0f), Vector2.Zero); Renderer.DrawText(_font, $"Update: {UpdateTimeStep * 1000:F1} ms", Color.White); } private void DrawEmitter(ParticleEmitter emitter) { Renderer.BeginBlended(Voile.Rendering.BlendMode.BlendAlpha); var maxParticles = emitter.Settings.MaxParticles; var particleSize = new Vector2(16.0f, 16.0f); var pivot = particleSize / 2; for (int i = maxParticles - 1; i >= 0; i--) { var particle = emitter.GetParticle(i); Renderer.SetTransform(particle.Position, pivot, particle.Rotation); Renderer.DrawRectangle(particleSize * particle.Scale, particle.Color); } Renderer.EndBlended(); } [NotNull] private ParticleSystem _particleSystem; private Stopwatch _particleSimStopwatch; private int _emitterId; private ResourceRef _fireEffect; private ResourceRef _font; private ResourceRef _icon; private Logger _logger = new(nameof(TestGame)); }