From 9f67c478a278f4315d8582845acd203ffe7ad2fb Mon Sep 17 00:00:00 2001 From: Leonid Pershin Date: Fri, 12 Jun 2026 13:29:49 +0300 Subject: [PATCH] Zoom the god camera toward the cursor The mouse-wheel zoom now keeps the world point under the cursor fixed (cursor-anchored zoom) by shifting the camera position after applying the new zoom, instead of zooming around the camera centre. GodCameraSystem takes the renderer to map the cursor to world space. Co-Authored-By: Claude Opus 4.8 --- src/LittleSim/Scenes/WorldScene.cs | 4 +++- src/LittleSim/Sim/SimSystems.cs | 21 ++++++++++++++++++--- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/src/LittleSim/Scenes/WorldScene.cs b/src/LittleSim/Scenes/WorldScene.cs index 6ee589c..c67d286 100644 --- a/src/LittleSim/Scenes/WorldScene.cs +++ b/src/LittleSim/Scenes/WorldScene.cs @@ -101,7 +101,9 @@ public sealed class WorldScene : Scene RegisterCommands(console, content, atlases); UpdateSystems.Add(new PlantGrowthSystem(plants, calendar, CellSize)); - UpdateSystems.Add(new GodCameraSystem(camera, input, console, () => _pause.IsOpen)); + UpdateSystems.Add( + new GodCameraSystem(camera, input, renderer, console, () => _pause.IsOpen) + ); UpdateSystems.Add( new HudSystem(Context, content.Languages, hudLabel, "hud.world", _config.Seed, calendar) ); diff --git a/src/LittleSim/Sim/SimSystems.cs b/src/LittleSim/Sim/SimSystems.cs index 76afa3e..76140cd 100644 --- a/src/LittleSim/Sim/SimSystems.cs +++ b/src/LittleSim/Sim/SimSystems.cs @@ -117,12 +117,14 @@ public sealed class SeparationSystem(MrGameEng.Collisions.CollisionWorld world) } /// -/// Камера бога: WASD/стрелки — панорамирование, колесо — зум. Молчит, пока открыта консоль -/// или активен (например, открыто меню-пауза). +/// Камера бога: WASD/стрелки — панорамирование, колесо — зум к курсору (мировая точка под мышью +/// остаётся под мышью). Молчит, пока открыта консоль или активен +/// (например, открыто меню-пауза). /// public sealed class GodCameraSystem( Entity cameraEntity, InputManager input, + Renderer2D renderer, MrGameEng.DevConsole.DevConsole console, Func? blocked = null ) : BaseSystem @@ -146,7 +148,20 @@ public sealed class GodCameraSystem( camera.Position += pan * (500f / camera.Zoom) * Tick.deltaTime; } - camera.Zoom = Math.Clamp(camera.Zoom * (1f + input.WheelDelta * 0.001f), 0.4f, 8f); + if (input.WheelDelta != 0) + { + var oldZoom = camera.Zoom; + var newZoom = Math.Clamp(oldZoom * (1f + input.WheelDelta * 0.001f), 0.4f, 8f); + if (newZoom != oldZoom) + { + // Точка мира под курсором до зума; после — сдвигаем камеру, чтобы она осталась там же. + var anchor = renderer.ScreenToWorld( + new Vector2(input.MousePosition.X, input.MousePosition.Y) + ); + camera.Zoom = newZoom; + camera.Position = anchor - (anchor - camera.Position) * (oldZoom / newZoom); + } + } } private static float Axis(