115 lines
3.3 KiB
C#
115 lines
3.3 KiB
C#
using Godot;
|
|
using GodotStateCharts;
|
|
|
|
namespace Movementtests.godot_state_charts_examples.csharp;
|
|
|
|
/// <summary>
|
|
/// This is an example of how to use the state chart from C#.
|
|
/// </summary>
|
|
// ReSharper disable once CheckNamespace
|
|
public partial class CSharpExample : Node2D
|
|
{
|
|
|
|
private StateChart _stateChart;
|
|
private Label _feelLabel;
|
|
private int _health = 20;
|
|
private StateChartState _poisonedStateChartState;
|
|
|
|
public override void _Ready()
|
|
{
|
|
// Get the state chart node and wrap it in a StateChart object, so we can easily
|
|
// interact with it from C#.
|
|
_stateChart = StateChart.Of(GetNode("%StateChart"));
|
|
|
|
// Get the poisoned state node and wrap it in a State object, so we can easily
|
|
// interact with it from C#.
|
|
_poisonedStateChartState = StateChartState.Of(GetNode("%Poisoned"));
|
|
|
|
// The the UI label.
|
|
_feelLabel = GetNode<Label>("%FeelLabel");
|
|
RefreshUi();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Called when the drink poison button is pressed.
|
|
/// </summary>
|
|
private void OnDrinkPoisonButtonPressed()
|
|
{
|
|
// This uses the regular API to interact with the state chart.
|
|
var currentPoisonCount = _stateChart.GetExpressionProperty("poison_count", 0);
|
|
currentPoisonCount += 3; // we add three rounds worth of poison
|
|
|
|
_stateChart.SetExpressionProperty("poison_count", currentPoisonCount);
|
|
_stateChart.SendEvent("poisoned");
|
|
|
|
// Ends the round
|
|
EndRound();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Called when the drink cure button is pressed.
|
|
/// </summary>
|
|
private void OnDrinkCureButtonPressed()
|
|
{
|
|
// Here we use some custom-made extension methods from StateChartExt.cs to have a nicer API
|
|
// that is specific to our game. This avoids having to use strings for property names and
|
|
// event names and it also helps with type safety and when you need to find all places where
|
|
// a certain property is set or an event is sent.
|
|
_stateChart.SetPoisonCount(0);
|
|
_stateChart.SendCuredEvent();
|
|
|
|
// Ends the round
|
|
EndRound();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Called when the next round button is pressed.
|
|
/// </summary>
|
|
private void OnWaitButtonPressed()
|
|
{
|
|
// Ends the round
|
|
EndRound();
|
|
}
|
|
|
|
|
|
private void EndRound()
|
|
{
|
|
// then send a "next_round" event
|
|
_stateChart.SendEvent("next_round");
|
|
// and finally call Step to calculate this round's effects, based on the current state
|
|
_stateChart.Step();
|
|
|
|
// Then at the beginning of the next round, we reduce any poison count by 1
|
|
_stateChart.SetPoisonCount( Mathf.Max(0, _stateChart.GetPoisonCount() - 1));
|
|
|
|
// And update the UI
|
|
RefreshUi();
|
|
}
|
|
|
|
private void OnPoisonedStateStepped()
|
|
{
|
|
// when we step while poisoned, remove the amount of poison from our health (but not below 0)
|
|
_health = Mathf.Max(0, _health - _stateChart.GetPoisonCount());
|
|
}
|
|
|
|
private void OnNormalStateStepped()
|
|
{
|
|
// when we step while not poisoned, heal 1 health, up to a maximum of 20
|
|
_health = Mathf.Min(20, _health + 1);
|
|
}
|
|
|
|
|
|
private void RefreshUi()
|
|
{
|
|
_feelLabel.Text = $"Health: {_health} Poison: {_stateChart.GetPoisonCount()}";
|
|
}
|
|
|
|
private void OnDebugButtonPressed()
|
|
{
|
|
// States have an "Active" property that can be used to check if they are currently active.
|
|
// Note that you should usually not use this in your game code, as it sort of defeats the
|
|
// purpose of using a state chart. But it can be useful for debugging.
|
|
GD.Print("Are we poisoned? ", _poisonedStateChartState.Active ? "Yes" : "No");
|
|
}
|
|
|
|
} |