diff --git a/Scripts/Entities/Player.cs b/Scripts/Entities/Player.cs index ff6fc99..fc57953 100644 --- a/Scripts/Entities/Player.cs +++ b/Scripts/Entities/Player.cs @@ -11,6 +11,68 @@ public partial class Player : CharacterBody2D [Export] public float SprintAcceleration = 1800.0f; // Slightly faster acceleration when sprinting [Export] public float Deceleration = 1200.0f; [Export] public float RotationSpeed = 3.0f; + [Export] public float MinZoom = 0.5f; + [Export] public float MaxZoom = 2.0f; + [Export] public float BaseZoomSpeed = 0.1f; + [Export] public float MaxZoomSpeed = 0.5f; + [Export] public float ZoomAcceleration = 0.05f; + [Export] public float ZoomDecay = 0.9f; + [Export] public float ZoomSmoothing = 10.0f; + + private Camera2D _camera; + private Vector2 _cameraTargetZoom = Vector2.One; + private float _currentZoomSpeed; + private int _lastZoomDirection; + private double _lastZoomTime; + + public override void _Ready() + { + _camera = GetNode("Camera2D"); + _cameraTargetZoom = _camera.Zoom; + } + + public override void _Input(InputEvent @event) + { + // Handle mouse wheel zoom + if (@event is InputEventMouseButton mouseEvent) + { + switch (mouseEvent.ButtonIndex) + { + case MouseButton.WheelDown when mouseEvent.Pressed: + HandleZoomInput(1); + break; + case MouseButton.WheelUp when mouseEvent.Pressed: + HandleZoomInput(-1); + break; + } + } + } + + private void HandleZoomInput(int direction) + { + var currentTime = Time.GetTicksMsec(); + + // If same direction as last time, accelerate + if (direction == _lastZoomDirection && (currentTime - _lastZoomTime) < 300) + { + _currentZoomSpeed = Mathf.Min(_currentZoomSpeed + ZoomAcceleration, MaxZoomSpeed); + } + else + { + _currentZoomSpeed = BaseZoomSpeed; + } + + _lastZoomDirection = direction; + _lastZoomTime = currentTime; + + // Apply zoom with current speed + var zoomFactor = 1.0f + (_currentZoomSpeed * -direction); + _cameraTargetZoom = _camera.Zoom * zoomFactor; + + // Clamp target zoom + _cameraTargetZoom.X = Mathf.Clamp(_cameraTargetZoom.X, MinZoom, MaxZoom); + _cameraTargetZoom.Y = Mathf.Clamp(_cameraTargetZoom.Y, MinZoom, MaxZoom); + } public override void _Process(double delta) { @@ -18,6 +80,16 @@ public partial class Player : CharacterBody2D var mousePos = GetGlobalMousePosition(); var direction = GlobalPosition.DirectionTo(mousePos); Rotation = direction.Angle(); + + // Smoothly interpolate to target zoom + var deltaF = (float)delta; + _camera.Zoom = _camera.Zoom.Lerp(_cameraTargetZoom, ZoomSmoothing * deltaF); + + // Decay zoom speed when not zooming + if ((Time.GetTicksMsec() - _lastZoomTime) > 300) + { + _currentZoomSpeed = Mathf.Max(_currentZoomSpeed * ZoomDecay, BaseZoomSpeed); + } } public override void _PhysicsProcess(double delta) diff --git a/Scripts/System/NaturalResourceGenerator.cs b/Scripts/System/NaturalResourceGenerator.cs index d7acd03..96df218 100644 --- a/Scripts/System/NaturalResourceGenerator.cs +++ b/Scripts/System/NaturalResourceGenerator.cs @@ -51,7 +51,7 @@ public partial class NaturalResourceGenerator : Node2D { // Create a copy of ground tiles for iteration var groundTilesToProcess = new List(_groundTiles); - + // Place stone veins foreach (var cell in groundTilesToProcess) { @@ -64,7 +64,7 @@ public partial class NaturalResourceGenerator : Node2D // Create a copy of stone tiles for iteration var stoneTilesToProcess = new List(_stoneTiles); - + // Place iron veins within stone foreach (var stoneCell in stoneTilesToProcess) { diff --git a/project.godot b/project.godot index e102079..210c7f7 100644 --- a/project.godot +++ b/project.godot @@ -70,6 +70,16 @@ move_sprint={ "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194325,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) ] } +camera_zoom_in={ +"deadzone": 0.2, +"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":8,"position":Vector2(437, 34),"global_position":Vector2(456, 130),"factor":0.0300018,"button_index":4,"canceled":false,"pressed":true,"double_click":false,"script":null) +] +} +camera_zoom_out={ +"deadzone": 0.2, +"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":16,"position":Vector2(583, 50),"global_position":Vector2(602, 146),"factor":0.437677,"button_index":5,"canceled":false,"pressed":true,"double_click":false,"script":null) +] +} [rendering]