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(