using UnityEngine; using Zenject; using FlappyBird.Gameplay.Pipes; namespace FlappyBird.Core { /// /// Pure C# service — owns all death side-effects. /// Subscribes to IGameStateManager.OnStateChanged at construction time /// and reacts when the state becomes GameOver. /// /// Side-effects on death: /// 1. Freeze the bird Rigidbody2D (velocity + gravity) /// 2. Reset the pipe spawner timer so pipes start cleanly on restart /// public sealed class DeathHandler : IDeathHandler, IInitializable { private readonly Rigidbody2D _birdRigidbody; private readonly IGameStateManager _gameStateManager; private readonly IPipeSpawner _pipeSpawner; public DeathHandler( Rigidbody2D birdRigidbody, IGameStateManager gameStateManager, IPipeSpawner pipeSpawner) { _birdRigidbody = birdRigidbody; _gameStateManager = gameStateManager; _pipeSpawner = pipeSpawner; } // ── IInitializable ───────────────────────────────────────────────── public void Initialize() { _gameStateManager.OnStateChanged += OnStateChanged; } // ── IDeathHandler ────────────────────────────────────────────────── /// public void HandleDeath() { FreezeBird(); _pipeSpawner.ResetTimer(); } // ── Private helpers ──────────────────────────────────────────────── private void OnStateChanged(GameState newState) { if (newState == GameState.Playing) UnfreezeBird(); } /// /// Kills velocity and disables gravity so the bird hangs in place /// during the GameOver freeze (Time.timeScale is 0, but we set this /// explicitly so the bird does not drop when timeScale resumes on restart). /// private void FreezeBird() { _birdRigidbody.linearVelocity = Vector2.zero; _birdRigidbody.angularVelocity = 0f; _birdRigidbody.gravityScale = 0f; } /// Restore gravity when a new game begins. private void UnfreezeBird() { _birdRigidbody.gravityScale = 1f; } } }