major rework

This commit is contained in:
max
2026-02-16 18:32:48 +01:00
parent bbd82da07e
commit 932734e5b4
24 changed files with 1706 additions and 893 deletions

View File

@@ -0,0 +1,306 @@
using SFML.Graphics;
using SFML.System;
using Car_simulation.Core.Models;
using Car_simulation.UI.Instruments;
namespace Car_simulation.UI
{
public class DisplayManager
{
private InstrumentPanel _instrumentPanel;
private RenderWindow _window;
private Font _font;
private Color _backgroundColor = new Color(20, 20, 30);
private Text _fpsText;
private Clock _fpsClock;
private int _frameCount = 0;
private float _fpsUpdateInterval = 0.5f;
private float _fpsAccumulator = 0f;
// Debug information
private bool _showDebugInfo = false;
private RectangleShape _debugPanel;
private List<Text> _debugTexts;
// Performance tracking
private Queue<float> _frameTimes = new Queue<float>();
private const int FRAME_TIME_HISTORY = 60;
private Text _performanceText;
public DisplayManager(RenderWindow window, Font font)
{
_window = window;
_font = font;
Initialize();
}
private void Initialize()
{
_instrumentPanel = new InstrumentPanel(_font, new Vector2f(750, 50), new Vector2f(750, 275));
// FPS counter
_fpsText = new Text("FPS: 0", _font, 12);
_fpsText.FillColor = new Color(180, 180, 180);
_fpsText.Position = new Vector2f(10, _window.Size.Y - 25);
_fpsClock = new Clock();
// Performance text
_performanceText = new Text("", _font, 12);
_performanceText.FillColor = new Color(180, 180, 220);
_performanceText.Position = new Vector2f(_window.Size.X - 200, _window.Size.Y - 25);
// Debug panel
InitializeDebugPanel();
}
private void InitializeDebugPanel()
{
_debugPanel = new RectangleShape(new Vector2f(300, 200));
_debugPanel.Position = new Vector2f(_window.Size.X - 320, 20);
_debugPanel.FillColor = new Color(0, 0, 0, 200);
_debugPanel.OutlineThickness = 1;
_debugPanel.OutlineColor = Color.Cyan;
_debugTexts = new List<Text>();
for (int i = 0; i < 10; i++)
{
Text text = new Text("", _font, 12);
text.FillColor = Color.Cyan;
text.Position = new Vector2f(_window.Size.X - 310, 30 + i * 18);
_debugTexts.Add(text);
}
}
public void Update(Car car, float deltaTime, float totalTime, long updateCount)
{
UpdateFPS(deltaTime);
UpdatePerformanceInfo(deltaTime);
_instrumentPanel.Update(car);
if (_showDebugInfo)
{
UpdateDebugInfo(car, deltaTime, totalTime, updateCount);
}
}
private void UpdateFPS(float deltaTime)
{
_frameCount++;
_fpsAccumulator += deltaTime;
if (_fpsAccumulator >= _fpsUpdateInterval)
{
float fps = _frameCount / _fpsAccumulator;
_fpsText.DisplayedString = $"FPS: {fps:F1}";
_frameCount = 0;
_fpsAccumulator = 0f;
}
}
private void UpdatePerformanceInfo(float deltaTime)
{
// Track frame times for smoothing
_frameTimes.Enqueue(deltaTime * 1000); // Convert to milliseconds
if (_frameTimes.Count > FRAME_TIME_HISTORY)
{
_frameTimes.Dequeue();
}
// Calculate average frame time
float avgFrameTime = 0;
foreach (var time in _frameTimes)
{
avgFrameTime += time;
}
avgFrameTime /= _frameTimes.Count;
_performanceText.DisplayedString = $"Frame: {deltaTime * 1000:F1}ms (Avg: {avgFrameTime:F1}ms)";
}
private void UpdateDebugInfo(Car car, float deltaTime, float totalTime, long updateCount)
{
int line = 0;
if (line < _debugTexts.Count)
_debugTexts[line++].DisplayedString = $"Time: {totalTime:F2}s";
if (line < _debugTexts.Count)
_debugTexts[line++].DisplayedString = $"Updates: {updateCount}";
if (line < _debugTexts.Count)
_debugTexts[line++].DisplayedString = $"Delta: {deltaTime:F4}s";
if (line < _debugTexts.Count)
_debugTexts[line++].DisplayedString = $"Position: ({car.Position.X:F1}, {car.Position.Y:F1})";
if (line < _debugTexts.Count)
_debugTexts[line++].DisplayedString = $"Velocity: {car.Velocity.Length:F2} m/s";
if (line < _debugTexts.Count)
_debugTexts[line++].DisplayedString = $"Engine Omega: {car.Engine.AngularVelocity:F2} rad/s";
if (line < _debugTexts.Count)
_debugTexts[line++].DisplayedString = $"Wheel Omega: {car.WheelSystem.AngularVelocity:F2} rad/s";
if (line < _debugTexts.Count)
_debugTexts[line++].DisplayedString = $"Clutch Eng: {car.Drivetrain.ClutchEngagement:P0}";
if (line < _debugTexts.Count)
_debugTexts[line++].DisplayedString = $"Force Clutch: {car.ForceClutch}";
}
public void Draw()
{
_window.Clear(_backgroundColor);
_instrumentPanel.Draw(_window);
// Draw FPS counter
_window.Draw(_fpsText);
// Draw performance info
_window.Draw(_performanceText);
// Draw debug panel if enabled
if (_showDebugInfo)
{
_window.Draw(_debugPanel);
foreach (var text in _debugTexts)
{
if (!string.IsNullOrEmpty(text.DisplayedString))
_window.Draw(text);
}
}
// Draw version info
DrawVersionInfo();
}
private void DrawVersionInfo()
{
Text versionText = new Text("Car Simulation v1.0", _font, 10);
versionText.FillColor = new Color(100, 100, 100);
versionText.Position = new Vector2f(_window.Size.X - 120, _window.Size.Y - 15);
_window.Draw(versionText);
}
public void ToggleDebugInfo()
{
_showDebugInfo = !_showDebugInfo;
}
public bool ShowDebugInfo => _showDebugInfo;
public void HandleResize(uint width, uint height)
{
// Update FPS text position
_fpsText.Position = new Vector2f(10, height - 25);
// Update performance text position
_performanceText.Position = new Vector2f(width - 200, height - 25);
// Update debug panel position
_debugPanel.Position = new Vector2f(width - 320, 20);
// Update debug text positions
for (int i = 0; i < _debugTexts.Count; i++)
{
_debugTexts[i].Position = new Vector2f(width - 310, 30 + i * 18);
}
// You might want to reposition the instrument panel too
// For now, the instrument panel is fixed, but you could add resize handling
}
public void DrawCustomMessage(string message, Vector2f position, uint fontSize, Color color)
{
Text customText = new Text(message, _font, fontSize);
customText.FillColor = color;
customText.Position = position;
_window.Draw(customText);
}
public void DrawProgressBar(Vector2f position, Vector2f size, float progress, Color fillColor, Color bgColor)
{
// Draw background
RectangleShape background = new RectangleShape(size);
background.Position = position;
background.FillColor = bgColor;
background.OutlineThickness = 1;
background.OutlineColor = Color.White;
_window.Draw(background);
// Draw fill
if (progress > 0)
{
RectangleShape fill = new RectangleShape(new Vector2f(size.X * Math.Clamp(progress, 0, 1), size.Y));
fill.Position = position;
fill.FillColor = fillColor;
_window.Draw(fill);
}
// Draw percentage text
Text progressText = new Text($"{progress:P0}", _font, 12);
progressText.FillColor = Color.White;
progressText.Position = new Vector2f(
position.X + size.X / 2 - progressText.GetLocalBounds().Width / 2,
position.Y + size.Y / 2 - progressText.CharacterSize / 2
);
_window.Draw(progressText);
}
public void DrawGraph(string title, List<float> data, Vector2f position, Vector2f size, Color lineColor)
{
if (data.Count < 2) return;
// Draw graph background
RectangleShape graphBackground = new RectangleShape(size);
graphBackground.Position = position;
graphBackground.FillColor = new Color(0, 0, 0, 128);
graphBackground.OutlineThickness = 1;
graphBackground.OutlineColor = Color.White;
_window.Draw(graphBackground);
// Draw title
Text titleText = new Text(title, _font, 12);
titleText.FillColor = Color.White;
titleText.Position = new Vector2f(position.X + 5, position.Y + 5);
_window.Draw(titleText);
// Find min and max values
float minValue = data.Min();
float maxValue = data.Max();
float valueRange = Math.Max(maxValue - minValue, 0.001f);
// Draw data points as line
VertexArray line = new VertexArray(PrimitiveType.LineStrip);
for (int i = 0; i < data.Count; i++)
{
float x = position.X + (i / (float)(data.Count - 1)) * size.X;
float normalizedValue = (data[i] - minValue) / valueRange;
float y = position.Y + size.Y - normalizedValue * size.Y;
line.Append(new Vertex(new Vector2f(x, y), lineColor));
}
_window.Draw(line);
// Draw min/max labels
Text minText = new Text($"{minValue:F0}", _font, 10);
minText.FillColor = Color.White;
minText.Position = new Vector2f(position.X + size.X - 30, position.Y + size.Y - 15);
_window.Draw(minText);
Text maxText = new Text($"{maxValue:F0}", _font, 10);
maxText.FillColor = Color.White;
maxText.Position = new Vector2f(position.X + size.X - 30, position.Y + 5);
_window.Draw(maxText);
}
}
}