From 871dd5014b357d072c339c3bd586ff5a56a8631e Mon Sep 17 00:00:00 2001 From: Jesus Castro Date: Thu, 18 Dec 2025 01:00:17 +0800 Subject: [PATCH] Implement debug switching --- Assets/Scripts/Services/GameBoardService.cs | 46 +++++++++++++++++++ Assets/Scripts/Services/InputService.cs | 23 ++++++++-- .../Services/Interfaces/IGameBoardService.cs | 1 + .../Services/Interfaces/IInputService.cs | 1 + Assets/Scripts/Services/LevelEntryPoint.cs | 5 ++ 5 files changed, 73 insertions(+), 3 deletions(-) diff --git a/Assets/Scripts/Services/GameBoardService.cs b/Assets/Scripts/Services/GameBoardService.cs index 997cc76..c700c8c 100644 --- a/Assets/Scripts/Services/GameBoardService.cs +++ b/Assets/Scripts/Services/GameBoardService.cs @@ -155,6 +155,52 @@ namespace Services { this.currentState = GameState.Move; return true; } + + public async UniTask TrySwitch(Vector2Int position) { + Gem gem = this.gameBoard.GetGemAt(position); + if(gem == null) + return false; + + GemType[] normalTypes = Enum.GetValues(typeof(GemType)) + .Cast() + .Where(t => t != GemType.Bomb) + .ToArray(); + + if (normalTypes.Length == 0) + return false; + + bool nextIsBomb; + GemType nextTypeOrMatchColor; + + if (gem.Type != GemType.Bomb) { + int index = Array.IndexOf(normalTypes, gem.Type); + if (index < 0) index = 0; + + if (index < normalTypes.Length - 1) { + nextIsBomb = false; + nextTypeOrMatchColor = normalTypes[index + 1]; + } else { + nextIsBomb = true; + nextTypeOrMatchColor = normalTypes[0]; + } + } else { + int idx = Array.IndexOf(normalTypes, gem.MatchColor); + if (idx < 0) idx = 0; + + if (idx < normalTypes.Length - 1) { + nextIsBomb = true; + nextTypeOrMatchColor = normalTypes[idx + 1]; + } else { + nextIsBomb = false; + nextTypeOrMatchColor = normalTypes[0]; + } + } + + // Replace both model+view by releasing current and respawning at same position. + ReleaseMatchedGems(position); + SpawnGemGameObject(SetGemAt(position, nextTypeOrMatchColor, nextIsBomb), nextIsBomb); + return true; + } private void ApplySwap(Vector2Int from, Vector2Int to) { Gem fromGem = this.gameBoard.GetGemAt(from); diff --git a/Assets/Scripts/Services/InputService.cs b/Assets/Scripts/Services/InputService.cs index fde99a8..f6295dc 100644 --- a/Assets/Scripts/Services/InputService.cs +++ b/Assets/Scripts/Services/InputService.cs @@ -6,6 +6,7 @@ namespace Services { public class InputService : MonoBehaviour, IInputService { public event Action OnSwapRequested; + public event Action OnSwitchRequested; private Camera inputCamera; private Vector2 pointerDownScreenPos; @@ -21,14 +22,14 @@ namespace Services { private void Update() { - if (TryGetPrimaryPointerState(out var isDown, out var screenPos)) + if (TryGetPrimaryPointerState(out bool isDown, out Vector2 screenPos)) { if (!this.isPointerDown && isDown) { - pointerDownScreenPos = screenPos; + this.pointerDownScreenPos = screenPos; } if (this.isPointerDown && !isDown) { - TryEmitSwap(pointerDownScreenPos, screenPos); + TryEmitSwap(this.pointerDownScreenPos, screenPos); } this.isPointerDown = isDown; @@ -38,6 +39,12 @@ namespace Services { // No pointer available this frame (rare). Ensure we don't get stuck. this.isPointerDown = false; } + + #if UNITY_EDITOR + if (TryGetSecondaryPointerClick(out screenPos)) { + OnSwitchRequested?.Invoke(WorldToCell(this.inputCamera.ScreenToWorldPoint(screenPos))); + } + #endif } private void TryEmitSwap(Vector2 downScreen, Vector2 upScreen) @@ -105,5 +112,15 @@ namespace Services { isDown = Input.GetMouseButton(0); return true; } + + private static bool TryGetSecondaryPointerClick(out Vector2 screenPosition) { + if (Input.GetMouseButtonDown(1)) { + screenPosition = Input.mousePosition; + return true; + } + + screenPosition = Input.mousePosition; + return false; + } } } \ No newline at end of file diff --git a/Assets/Scripts/Services/Interfaces/IGameBoardService.cs b/Assets/Scripts/Services/Interfaces/IGameBoardService.cs index 143e627..a35eab8 100644 --- a/Assets/Scripts/Services/Interfaces/IGameBoardService.cs +++ b/Assets/Scripts/Services/Interfaces/IGameBoardService.cs @@ -6,5 +6,6 @@ namespace Services.Interfaces { void Setup(); UniTask TrySwap(Vector2Int from, Vector2Int to); + UniTask TrySwitch(Vector2Int position); } } \ No newline at end of file diff --git a/Assets/Scripts/Services/Interfaces/IInputService.cs b/Assets/Scripts/Services/Interfaces/IInputService.cs index 07cf9cb..47d974b 100644 --- a/Assets/Scripts/Services/Interfaces/IInputService.cs +++ b/Assets/Scripts/Services/Interfaces/IInputService.cs @@ -4,5 +4,6 @@ using UnityEngine; namespace Services.Interfaces { public interface IInputService { event Action OnSwapRequested; + event Action OnSwitchRequested; } } \ No newline at end of file diff --git a/Assets/Scripts/Services/LevelEntryPoint.cs b/Assets/Scripts/Services/LevelEntryPoint.cs index 602e543..5c1e781 100644 --- a/Assets/Scripts/Services/LevelEntryPoint.cs +++ b/Assets/Scripts/Services/LevelEntryPoint.cs @@ -25,10 +25,15 @@ namespace Services { this.gameBoardService.Setup(); this.inputService.OnSwapRequested += HandleSwapRequest; + this.inputService.OnSwitchRequested += HandleSwitchRequest; } private void HandleSwapRequest(Vector2Int from, Vector2Int to) { this.gameBoardService.TrySwap(from, to); } + + private void HandleSwitchRequest(Vector2Int position) { + this.gameBoardService.TrySwitch(position); + } } } \ No newline at end of file