In progress gameplay loop changes

This commit is contained in:
2025-04-15 00:33:59 -07:00
parent 03caa13ceb
commit 24b4227425
11 changed files with 108 additions and 29 deletions

View File

@@ -20,7 +20,6 @@ public partial class GameLogic
public Transition On(in Input.StartGame input) public Transition On(in Input.StartGame input)
{ {
Output(new Output.LoadMap());
return To<Playing>(); return To<Playing>();
} }

View File

@@ -17,6 +17,7 @@ public partial class GameLogic
OnAttach(() => OnAttach(() =>
{ {
Output(new Output.StartGame()); Output(new Output.StartGame());
Output(new Output.LoadMap());
}); });
} }

View File

@@ -8,12 +8,18 @@ public partial class GameLogic
public partial record State public partial record State
{ {
[Meta] [Meta]
public partial record Quit : State public partial record Quit : State, IGet<Input.GoToOverworld>
{ {
public Quit() public Quit()
{ {
this.OnEnter(() => Output(new Output.ShowLostScreen())); this.OnEnter(() => Output(new Output.ShowLostScreen()));
} }
public Transition On(in Input.GoToOverworld input)
{
Input(new Input.StartGame());
return To<Playing>();
}
} }
} }
} }

View File

@@ -6,6 +6,8 @@ namespace Zennysoft.Ma.Adapter;
public interface IPlayer : IKillable public interface IPlayer : IKillable
{ {
public void InitializePlayerState();
public void Attack(); public void Attack();
public void PlayerPause(); public void PlayerPause();

View File

@@ -1,14 +1,14 @@
@startuml EnemyLogic @startuml EnemyLogic
state "EnemyLogic State" as Zennysoft_Game_Ma_EnemyLogic_State { state "EnemyLogic State" as Zennysoft_Game_Ma_EnemyLogic_State {
state "Defeated" as Zennysoft_Game_Ma_EnemyLogic_State_Defeated
state "Alive" as Zennysoft_Game_Ma_EnemyLogic_State_Alive { state "Alive" as Zennysoft_Game_Ma_EnemyLogic_State_Alive {
state "Activated" as Zennysoft_Game_Ma_EnemyLogic_State_Activated { state "Activated" as Zennysoft_Game_Ma_EnemyLogic_State_Activated {
state "FollowPlayer" as Zennysoft_Game_Ma_EnemyLogic_State_FollowPlayer
state "Attacking" as Zennysoft_Game_Ma_EnemyLogic_State_Attacking state "Attacking" as Zennysoft_Game_Ma_EnemyLogic_State_Attacking
state "FollowPlayer" as Zennysoft_Game_Ma_EnemyLogic_State_FollowPlayer
state "Patrolling" as Zennysoft_Game_Ma_EnemyLogic_State_Patrolling state "Patrolling" as Zennysoft_Game_Ma_EnemyLogic_State_Patrolling
} }
state "Idle" as Zennysoft_Game_Ma_EnemyLogic_State_Idle state "Idle" as Zennysoft_Game_Ma_EnemyLogic_State_Idle
} }
state "Defeated" as Zennysoft_Game_Ma_EnemyLogic_State_Defeated
} }
Zennysoft_Game_Ma_EnemyLogic_State_Alive --> Zennysoft_Game_Ma_EnemyLogic_State_Attacking : AttackTimer Zennysoft_Game_Ma_EnemyLogic_State_Alive --> Zennysoft_Game_Ma_EnemyLogic_State_Attacking : AttackTimer

View File

@@ -78,7 +78,6 @@ public partial class Game : Node3D, IGame
{ {
_container = new SimpleInjector.Container(); _container = new SimpleInjector.Container();
Module.Bootstrap(_container); Module.Bootstrap(_container);
//_container.Verify();
GameRepo = _container.GetInstance<IGameRepo>(); GameRepo = _container.GetInstance<IGameRepo>();
GameLogic = _container.GetInstance<IGameLogic>(); GameLogic = _container.GetInstance<IGameLogic>();
@@ -164,6 +163,7 @@ public partial class Game : Node3D, IGame
{ {
GameRepo.Resume(); GameRepo.Resume();
InGameUI.Show(); InGameUI.Show();
Player.InitializePlayerState();
}) })
.Handle((in GameLogic.Output.GoToOverworld _) => .Handle((in GameLogic.Output.GoToOverworld _) =>
{ {

View File

@@ -38,7 +38,7 @@ stretch = true
[node name="SubViewport" type="SubViewport" parent="SubViewportContainer"] [node name="SubViewport" type="SubViewport" parent="SubViewportContainer"]
transparent_bg = true transparent_bg = true
handle_input_locally = false handle_input_locally = false
size = Vector2i(1280, 960) size = Vector2i(1920, 1080)
render_target_update_mode = 4 render_target_update_mode = 4
[node name="PauseContainer" type="Node3D" parent="SubViewportContainer/SubViewport"] [node name="PauseContainer" type="Node3D" parent="SubViewportContainer/SubViewport"]

View File

@@ -98,9 +98,8 @@ public partial class Player : CharacterBody3D, IPlayer, IProvide<ISaveChunk<Play
private DamageCalculator _damageCalculator; private DamageCalculator _damageCalculator;
#region Initialization #region Initialization
public void Initialize() public void InitializePlayerState()
{ {
AnimationPlayer.AnimationFinished += OnAnimationFinished;
_expToNextLevel = new Dictionary<int, int> _expToNextLevel = new Dictionary<int, int>
{ {
{ 2, 12 }, { 2, 12 },
@@ -112,15 +111,7 @@ public partial class Player : CharacterBody3D, IPlayer, IProvide<ISaveChunk<Play
{ 8, 609 } { 8, 609 }
}; };
_damageCalculator = new DamageCalculator(); _damageCalculator = new DamageCalculator();
}
public void Setup()
{
var container = new SimpleInjector.Container();
container.Register<IPlayerLogic, PlayerLogic>(Lifestyle.Singleton);
//container.Verify();
Settings = new PlayerLogic.Settings() { RotationSpeed = PlayerStatResource.RotationSpeed, MoveSpeed = PlayerStatResource.MoveSpeed, Acceleration = PlayerStatResource.Acceleration };
Stats = new PlayerStatController(); Stats = new PlayerStatController();
Stats.Init( Stats.Init(
new PlayerStats new PlayerStats
@@ -143,12 +134,6 @@ public partial class Player : CharacterBody3D, IPlayer, IProvide<ISaveChunk<Play
Inventory = new Inventory(); Inventory = new Inventory();
PlayerLogic = container.GetInstance<IPlayerLogic>();
PlayerLogic.Set(this as IPlayer);
PlayerLogic.Set(Settings);
PlayerLogic.Set(Stats);
PlayerLogic.Set(_gameRepo);
var defaultWeapon = new Weapon var defaultWeapon = new Weapon
{ {
Stats = _defaultWeapon Stats = _defaultWeapon
@@ -160,19 +145,35 @@ public partial class Player : CharacterBody3D, IPlayer, IProvide<ISaveChunk<Play
Inventory.TryAdd(defaultWeapon); Inventory.TryAdd(defaultWeapon);
Inventory.TryAdd(defaultArmor); Inventory.TryAdd(defaultArmor);
Equip(defaultWeapon);
Equip(defaultArmor);
EquippedWeapon.Sync += EquippedWeapon_Sync; EquippedWeapon.Sync += EquippedWeapon_Sync;
EquippedArmor.Sync += EquippedArmor_Sync; EquippedArmor.Sync += EquippedArmor_Sync;
EquippedAccessory.Sync += EquippedAccessory_Sync; EquippedAccessory.Sync += EquippedAccessory_Sync;
Stats.CurrentHP.Sync += CurrentHP_Sync; Stats.CurrentHP.Sync += CurrentHP_Sync;
Stats.CurrentExp.Sync += CurrentEXP_Sync; Stats.CurrentExp.Sync += CurrentEXP_Sync;
Equip(defaultWeapon);
Equip(defaultArmor);
HealthTimer.WaitTime = _healthTimerWaitTime; HealthTimer.WaitTime = _healthTimerWaitTime;
HealthTimer.Timeout += OnHealthTimerTimeout; HealthTimer.Timeout += OnHealthTimerTimeout;
Hitbox.AreaEntered += Hitbox_AreaEntered; Hitbox.AreaEntered += Hitbox_AreaEntered;
CollisionDetector.AreaEntered += CollisionDetector_AreaEntered; CollisionDetector.AreaEntered += CollisionDetector_AreaEntered;
AnimationPlayer.AnimationFinished += OnAnimationFinished;
}
public void Setup()
{
var container = new SimpleInjector.Container();
container.Register<IPlayerLogic, PlayerLogic>(Lifestyle.Singleton);
//container.Verify();
Settings = new PlayerLogic.Settings() { RotationSpeed = PlayerStatResource.RotationSpeed, MoveSpeed = PlayerStatResource.MoveSpeed, Acceleration = PlayerStatResource.Acceleration };
PlayerLogic = container.GetInstance<IPlayerLogic>();
PlayerLogic.Set(this as IPlayer);
PlayerLogic.Set(Settings);
PlayerLogic.Set(Stats);
PlayerLogic.Set(_gameRepo);
} }
public void OnResolved() public void OnResolved()
@@ -363,7 +364,21 @@ public partial class Player : CharacterBody3D, IPlayer, IProvide<ISaveChunk<Play
Stats.SetCurrentExp(newCurrentExp); Stats.SetCurrentExp(newCurrentExp);
} }
public void Die() => PlayerLogic.Input(new PlayerLogic.Input.Die()); public void Die()
{
EquippedWeapon.Sync -= EquippedWeapon_Sync;
EquippedArmor.Sync -= EquippedArmor_Sync;
EquippedAccessory.Sync -= EquippedAccessory_Sync;
Stats.CurrentHP.Sync -= CurrentHP_Sync;
Stats.CurrentExp.Sync -= CurrentEXP_Sync;
HealthTimer.WaitTime = _healthTimerWaitTime;
HealthTimer.Timeout -= OnHealthTimerTimeout;
Hitbox.AreaEntered -= Hitbox_AreaEntered;
CollisionDetector.AreaEntered -= CollisionDetector_AreaEntered;
AnimationPlayer.AnimationFinished -= OnAnimationFinished;
PlayerLogic.Input(new PlayerLogic.Input.Die());
}
public override void _UnhandledInput(InputEvent @event) public override void _UnhandledInput(InputEvent @event)
{ {

View File

@@ -17,9 +17,9 @@ script = ExtResource("2_xq68d")
RotationSpeed = 1.5 RotationSpeed = 1.5
MoveSpeed = 8.0 MoveSpeed = 8.0
Acceleration = 1.0 Acceleration = 1.0
CurrentHP = 50 CurrentHP = 100
MaximumHP = 100 MaximumHP = 100
CurrentVT = 90 CurrentVT = 0
MaximumVT = 90 MaximumVT = 90
CurrentExp = 0 CurrentExp = 0
ExpToNextLevel = 10 ExpToNextLevel = 10

View File

@@ -2,6 +2,7 @@ using Chickensoft.AutoInject;
using Chickensoft.GodotNodeInterfaces; using Chickensoft.GodotNodeInterfaces;
using Chickensoft.Introspection; using Chickensoft.Introspection;
using Godot; using Godot;
using Zennysoft.Ma.Adapter;
namespace Zennysoft.Game.Ma; namespace Zennysoft.Game.Ma;
@@ -16,8 +17,40 @@ public partial class DeathMenu : Control, IDeathMenu
{ {
public override void _Notification(int what) => this.Notify(what); public override void _Notification(int what) => this.Notify(what);
[Dependency] Game Game => this.DependOn<Game>();
[Node] public IAnimationPlayer AnimationPlayer { get; set; } = default!; [Node] public IAnimationPlayer AnimationPlayer { get; set; } = default!;
[Node] public IButton Continue { get; set; } = default!;
[Node] public IButton Exit { get; set; } = default!;
public void OnReady()
{
Continue.Pressed += Continue_Pressed;
Exit.Pressed += Exit_Pressed;
VisibilityChanged += DeathMenu_VisibilityChanged;
}
private void DeathMenu_VisibilityChanged()
{
if (Visible)
Continue.CallDeferred(MethodName.GrabFocus, []);
else
ReleaseFocus();
}
private void Exit_Pressed()
{
GetTree().Quit();
}
private void Continue_Pressed()
{
FadeOut();
Game.GameLogic.Input(new GameLogic.Input.GoToOverworld());
}
public void FadeIn() => AnimationPlayer.Play("fade_in"); public void FadeIn() => AnimationPlayer.Play("fade_in");
public void FadeOut() => AnimationPlayer.Play("fade_out"); public void FadeOut() => AnimationPlayer.Play("fade_out");

View File

@@ -90,10 +90,33 @@ anchor_bottom = 1.0
grow_horizontal = 2 grow_horizontal = 2
grow_vertical = 2 grow_vertical = 2
[node name="GameOverPlaceholder" type="Label" parent="CenterContainer"] [node name="VBoxContainer" type="VBoxContainer" parent="CenterContainer"]
layout_mode = 2
[node name="GameOverPlaceholder" type="Label" parent="CenterContainer/VBoxContainer"]
layout_mode = 2 layout_mode = 2
theme_override_colors/font_color = Color(0.545098, 0, 0, 1) theme_override_colors/font_color = Color(0.545098, 0, 0, 1)
theme_override_constants/outline_size = 12 theme_override_constants/outline_size = 12
theme_override_fonts/font = ExtResource("2_ip5p6") theme_override_fonts/font = ExtResource("2_ip5p6")
theme_override_font_sizes/font_size = 72 theme_override_font_sizes/font_size = 72
text = "Game Over" text = "Game Over"
[node name="Continue" type="Button" parent="CenterContainer/VBoxContainer"]
unique_name_in_owner = true
process_mode = 3
layout_mode = 2
focus_neighbor_top = NodePath(".")
focus_neighbor_bottom = NodePath("../Exit")
focus_next = NodePath("../Exit")
focus_previous = NodePath(".")
text = "Continue"
[node name="Exit" type="Button" parent="CenterContainer/VBoxContainer"]
unique_name_in_owner = true
process_mode = 3
layout_mode = 2
focus_neighbor_top = NodePath("../Continue")
focus_neighbor_bottom = NodePath(".")
focus_next = NodePath(".")
focus_previous = NodePath("../Continue")
text = "Exit"