camera implemented

This commit is contained in:
maxwes08
2026-09-02 13:55:55 +02:00
parent 5680beef02
commit cf1f083cc5
21 changed files with 289 additions and 29 deletions

187
PhysicsEngine/Camera.cs Normal file
View File

@@ -0,0 +1,187 @@
using Raylib_cs;
using System;
using System.Numerics;
namespace PhysicsEngine
{
public class Camera
{
public const float PixelsPerMeter = 100.0f;
private const float GridSpacing = 1.0f; // meters
private const float ZoomLerpSpeed = 30.0f;
private const float MoveLerpSpeed = 20.0f;
private const float ZoomFactor = 0.1f;
private const float MinZoom = 0.2f;
private const float MaxZoom = 500000000000000000000000000000000000.0f;
public Camera2D RaylibCamera { get; private set; }
public Vector2 Position => RaylibCamera.Target / PixelsPerMeter;
public float Zoom => RaylibCamera.Zoom;
private float targetZoom;
private Vector2 targetPosition;
private Vector2 dragStartMouseScreen;
private Vector2 dragStartTarget;
private bool isDragging = false;
public Camera()
{
RaylibCamera = new Camera2D
{
Target = Vector2.Zero,
Offset = new Vector2(Raylib.GetScreenWidth() / 2.0f, Raylib.GetScreenHeight() / 2.0f),
Rotation = 0.0f,
Zoom = 1.0f
};
targetZoom = 1.0f;
targetPosition = RaylibCamera.Target;
}
public void Update(float frameTime)
{
Camera2D cam = RaylibCamera;
cam.Offset = new Vector2(Raylib.GetScreenWidth() / 2.0f, Raylib.GetScreenHeight() / 2.0f);
// panning
if (Raylib.IsMouseButtonPressed(MouseButton.Middle))
{
isDragging = true;
dragStartMouseScreen = Raylib.GetMousePosition();
dragStartTarget = targetPosition;
}
if (isDragging)
{
if (Raylib.IsMouseButtonDown(MouseButton.Middle))
{
Vector2 currentMouseScreen = Raylib.GetMousePosition();
Vector2 screenDelta = currentMouseScreen - dragStartMouseScreen;
targetPosition = dragStartTarget - (screenDelta / cam.Zoom);
cam.Target = targetPosition;
}
else
{
isDragging = false;
}
}
else
{
// arrow key panning
float moveSpeed = 5.0f * PixelsPerMeter;
if (Raylib.IsKeyDown(KeyboardKey.Right)) targetPosition.X += moveSpeed * frameTime;
if (Raylib.IsKeyDown(KeyboardKey.Left)) targetPosition.X -= moveSpeed * frameTime;
if (Raylib.IsKeyDown(KeyboardKey.Down)) targetPosition.Y += moveSpeed * frameTime;
if (Raylib.IsKeyDown(KeyboardKey.Up)) targetPosition.Y -= moveSpeed * frameTime;
}
// recenter
if (Raylib.IsKeyPressed(KeyboardKey.Space))
{
targetPosition = Vector2.Zero;
targetZoom = 1.0f;
isDragging = false;
}
// zooming
float wheel = Raylib.GetMouseWheelMove();
if (wheel != 0.0f)
{
targetZoom *= MathF.Pow(1 + ZoomFactor, wheel);
targetZoom = Math.Clamp(targetZoom, MinZoom, MaxZoom);
}
// lerp zoom
if (MathF.Abs(cam.Zoom - targetZoom) > 0.0001f)
{
Vector2 mouseWorldBefore = Raylib.GetScreenToWorld2D(Raylib.GetMousePosition(), cam);
cam.Zoom += (targetZoom - cam.Zoom) * ZoomLerpSpeed * frameTime;
cam.Zoom = Math.Clamp(cam.Zoom, MinZoom, MaxZoom);
Vector2 mouseWorldAfter = Raylib.GetScreenToWorld2D(Raylib.GetMousePosition(), cam);
targetPosition += (mouseWorldBefore - mouseWorldAfter);
cam.Target = targetPosition;
if (isDragging)
{
dragStartMouseScreen = Raylib.GetMousePosition();
dragStartTarget = targetPosition;
}
}
else if (!isDragging)
{
cam.Target.X += (targetPosition.X - cam.Target.X) * MoveLerpSpeed * frameTime;
cam.Target.Y += (targetPosition.Y - cam.Target.Y) * MoveLerpSpeed * frameTime;
targetPosition = cam.Target;
}
RaylibCamera = cam;
}
public void DrawGrid()
{
float screenW = Raylib.GetScreenWidth();
float screenH = Raylib.GetScreenHeight();
float cellPixels = GridSpacing * PixelsPerMeter * RaylibCamera.Zoom;
float subCellPixels = cellPixels / 5.0f;
Vector2 originScreen = Raylib.GetWorldToScreen2D(Vector2.Zero, RaylibCamera);
Color gridColor = MuiDarkColor.SurfaceVariant.ToColor();
Color subGridColor = new Color((byte)gridColor.R, (byte)gridColor.G, (byte)gridColor.B, (byte)75);
Color mainGridColor = new Color((byte)gridColor.R, (byte)gridColor.G, (byte)gridColor.B, (byte)150);
// subgrid lines
float startSubX = originScreen.X % subCellPixels;
if (startSubX > 0) startSubX -= subCellPixels;
for (float x = startSubX; x <= screenW; x += subCellPixels)
{
float relativeToOriginX = x - originScreen.X;
int indexX = (int)Math.Round(relativeToOriginX / subCellPixels);
if (indexX % 5 == 0) continue;
int ix = (int)Math.Round(x);
Raylib.DrawLineEx(new Vector2(ix, 0), new Vector2(ix, screenH), 2.0f, subGridColor);
}
float startSubY = originScreen.Y % subCellPixels;
if (startSubY > 0) startSubY -= subCellPixels;
for (float y = startSubY; y <= screenH; y += subCellPixels)
{
float relativeToOriginY = y - originScreen.Y;
int indexY = (int)Math.Round(relativeToOriginY / subCellPixels);
if (indexY % 5 == 0) continue;
int iy = (int)Math.Round(y);
Raylib.DrawLineEx(new Vector2(0, iy), new Vector2(screenW, iy), 2.0f, subGridColor);
}
// main grid lines
float startMainX = originScreen.X % cellPixels;
if (startMainX > 0) startMainX -= cellPixels;
for (float x = startMainX; x <= screenW; x += cellPixels)
{
int ix = (int)Math.Round(x);
Raylib.DrawLineEx(new Vector2(ix, 0), new Vector2(ix, screenH), 3.0f, mainGridColor);
}
float startMainY = originScreen.Y % cellPixels;
if (startMainY > 0) startMainY -= cellPixels;
for (float y = startMainY; y <= screenH; y += cellPixels)
{
int iy = (int)Math.Round(y);
Raylib.DrawLineEx(new Vector2(0, iy), new Vector2(screenW, iy), 3.0f, mainGridColor);
}
}
public void DrawHUD()
{
float screenH = Raylib.GetScreenHeight();
string hudText = $"X: {Position.X:F1}m Y: {Position.Y:F1}m Zoom: {Zoom:F2}x";
Raylib.DrawText(hudText, 20, (int)screenH - 40, 20, MuiDarkColor.TextPrimary.ToColor());
}
}
}

View File

@@ -0,0 +1,44 @@
using Raylib_cs;
namespace PhysicsEngine
{
public enum MuiDarkColor : uint
{
// Backgrounds & Surfaces
BackgroundDefault = 0x121212FF, // #121212
SurfacePaper = 0x121212FF,
SurfaceVariant = 0x1E1E1EFF, // #1E1E1E
// Text Colors
TextPrimary = 0xFFFFFFFF, // #FFFFFF
TextSecondary = 0xFFFFFFB3,
TextDisabled = 0xFFFFFF80,
// Actions & States
ActionHover = 0xFFFFFF14,
ActionSelected = 0xFFFFFF29,
Divider = 0xFFFFFF1F,
// Brand / Theme Accents
PrimaryMain = 0x90CAF9FF, // #90CAF9
SecondaryMain = 0xCE93D8FF, // #CE93D8
ErrorMain = 0xEF5350FF, // #EF5350
WarningMain = 0xFF9800FF, // #FF9800
SuccessMain = 0x66BB6AFF // #66BB6A
}
public static class MuiDarkColorExtensions
{
public static Color ToColor(this MuiDarkColor colorEnum)
{
uint packedValue = (uint)colorEnum;
byte r = (byte)(packedValue >> 24);
byte g = (byte)((packedValue >> 16) & 0xFF);
byte b = (byte)((packedValue >> 8) & 0xFF);
byte a = (byte)(packedValue & 0xFF);
return new Color(r, g, b, a);
}
}
}

View File

@@ -6,28 +6,28 @@ namespace PhysicsEngine
{
static void Main(string[] args)
{
const int screenWidth = 1280;
const int screenHeight = 720;
Raylib.InitWindow(screenWidth, screenHeight, "Fysikmotor & Sandlåda");
Raylib.SetTargetFPS(144);
Raylib.SetConfigFlags(ConfigFlags.FullscreenMode | ConfigFlags.VSyncHint);
Raylib.InitWindow(0, 0, "Physics Engine");
const float physicsTimeStep = 1.0f / 60.0f;
Camera camera = new Camera();
const float physicsTimeStep = 1.0f / 60.0f;
float accumulator = 0.0f;
// Main loop
while (!Raylib.WindowShouldClose())
{
float frameTime = Raylib.GetFrameTime();
if (frameTime > 0.25f)
{
frameTime = 0.25f;
}
accumulator += frameTime;
// Update Camera
camera.Update(frameTime);
// Update loop
// Update Physics accumulator
accumulator += frameTime;
while (accumulator >= physicsTimeStep)
{
UpdatePhysics(physicsTimeStep);
@@ -36,26 +36,33 @@ namespace PhysicsEngine
// Render loop
Raylib.BeginDrawing();
Raylib.ClearBackground(Color.RayWhite);
Raylib.ClearBackground(MuiDarkColor.BackgroundDefault.ToColor());
// Draw
// Draw background screen-space elements (Grid)
camera.DrawGrid();
// Draw world-space elements inside 2D mode
Raylib.BeginMode2D(camera.RaylibCamera);
Raylib.EndMode2D();
// Draw UI / HUD elements
RenderScene();
camera.DrawHUD();
Raylib.EndDrawing();
}
// Close
Raylib.CloseWindow();
}
private static void UpdatePhysics(float dt)
{
// Physics simulation step
}
private static void RenderScene()
{
Raylib.DrawText("Physics Engine", 20, 20, 20, Color.DarkGray);
Raylib.DrawText("Physics Engine", 20, 20, 20, MuiDarkColor.TextPrimary.ToColor());
}
}
}

View File

@@ -13,7 +13,7 @@ using System.Reflection;
[assembly: System.Reflection.AssemblyCompanyAttribute("PhysicsEngine")]
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+b88c9b3581c79bcf7dab83ce9a4a3ddfe9b5c791")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+5680beef02a5c7a4cdc1dc725326855b4af1faab")]
[assembly: System.Reflection.AssemblyProductAttribute("PhysicsEngine")]
[assembly: System.Reflection.AssemblyTitleAttribute("PhysicsEngine")]
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]

View File

@@ -1 +1 @@
6e7f12d0a748e6f800b5c90b709ee56dda6d5016d01ed56969641ea0c3b50864
65813feab20f3482f44a4d97f31d1282ff5b6ec731137cac82a3e7db08a5bb63

View File

@@ -10,7 +10,7 @@ build_property.PlatformNeutralAssembly =
build_property.EnforceExtendedAnalyzerRules =
build_property._SupportedPlatformList = Linux,macOS,Windows
build_property.RootNamespace = PhysicsEngine
build_property.ProjectDir = C:\Users\maxwes08\source\repos\Physics-Engine\Physics-Engine\PhysicsEngine\
build_property.ProjectDir = C:\Users\maxwes08\source\repos\Physics-Engine\PhysicsEngine\
build_property.EnableComHosting =
build_property.EnableGeneratedComInterfaceComImportInterop =
build_property.EffectiveAnalysisLevelStyle = 10.0

View File

@@ -1 +1 @@
e0ab312c01de0fc5b913a50944f6e9e9f433b7e80a2ed356c2dd839872cf6c9d
6b2f1f27b472d9ef51ad7745525496297fe0832151173bc3df4acdae2fd1d6fe

View File

@@ -20,3 +20,25 @@ C:\Users\maxwes08\source\repos\Physics-Engine\Physics-Engine\PhysicsEngine\bin\D
C:\Users\maxwes08\source\repos\Physics-Engine\Physics-Engine\PhysicsEngine\bin\Debug\net10.0\runtimes\win-x86\native\raylib.dll
C:\Users\maxwes08\source\repos\Physics-Engine\Physics-Engine\PhysicsEngine\obj\Debug\net10.0\PhysicsEngine.csproj.AssemblyReference.cache
C:\Users\maxwes08\source\repos\Physics-Engine\Physics-Engine\PhysicsEngine\obj\Debug\net10.0\PhysicsE.CA49F505.Up2Date
C:\Users\maxwes08\source\repos\Physics-Engine\PhysicsEngine\bin\Debug\net10.0\PhysicsEngine.exe
C:\Users\maxwes08\source\repos\Physics-Engine\PhysicsEngine\bin\Debug\net10.0\PhysicsEngine.deps.json
C:\Users\maxwes08\source\repos\Physics-Engine\PhysicsEngine\bin\Debug\net10.0\PhysicsEngine.runtimeconfig.json
C:\Users\maxwes08\source\repos\Physics-Engine\PhysicsEngine\bin\Debug\net10.0\PhysicsEngine.dll
C:\Users\maxwes08\source\repos\Physics-Engine\PhysicsEngine\bin\Debug\net10.0\PhysicsEngine.pdb
C:\Users\maxwes08\source\repos\Physics-Engine\PhysicsEngine\bin\Debug\net10.0\Raylib-cs.dll
C:\Users\maxwes08\source\repos\Physics-Engine\PhysicsEngine\bin\Debug\net10.0\runtimes\linux-x64\native\libraylib.so
C:\Users\maxwes08\source\repos\Physics-Engine\PhysicsEngine\bin\Debug\net10.0\runtimes\osx-arm64\native\libraylib.dylib
C:\Users\maxwes08\source\repos\Physics-Engine\PhysicsEngine\bin\Debug\net10.0\runtimes\osx-x64\native\libraylib.dylib
C:\Users\maxwes08\source\repos\Physics-Engine\PhysicsEngine\bin\Debug\net10.0\runtimes\win-x64\native\raylib.dll
C:\Users\maxwes08\source\repos\Physics-Engine\PhysicsEngine\bin\Debug\net10.0\runtimes\win-x86\native\raylib.dll
C:\Users\maxwes08\source\repos\Physics-Engine\PhysicsEngine\obj\Debug\net10.0\PhysicsEngine.csproj.AssemblyReference.cache
C:\Users\maxwes08\source\repos\Physics-Engine\PhysicsEngine\obj\Debug\net10.0\PhysicsEngine.GeneratedMSBuildEditorConfig.editorconfig
C:\Users\maxwes08\source\repos\Physics-Engine\PhysicsEngine\obj\Debug\net10.0\PhysicsEngine.AssemblyInfoInputs.cache
C:\Users\maxwes08\source\repos\Physics-Engine\PhysicsEngine\obj\Debug\net10.0\PhysicsEngine.AssemblyInfo.cs
C:\Users\maxwes08\source\repos\Physics-Engine\PhysicsEngine\obj\Debug\net10.0\PhysicsEngine.csproj.CoreCompileInputs.cache
C:\Users\maxwes08\source\repos\Physics-Engine\PhysicsEngine\obj\Debug\net10.0\PhysicsE.CA49F505.Up2Date
C:\Users\maxwes08\source\repos\Physics-Engine\PhysicsEngine\obj\Debug\net10.0\PhysicsEngine.dll
C:\Users\maxwes08\source\repos\Physics-Engine\PhysicsEngine\obj\Debug\net10.0\refint\PhysicsEngine.dll
C:\Users\maxwes08\source\repos\Physics-Engine\PhysicsEngine\obj\Debug\net10.0\PhysicsEngine.pdb
C:\Users\maxwes08\source\repos\Physics-Engine\PhysicsEngine\obj\Debug\net10.0\PhysicsEngine.genruntimeconfig.cache
C:\Users\maxwes08\source\repos\Physics-Engine\PhysicsEngine\obj\Debug\net10.0\ref\PhysicsEngine.dll

View File

@@ -1 +1 @@
e7eef5f4e79a0494c21170ebb5e4e3181fcde6e607179c48869e445b1eefb095
37ea7c12f0356941dc732812414abe750a46377a93f758cd17f2e72c58cb3a80

View File

@@ -1,17 +1,17 @@
{
"format": 1,
"restore": {
"C:\\Users\\maxwes08\\source\\repos\\Physics-Engine\\Physics-Engine\\PhysicsEngine\\PhysicsEngine.csproj": {}
"C:\\Users\\maxwes08\\source\\repos\\Physics-Engine\\PhysicsEngine\\PhysicsEngine.csproj": {}
},
"projects": {
"C:\\Users\\maxwes08\\source\\repos\\Physics-Engine\\Physics-Engine\\PhysicsEngine\\PhysicsEngine.csproj": {
"C:\\Users\\maxwes08\\source\\repos\\Physics-Engine\\PhysicsEngine\\PhysicsEngine.csproj": {
"version": "1.0.0",
"restore": {
"projectUniqueName": "C:\\Users\\maxwes08\\source\\repos\\Physics-Engine\\Physics-Engine\\PhysicsEngine\\PhysicsEngine.csproj",
"projectUniqueName": "C:\\Users\\maxwes08\\source\\repos\\Physics-Engine\\PhysicsEngine\\PhysicsEngine.csproj",
"projectName": "PhysicsEngine",
"projectPath": "C:\\Users\\maxwes08\\source\\repos\\Physics-Engine\\Physics-Engine\\PhysicsEngine\\PhysicsEngine.csproj",
"projectPath": "C:\\Users\\maxwes08\\source\\repos\\Physics-Engine\\PhysicsEngine\\PhysicsEngine.csproj",
"packagesPath": "C:\\Users\\maxwes08\\.nuget\\packages\\",
"outputPath": "C:\\Users\\maxwes08\\source\\repos\\Physics-Engine\\Physics-Engine\\PhysicsEngine\\obj\\",
"outputPath": "C:\\Users\\maxwes08\\source\\repos\\Physics-Engine\\PhysicsEngine\\obj\\",
"projectStyle": "PackageReference",
"configFilePaths": [
"C:\\Users\\maxwes08\\AppData\\Roaming\\NuGet\\NuGet.Config",

View File

@@ -74,11 +74,11 @@
"project": {
"version": "1.0.0",
"restore": {
"projectUniqueName": "C:\\Users\\maxwes08\\source\\repos\\Physics-Engine\\Physics-Engine\\PhysicsEngine\\PhysicsEngine.csproj",
"projectUniqueName": "C:\\Users\\maxwes08\\source\\repos\\Physics-Engine\\PhysicsEngine\\PhysicsEngine.csproj",
"projectName": "PhysicsEngine",
"projectPath": "C:\\Users\\maxwes08\\source\\repos\\Physics-Engine\\Physics-Engine\\PhysicsEngine\\PhysicsEngine.csproj",
"projectPath": "C:\\Users\\maxwes08\\source\\repos\\Physics-Engine\\PhysicsEngine\\PhysicsEngine.csproj",
"packagesPath": "C:\\Users\\maxwes08\\.nuget\\packages\\",
"outputPath": "C:\\Users\\maxwes08\\source\\repos\\Physics-Engine\\Physics-Engine\\PhysicsEngine\\obj\\",
"outputPath": "C:\\Users\\maxwes08\\source\\repos\\Physics-Engine\\PhysicsEngine\\obj\\",
"projectStyle": "PackageReference",
"configFilePaths": [
"C:\\Users\\maxwes08\\AppData\\Roaming\\NuGet\\NuGet.Config",

View File

@@ -1,8 +1,8 @@
{
"version": 2,
"dgSpecHash": "+GLC3EnolcY=",
"dgSpecHash": "OBnd1zSM6H8=",
"success": true,
"projectFilePath": "C:\\Users\\maxwes08\\source\\repos\\Physics-Engine\\Physics-Engine\\PhysicsEngine\\PhysicsEngine.csproj",
"projectFilePath": "C:\\Users\\maxwes08\\source\\repos\\Physics-Engine\\PhysicsEngine\\PhysicsEngine.csproj",
"expectedPackageFiles": [
"C:\\Users\\maxwes08\\.nuget\\packages\\raylib-cs\\8.0.0\\raylib-cs.8.0.0.nupkg.sha512"
],