From 50ba75c55e9e7a483c8a98a9e3f88214678a5244 Mon Sep 17 00:00:00 2001 From: Matheus Date: Sat, 30 Aug 2025 23:21:20 -0300 Subject: Múltiplas formas de input MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/Game.cs | 3 +- scripts/actors/Actor.cs | 15 +++++++- scripts/input/BaseInputHandler.cs | 19 ++++++++++ scripts/input/GameOverInputHandler.cs | 13 +++++++ scripts/input/GameOverInputHandler.cs.uid | 1 + scripts/input/InputHandler.cs | 62 +++++++++++++++++-------------- scripts/input/InputHandler.cs.uid | 2 +- scripts/input/MainGameInputHandler.cs | 35 +++++++++++++++++ scripts/input/MainGameInputHandler.cs.uid | 1 + 9 files changed, 121 insertions(+), 30 deletions(-) create mode 100644 scripts/input/BaseInputHandler.cs create mode 100644 scripts/input/GameOverInputHandler.cs create mode 100644 scripts/input/GameOverInputHandler.cs.uid create mode 100644 scripts/input/MainGameInputHandler.cs create mode 100644 scripts/input/MainGameInputHandler.cs.uid (limited to 'scripts') diff --git a/scripts/Game.cs b/scripts/Game.cs index 4dc7a34..981699d 100644 --- a/scripts/Game.cs +++ b/scripts/Game.cs @@ -34,6 +34,7 @@ public partial class Game : Node { Camera2D camera = GetNode("Camera2D"); RemoveChild(camera); player.HealthChanged += (int hp, int maxHp) => ui.OnHealthChanged(hp, maxHp); + player.Died += () => inputHandler.SetInputHandler(InputHandlers.GameOver); player.AddChild(camera); @@ -80,7 +81,7 @@ public partial class Game : Node { } /// - /// Executa um turno para cada ator no mapa. + /// Executa turnos para cada ator no mapa. /// private void HandleEnemyTurns() { foreach (Actor actor in Map.Map_Data.Actors) { diff --git a/scripts/actors/Actor.cs b/scripts/actors/Actor.cs index afa6989..06cfd69 100644 --- a/scripts/actors/Actor.cs +++ b/scripts/actors/Actor.cs @@ -6,9 +6,21 @@ using Godot; [GlobalClass] public abstract partial class Actor : Sprite2D { + /// + /// Sinal emitido toda vez que o HP mudar. + /// + /// Novo HP + /// Quantidade máxima de HP. [Signal] public delegate void HealthChangedEventHandler(int hp, int maxHp); + /// + /// Sinal emitido se o ator morrer. + /// + [Signal] + public delegate void DiedEventHandler(); + + /// /// A definição do ator possui caracterísitcas padrões que definem /// o ator em questão. @@ -229,7 +241,8 @@ public abstract partial class Actor : Sprite2D Texture = definition.deathTexture; blocksMovement = false; ZIndex = 0; - actorName = $"Restos mortais de ${actorName}"; + actorName = $"Restos mortais de {actorName}"; Map_Data.UnregisterBlockingActor(this); + EmitSignal(SignalName.Died); } } \ No newline at end of file diff --git a/scripts/input/BaseInputHandler.cs b/scripts/input/BaseInputHandler.cs new file mode 100644 index 0000000..4ba25d7 --- /dev/null +++ b/scripts/input/BaseInputHandler.cs @@ -0,0 +1,19 @@ +using Godot; + +/// +/// Classe base para obter ações do usuário. +/// É interessante ter mais de um objeto para obter ações de +/// usuário porque permite limitar certas ações para +/// certos estados do jogo. Atualmente, o jogo +/// possui somente dois estados: Com jogador vivo e com jogador morto. +/// Mas isto pode aumentar. +/// +public abstract partial class BaseInputHandler : Node { + + /// + /// Obtém uma ação do usuári conforme input. + /// + /// Jogador + /// Ação que o jogador escolheu, nulo se nenhuma. + public abstract Action GetAction(Player player); +} diff --git a/scripts/input/GameOverInputHandler.cs b/scripts/input/GameOverInputHandler.cs new file mode 100644 index 0000000..5e41daf --- /dev/null +++ b/scripts/input/GameOverInputHandler.cs @@ -0,0 +1,13 @@ +using Godot; + +/// +/// Esquema de controles para quando o jogador está morto. +/// +public partial class GameOverInputHandler : BaseInputHandler { + + // Por enquanto não tem nada. + public override Action GetAction(Player player) + { + return null; + } +} \ No newline at end of file diff --git a/scripts/input/GameOverInputHandler.cs.uid b/scripts/input/GameOverInputHandler.cs.uid new file mode 100644 index 0000000..14ddfd8 --- /dev/null +++ b/scripts/input/GameOverInputHandler.cs.uid @@ -0,0 +1 @@ +uid://ogqlb3purl6n diff --git a/scripts/input/InputHandler.cs b/scripts/input/InputHandler.cs index 838790e..873276f 100644 --- a/scripts/input/InputHandler.cs +++ b/scripts/input/InputHandler.cs @@ -1,36 +1,44 @@ -using System.Numerics; using Godot; +public enum InputHandlers +{ + MainGame, + GameOver +} + /// -/// Obtém input do usuário. +/// Máquina de estado que obtém ações do usuário conforme o estado atual do jogo. /// -public partial class InputHandler : Node { - private readonly Godot.Collections.Dictionary directions = new() +public partial class InputHandler : Node +{ + private Godot.Collections.Dictionary inputHandlers = []; + + [Export] + private InputHandlers startingInputHandler; + + private BaseInputHandler selectedInputHandler; + + public override void _Ready() { - {"walk-up", Vector2I.Up}, - {"walk-down", Vector2I.Down}, - {"walk-left", Vector2I.Left}, - {"walk-right", Vector2I.Right}, - {"walk-up-right", Vector2I.Up + Vector2I.Right}, - {"walk-up-left", Vector2I.Up + Vector2I.Left}, - {"walk-down-right", Vector2I.Down + Vector2I.Right}, - {"walk-down-left", Vector2I.Down + Vector2I.Left}, - }; + base._Ready(); + // Controles para quando o jogador está vivo e jogando normalmente. + inputHandlers.Add(InputHandlers.MainGame, GetNode("MainGameInputHandler")); + // Controles para quando o jogador está morto. + inputHandlers.Add(InputHandlers.GameOver, GetNode("GameOverInputHandler")); + + SetInputHandler(startingInputHandler); + } + public Action GetAction(Player player) { - Action action = null; - - if (player.IsAlive) { - foreach (var direction in directions) { - if (Input.IsActionJustPressed(direction.Key)) { - action = new BumpAction(player, direction.Value); - } - } - - if (Input.IsActionJustPressed("skip-turn")) { - action = new WaitAction(player); - } - } + return selectedInputHandler.GetAction(player); + } - return action; + /// + /// Define o esquema de controle atual do jogo + /// para o estado informado. + /// + /// Estado do jogo. + public void SetInputHandler(InputHandlers inputhandler) { + selectedInputHandler = inputHandlers[inputhandler]; } } diff --git a/scripts/input/InputHandler.cs.uid b/scripts/input/InputHandler.cs.uid index 302a3b5..f61cdba 100644 --- a/scripts/input/InputHandler.cs.uid +++ b/scripts/input/InputHandler.cs.uid @@ -1 +1 @@ -uid://ejqmdbc0524i +uid://bxt6g7t1uvvia diff --git a/scripts/input/MainGameInputHandler.cs b/scripts/input/MainGameInputHandler.cs new file mode 100644 index 0000000..1c5ac6e --- /dev/null +++ b/scripts/input/MainGameInputHandler.cs @@ -0,0 +1,35 @@ +using Godot; + +/// +/// Esquema de controles principal do jogo. +/// +public partial class MainGameInputHandler : BaseInputHandler { + private readonly Godot.Collections.Dictionary directions = new() + { + {"walk-up", Vector2I.Up}, + {"walk-down", Vector2I.Down}, + {"walk-left", Vector2I.Left}, + {"walk-right", Vector2I.Right}, + {"walk-up-right", Vector2I.Up + Vector2I.Right}, + {"walk-up-left", Vector2I.Up + Vector2I.Left}, + {"walk-down-right", Vector2I.Down + Vector2I.Right}, + {"walk-down-left", Vector2I.Down + Vector2I.Left}, + }; + public override Action GetAction(Player player) { + Action action = null; + + if (player.IsAlive) { + foreach (var direction in directions) { + if (Input.IsActionJustPressed(direction.Key)) { + action = new BumpAction(player, direction.Value); + } + } + + if (Input.IsActionJustPressed("skip-turn")) { + action = new WaitAction(player); + } + } + + return action; + } +} diff --git a/scripts/input/MainGameInputHandler.cs.uid b/scripts/input/MainGameInputHandler.cs.uid new file mode 100644 index 0000000..302a3b5 --- /dev/null +++ b/scripts/input/MainGameInputHandler.cs.uid @@ -0,0 +1 @@ +uid://ejqmdbc0524i -- cgit v1.2.3