├── .gitignore
├── .zed
└── settings.json
├── LICENSE
├── README.md
├── godot-csharp
├── EntityComponent
│ ├── Components
│ │ ├── PowerReceiver.cs
│ │ └── PowerSource.cs
│ ├── Entities
│ │ ├── BatteryEntity.cs
│ │ ├── BatteryEntity.tscn
│ │ ├── GeneratorEntity.cs
│ │ └── GeneratorEntity.tscn
│ ├── Game.cs
│ ├── Game.tscn
│ ├── PowerSystem.cs
│ └── Shared
│ │ ├── battery_indicator.png
│ │ ├── battery_indicator.png.import
│ │ ├── tileset.svg
│ │ ├── tileset.svg.import
│ │ └── tileset.tres
├── Godot Design Pattern csharp demo.csproj
├── Godot Design Pattern csharp demo.csproj.old
├── Godot Design Pattern csharp demo.sln
├── Godot Design Pattern csharp demo.sln.old
├── Properties
│ └── AssemblyInfo.cs
├── Shared
│ ├── background.png
│ ├── background.png.import
│ ├── monserrate_bold.tres
│ ├── montserrat_extrabold.otf
│ ├── player.png
│ ├── player.png.import
│ ├── tileset_platformer.png
│ ├── tileset_platformer.png.import
│ └── tileset_platformer.tres
├── StateMachine
│ ├── Player
│ │ ├── Air.cs
│ │ ├── Idle.cs
│ │ ├── Player.cs
│ │ ├── Player.tscn
│ │ ├── PlayerState.cs
│ │ ├── Run.cs
│ │ └── StateMachine.cs
│ ├── State.cs
│ └── StateMachineDemoCSharp.tscn
├── default_env.tres
├── icon.png
├── icon.png.import
└── project.godot
├── godot
├── common
│ ├── background.png
│ ├── background.png.import
│ ├── monserrate_bold.tres
│ ├── montserrat_extrabold.otf
│ ├── montserrat_extrabold.otf.import
│ ├── player.png
│ ├── player.png.import
│ ├── tileset_platformer.png
│ ├── tileset_platformer.png.import
│ └── tileset_platformer.tres
├── default_env.tres
├── entity_component
│ ├── common
│ │ ├── battery_indicator.png
│ │ ├── battery_indicator.png.import
│ │ ├── tileset.svg
│ │ ├── tileset.svg.import
│ │ └── tileset.tres
│ ├── components
│ │ ├── power_receiver.gd
│ │ └── power_source.gd
│ ├── entities
│ │ ├── battery_entity.gd
│ │ ├── battery_entity.tscn
│ │ ├── generator_entity.gd
│ │ └── generator_entity.tscn
│ ├── game.gd
│ ├── game.tscn
│ └── power_system.gd
├── finite_state_machine
│ ├── demo_state_machine.tscn
│ ├── node_version
│ │ ├── player.gd
│ │ ├── player.tscn
│ │ ├── state.gd
│ │ ├── state_machine.gd
│ │ └── states
│ │ │ ├── falling.gd
│ │ │ ├── gliding.gd
│ │ │ ├── idle.gd
│ │ │ ├── jumping.gd
│ │ │ ├── player_state.gd
│ │ │ └── running.gd
│ ├── simple_version
│ │ ├── player_single_script.gd
│ │ └── player_single_script.tscn
│ └── without_states
│ │ └── player_without_states.gd
├── icon.png
├── icon.png.import
└── project.godot
└── images
└── design-patterns-banner.png
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | # Godot-specific ignores
3 | .import/
4 | .godot/
5 |
6 | # Mono-specific ignores
7 | .mono/
8 | data_*/
9 |
--------------------------------------------------------------------------------
/.zed/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "hard_tabs": true
3 | }
4 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 GDQuest
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Godot Design Patterns
2 |
3 | 
4 |
5 | This repository is a collection of programming patterns implemented in Godot.
6 |
7 | On our website, you will also find some free companion guides.
8 |
9 | Here are the ones we released already:
10 |
11 | - [Finite state machine in Godot 4](https://www.gdquest.com/tutorial/godot/design-patterns/finite-state-machine/)
12 | - [Entity Component pattern in Godot 3](https://www.gdquest.com/tutorial/godot/design-patterns/entity-component-pattern/)
13 |
14 | If you want to learn Godot and support our work, check out our [Godot courses](https://school.gdquest.com/).
--------------------------------------------------------------------------------
/godot-csharp/EntityComponent/Components/PowerReceiver.cs:
--------------------------------------------------------------------------------
1 | using Godot;
2 | using System;
3 |
4 | public class PowerReceiver : Node
5 | {
6 | [Signal]
7 | public delegate void PowerReceived(float power, float delta);
8 |
9 | [Export]
10 | public float PowerRequired = 50.0f;
11 |
12 | public float Efficiency = 0.0f;
13 | }
14 |
--------------------------------------------------------------------------------
/godot-csharp/EntityComponent/Components/PowerSource.cs:
--------------------------------------------------------------------------------
1 | using Godot;
2 | using System;
3 |
4 | public class PowerSource : Node
5 | {
6 | [Signal]
7 | public delegate void PowerDrawn(float power, float delta);
8 |
9 | [Export]
10 | public float PowerAmount = 50.0f;
11 |
12 | public float Efficiency = 0.0f;
13 | }
14 |
--------------------------------------------------------------------------------
/godot-csharp/EntityComponent/Entities/BatteryEntity.cs:
--------------------------------------------------------------------------------
1 | using Godot;
2 | using System;
3 | using System.Threading.Tasks;
4 |
5 | public class BatteryEntity : Node2D
6 | {
7 | ///
8 | /// Total amount of power the battery is able to hold
9 | ///
10 | [Export]
11 | public float MaxStorage = 1000.0f;
12 |
13 | ///
14 | /// Actual amount of power currently in the battery
15 | ///
16 | private float _storedPower = 0.0f;
17 | public float StoredPower
18 | {
19 | get { return _storedPower; }
20 | set { SetStoredPower(value); }
21 | }
22 |
23 | private PowerReceiver receiver;
24 | private PowerSource source;
25 | private Sprite indicator;
26 |
27 | public override void _Ready()
28 | {
29 | // onready equivalent doesn't exist in C#
30 | receiver = GetNode("PowerReceiver");
31 | source = GetNode("PowerSource");
32 | indicator = GetNode("Indicator");
33 | }
34 |
35 | private void SetStoredPower(float value)
36 | {
37 | _storedPower = value;
38 |
39 | // Make sure all nodes are ready
40 | if (!this.IsInsideTree())
41 | {
42 | Task.Run(async () => await ToSignal(this, "ready"));
43 | }
44 |
45 | // Set receiver efficiency to 0 if already full, otherwise set it to a percentage
46 | // of power that it can still receive from its input capacity.
47 | receiver.Efficiency = _storedPower >= MaxStorage ?
48 | 0.0f :
49 | Math.Min((MaxStorage - _storedPower) / receiver.PowerRequired, 1.0f);
50 |
51 | source.Efficiency = _storedPower <= 0 ?
52 | 0.0f :
53 | Math.Min(_storedPower / source.PowerAmount, 1.0f);
54 |
55 | // Update shader with power amount so the indicator is up to date with amount
56 | var shader = (ShaderMaterial)indicator.Material;
57 | shader.SetShaderParam("amount", _storedPower / MaxStorage);
58 | indicator.Material = shader;
59 | }
60 |
61 | ///
62 | /// Reduce the amount of power in the battery by the power value per second
63 | ///
64 | ///
65 | ///
66 | private void OnPowerSourcePowerDrawn(float power, float delta)
67 | {
68 | StoredPower = Math.Max(0, _storedPower - Math.Min(power, source.PowerAmount * source.Efficiency) * delta);
69 | }
70 |
71 | ///
72 | /// Increase the amount of power in the battery by the power value per second
73 | ///
74 | ///
75 | ///
76 | private void OnPowerReceiverPowerReceived(float power, float delta)
77 | {
78 | StoredPower = Math.Min(MaxStorage, _storedPower + power * delta);
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/godot-csharp/EntityComponent/Entities/BatteryEntity.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=8 format=2]
2 |
3 | [ext_resource path="res://EntityComponent/Shared/tileset.svg" type="Texture" id=1]
4 | [ext_resource path="res://EntityComponent/Shared/battery_indicator.png" type="Texture" id=2]
5 | [ext_resource path="res://EntityComponent/Components/PowerSource.cs" type="Script" id=3]
6 | [ext_resource path="res://EntityComponent/Entities/BatteryEntity.cs" type="Script" id=4]
7 | [ext_resource path="res://EntityComponent/Components/PowerReceiver.cs" type="Script" id=5]
8 |
9 | [sub_resource type="Shader" id=1]
10 | code = "shader_type canvas_item;
11 |
12 | //A percentage from 0 to 1 for how full the battery is
13 | uniform float amount : hint_range(0, 1) = 0.0;
14 |
15 | void fragment() {
16 | //Load the texture as a mask for our flat color indicator
17 | vec4 mask = texture(TEXTURE, UV);
18 | //We only need the red part of it. The rest, black or transparent, is of
19 | //no interest.
20 | float masking_area = mask.r;
21 |
22 | //Set the percentage of the UV sampling along the X axis to either 0 or 1,
23 | // based on how full the battery is. So if amount is 0.5, the percentage will
24 | // be 0 if UV.x is greater than that.
25 | float uv_percentage = step(UV.x, amount);
26 |
27 | //Set the sprite to the sprite's modulate color, and the alpha to the UV
28 | //percentage calculated above so only the red parts show up.
29 | COLOR = vec4(mask.rgb, uv_percentage * masking_area);
30 | }"
31 |
32 | [sub_resource type="ShaderMaterial" id=2]
33 | resource_local_to_scene = true
34 | shader = SubResource( 1 )
35 | shader_param/amount = 0.0
36 |
37 | [node name="BatteryEntity" type="Node2D" groups=[
38 | "power_receivers",
39 | "power_sources",
40 | ]]
41 | script = ExtResource( 4 )
42 |
43 | [node name="PowerSource" type="Node" parent="."]
44 | script = ExtResource( 3 )
45 | PowerAmount = 200.0
46 |
47 | [node name="PowerReceiver" type="Node" parent="."]
48 | script = ExtResource( 5 )
49 | PowerRequired = 200.0
50 |
51 | [node name="Sprite" type="Sprite" parent="."]
52 | position = Vector2( 0, -14.8726 )
53 | texture = ExtResource( 1 )
54 | region_enabled = true
55 | region_rect = Rect2( 119, 4, 102, 82 )
56 |
57 | [node name="Indicator" type="Sprite" parent="."]
58 | modulate = Color( 1, 0, 0, 1 )
59 | material = SubResource( 2 )
60 | position = Vector2( -23.2885, -17.3956 )
61 | scale = Vector2( 0.6, 0.6 )
62 | texture = ExtResource( 2 )
63 | [connection signal="PowerDrawn" from="PowerSource" to="." method="OnPowerSourcePowerDrawn"]
64 | [connection signal="PowerReceived" from="PowerReceiver" to="." method="OnPowerReceiverPowerReceived"]
65 |
--------------------------------------------------------------------------------
/godot-csharp/EntityComponent/Entities/GeneratorEntity.cs:
--------------------------------------------------------------------------------
1 | using Godot;
2 | using System;
3 |
4 | public class GeneratorEntity : Node2D
5 | {
6 | private AnimationPlayer _animationPlayer;
7 | private PowerSource _powerSource;
8 |
9 | public override void _Ready()
10 | {
11 | _animationPlayer = GetNode("AnimationPlayer");
12 | _animationPlayer.Play("Work");
13 |
14 | _powerSource = GetNode("PowerSource");
15 | _powerSource.Efficiency = 1.0f;
16 | }
17 |
18 | private void OnPowerSourcePowerDrawn(float power, float delta)
19 | {
20 | var proportion = power / _powerSource.PowerAmount;
21 | _animationPlayer.PlaybackSpeed = proportion;
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/godot-csharp/EntityComponent/Entities/GeneratorEntity.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=5 format=2]
2 |
3 | [ext_resource path="res://EntityComponent/Components/PowerSource.cs" type="Script" id=1]
4 | [ext_resource path="res://EntityComponent/Shared/tileset.svg" type="Texture" id=2]
5 | [ext_resource path="res://EntityComponent/Entities/GeneratorEntity.cs" type="Script" id=3]
6 |
7 | [sub_resource type="Animation" id=1]
8 | resource_name = "Work"
9 | length = 0.6
10 | loop = true
11 | tracks/0/type = "value"
12 | tracks/0/path = NodePath("PistonBack:position")
13 | tracks/0/interp = 1
14 | tracks/0/loop_wrap = true
15 | tracks/0/imported = false
16 | tracks/0/enabled = true
17 | tracks/0/keys = {
18 | "times": PoolRealArray( 0, 0.3, 0.6 ),
19 | "transitions": PoolRealArray( 1, 1, 1 ),
20 | "update": 0,
21 | "values": [ Vector2( 0, -33 ), Vector2( 0, -60.7809 ), Vector2( 0, -33 ) ]
22 | }
23 | tracks/1/type = "value"
24 | tracks/1/path = NodePath("PistonFront:position")
25 | tracks/1/interp = 1
26 | tracks/1/loop_wrap = true
27 | tracks/1/imported = false
28 | tracks/1/enabled = true
29 | tracks/1/keys = {
30 | "times": PoolRealArray( 0, 0.3, 0.6 ),
31 | "transitions": PoolRealArray( 1, 1, 1 ),
32 | "update": 0,
33 | "values": [ Vector2( 0, -3.42728 ), Vector2( 0, -31.2082 ), Vector2( 0, -3.42728 ) ]
34 | }
35 |
36 | [node name="GeneratorEntity" type="Node2D" groups=[
37 | "power_sources",
38 | ]]
39 | script = ExtResource( 3 )
40 |
41 | [node name="PowerSource" type="Node" parent="."]
42 | script = ExtResource( 1 )
43 | PowerAmount = 200.0
44 |
45 | [node name="Base" type="Sprite" parent="."]
46 | position = Vector2( 0, -5.42728 )
47 | texture = ExtResource( 2 )
48 | region_enabled = true
49 | region_rect = Rect2( 229, 34, 102, 62 )
50 |
51 | [node name="PistonBack" type="Sprite" parent="."]
52 | position = Vector2( 0, -33 )
53 | texture = ExtResource( 2 )
54 | region_enabled = true
55 | region_rect = Rect2( 560, 24, 100, 27 )
56 |
57 | [node name="PistonShaft" type="Sprite" parent="."]
58 | modulate = Color( 0.301961, 0.933333, 0.14902, 1 )
59 | position = Vector2( 0, -31.4285 )
60 | texture = ExtResource( 2 )
61 | region_enabled = true
62 | region_rect = Rect2( 364, 4, 52, 70 )
63 |
64 | [node name="PistonFront" type="Sprite" parent="."]
65 | position = Vector2( 0, -3.42728 )
66 | texture = ExtResource( 2 )
67 | region_enabled = true
68 | region_rect = Rect2( 449, 49, 102, 37 )
69 |
70 | [node name="AnimationPlayer" type="AnimationPlayer" parent="."]
71 | anims/Work = SubResource( 1 )
72 | [connection signal="PowerDrawn" from="PowerSource" to="." method="OnPowerSourcePowerDrawn"]
73 |
--------------------------------------------------------------------------------
/godot-csharp/EntityComponent/Game.cs:
--------------------------------------------------------------------------------
1 | using Godot;
2 | using System.Collections.Generic;
3 |
4 | public class Game : Node
5 | {
6 | private PowerSystem powerSystem = new PowerSystem();
7 |
8 | public override void _Ready()
9 | {
10 | var sources = GetTree().GetNodesInGroup("power_sources");
11 | var sourceList = ToList(sources);
12 | var receivers = GetTree().GetNodesInGroup("power_receivers");
13 | var receiverList = ToList(receivers);
14 | var tileMap = GetNode("TileMap");
15 | powerSystem.Setup(sourceList, receiverList, tileMap);
16 | }
17 |
18 | public override void _PhysicsProcess(float delta)
19 | {
20 | powerSystem.Update(delta);
21 | }
22 |
23 | private List ToList(Godot.Collections.Array array) where T : Node
24 | {
25 | var results = new List();
26 |
27 | foreach (var element in array)
28 | {
29 | results.Add((T)element);
30 | }
31 |
32 | return results;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/godot-csharp/EntityComponent/Game.tscn:
--------------------------------------------------------------------------------
1 | [gd_scene load_steps=5 format=2]
2 |
3 | [ext_resource path="res://EntityComponent/Game.cs" type="Script" id=1]
4 | [ext_resource path="res://EntityComponent/Shared/tileset.tres" type="TileSet" id=2]
5 | [ext_resource path="res://EntityComponent/Entities/GeneratorEntity.tscn" type="PackedScene" id=3]
6 | [ext_resource path="res://EntityComponent/Entities/BatteryEntity.tscn" type="PackedScene" id=4]
7 |
8 | [node name="Game" type="Node"]
9 | script = ExtResource( 1 )
10 |
11 | [node name="TileMap" type="TileMap" parent="."]
12 | mode = 1
13 | tile_set = ExtResource( 2 )
14 | cell_size = Vector2( 100, 50 )
15 | cell_y_sort = true
16 | format = 1
17 | tile_data = PoolIntArray( -589807, 0, 0, -589806, 0, 0, -524272, 0, 0, -524271, 0, 0, -524270, 0, 0, -524269, 0, 0, -458737, 0, 0, -458736, 0, 0, -458735, 0, 0, -458734, 0, 0, -458733, 0, 0, -458732, 0, 0, -393202, 0, 0, -393201, 0, 0, -393200, 0, 0, -393199, 0, 0, -393198, 0, 0, -393197, 0, 0, -393196, 0, 0, -393195, 0, 0, -327667, 0, 0, -327666, 0, 0, -327665, 0, 0, -327664, 0, 0, -327663, 0, 0, -327662, 0, 0, -327661, 0, 0, -327660, 0, 0, -327659, 0, 0, -327658, 0, 0, -262132, 0, 0, -262131, 0, 0, -262130, 0, 0, -262129, 0, 0, -262128, 0, 0, -262127, 0, 0, -262126, 0, 0, -262125, 0, 0, -262124, 0, 0, -262123, 0, 0, -262122, 0, 0, -262121, 0, 0, -196597, 0, 0, -196596, 0, 0, -196595, 0, 0, -196594, 0, 0, -196593, 0, 0, -196592, 0, 0, -196591, 0, 0, -196590, 0, 0, -196589, 0, 0, -196588, 0, 0, -196587, 0, 0, -196586, 0, 0, -196585, 0, 0, -196584, 0, 0, -131062, 0, 0, -131061, 0, 0, -131060, 0, 0, -131059, 0, 0, -131058, 0, 0, -131057, 0, 0, -131056, 0, 0, -131055, 0, 0, -131054, 0, 0, -131053, 0, 0, -131052, 0, 0, -131051, 0, 0, -131050, 0, 0, -131049, 0, 0, -131048, 0, 0, -131047, 0, 0, -65526, 0, 0, -65525, 0, 0, -65524, 0, 0, -65523, 0, 0, -65522, 0, 0, -65521, 0, 0, -65520, 0, 0, -65519, 0, 0, -65518, 0, 0, -65517, 0, 0, -65516, 0, 0, -65515, 0, 0, -65514, 0, 0, -65513, 0, 0, -65512, 0, 0, -65511, 0, 0, -65510, 0, 0, 11, 0, 0, 12, 0, 0, 13, 0, 0, 14, 0, 0, 15, 0, 0, 16, 0, 0, 17, 0, 0, 18, 0, 0, 19, 0, 0, 20, 0, 0, 21, 0, 0, 22, 0, 0, 23, 0, 0, 24, 0, 0, 25, 0, 0, 65548, 0, 0, 65549, 0, 0, 65550, 0, 0, 65551, 0, 0, 65552, 0, 0, 65553, 0, 0, 65554, 0, 0, 65555, 0, 0, 65556, 0, 0, 65557, 0, 0, 65558, 0, 0, 65559, 0, 0, 65560, 0, 0, 131085, 0, 0, 131086, 0, 0, 131087, 0, 0, 131088, 0, 0, 131089, 0, 0, 131090, 0, 0, 131091, 0, 0, 131092, 0, 0, 131093, 0, 0, 131094, 0, 0, 131095, 0, 0, 196622, 0, 0, 196623, 0, 0, 196624, 0, 0, 196625, 0, 0, 196626, 0, 0, 196627, 0, 0, 196628, 0, 0, 196629, 0, 0, 196630, 0, 0, 262159, 0, 0, 262160, 0, 0, 262161, 0, 0, 262162, 0, 0, 262163, 0, 0, 262164, 0, 0, 262165, 0, 0, 327696, 0, 0, 327697, 0, 0, 327698, 0, 0, 327699, 0, 0, 327700, 0, 0, 393233, 0, 0, 393234, 0, 0, 393235, 0, 0, 458770, 0, 0 )
18 |
19 | [node name="GeneratorEntity" parent="TileMap" instance=ExtResource( 3 )]
20 | position = Vector2( 850.646, 400.105 )
21 |
22 | [node name="BatteryEntity" parent="TileMap" instance=ExtResource( 4 )]
23 | position = Vector2( 901.627, 425.519 )
24 |
25 | [node name="BatteryEntity2" parent="TileMap" instance=ExtResource( 4 )]
26 | position = Vector2( 952.473, 451.134 )
27 |
28 | [node name="BatteryEntity3" parent="TileMap" instance=ExtResource( 4 )]
29 | position = Vector2( 1002.48, 476.533 )
30 |
31 | [node name="BatteryEntity4" parent="TileMap" instance=ExtResource( 4 )]
32 | position = Vector2( 1052.48, 501.931 )
33 |
34 | [node name="Camera2D" type="Camera2D" parent="."]
35 | position = Vector2( 953.234, 439.71 )
36 | current = true
37 | zoom = Vector2( 0.379, 0.379 )
38 |
--------------------------------------------------------------------------------
/godot-csharp/EntityComponent/PowerSystem.cs:
--------------------------------------------------------------------------------
1 | using Godot;
2 | using System;
3 | using System.Collections.Generic;
4 | public class PowerSystem : Reference
5 | {
6 | private Dictionary sources = new Dictionary();
7 | private Dictionary receivers = new Dictionary();
8 |
9 | private List> paths = new List>();
10 |
11 | private Dictionary receiverAlreadyProvided = new Dictionary();
12 |
13 | public void Setup(List powerSources,
14 | List powerReceivers,
15 | TileMap tileMap)
16 | {
17 | foreach (var source in powerSources)
18 | {
19 | var location = tileMap.WorldToMap(source.GlobalPosition);
20 | sources.Add(location, FindChildOfType(source));
21 | paths.Add(new List { location });
22 | }
23 |
24 | foreach (var receiver in powerReceivers)
25 | {
26 | var location = tileMap.WorldToMap(receiver.GlobalPosition);
27 | receivers.Add(location, FindChildOfType(receiver));
28 | }
29 |
30 | foreach (var path in paths)
31 | {
32 | foreach (var receiver in receivers)
33 | {
34 | if (receiver.Key.x == path[0].x + 1)
35 | {
36 | path.Add(receiver.Key);
37 | }
38 | }
39 | }
40 | }
41 |
42 | public void Update(float delta)
43 | {
44 | receiverAlreadyProvided.Clear();
45 |
46 | foreach (var path in paths)
47 | {
48 | var source = sources[path[0]];
49 |
50 | var avilablePower = source.PowerAmount * source.Efficiency;
51 |
52 | var powerDraw = 0.0f;
53 |
54 | foreach (var cell in path.GetRange(1, path.Count - 1))
55 | {
56 | if (!receivers.ContainsKey(cell))
57 | {
58 | continue;
59 | }
60 |
61 | var receiver = receivers[cell];
62 | var powerRequired = receiver.PowerRequired * receiver.Efficiency;
63 |
64 | if (receiverAlreadyProvided.ContainsKey(cell))
65 | {
66 | var receiverTotal = receiverAlreadyProvided[cell];
67 | if (receiverTotal >= powerRequired)
68 | {
69 | continue;
70 | }
71 | else
72 | {
73 | powerRequired -= receiverTotal;
74 | }
75 | }
76 |
77 | receiver.EmitSignal("PowerReceived", Math.Min(avilablePower, powerRequired), delta);
78 | powerDraw += powerRequired;
79 |
80 | if (!receiverAlreadyProvided.ContainsKey(cell))
81 | {
82 | receiverAlreadyProvided[cell] = Math.Min(avilablePower, powerRequired);
83 | }
84 | else
85 | {
86 | receiverAlreadyProvided[cell] += Math.Min(avilablePower, powerRequired);
87 | }
88 |
89 | avilablePower -= powerRequired;
90 | }
91 |
92 | source.EmitSignal("PowerDrawn", powerDraw, delta);
93 | }
94 | }
95 |
96 | private T FindChildOfType(Node parent) where T : Node
97 | {
98 | foreach (var child in parent.GetChildren())
99 | {
100 | if (child is T specifiedType)
101 | {
102 | return specifiedType;
103 | }
104 | }
105 |
106 | return null;
107 | }
108 | }
109 |
--------------------------------------------------------------------------------
/godot-csharp/EntityComponent/Shared/battery_indicator.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gdquest-demos/godot-design-patterns/34c16b71db6d97decb46f0253984aa4cd9259a5d/godot-csharp/EntityComponent/Shared/battery_indicator.png
--------------------------------------------------------------------------------
/godot-csharp/EntityComponent/Shared/battery_indicator.png.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="StreamTexture"
5 | path="res://.import/battery_indicator.png-d2ad5601d9bd0d85c4f08309c7fc43a0.stex"
6 | metadata={
7 | "vram_texture": false
8 | }
9 |
10 | [deps]
11 |
12 | source_file="res://EntityComponent/Shared/battery_indicator.png"
13 | dest_files=[ "res://.import/battery_indicator.png-d2ad5601d9bd0d85c4f08309c7fc43a0.stex" ]
14 |
15 | [params]
16 |
17 | compress/mode=0
18 | compress/lossy_quality=0.7
19 | compress/hdr_mode=0
20 | compress/bptc_ldr=0
21 | compress/normal_map=0
22 | flags/repeat=0
23 | flags/filter=true
24 | flags/mipmaps=false
25 | flags/anisotropic=false
26 | flags/srgb=2
27 | process/fix_alpha_border=true
28 | process/premult_alpha=false
29 | process/HDR_as_SRGB=false
30 | process/invert_color=false
31 | process/normal_map_invert_y=false
32 | stream=false
33 | size_limit=0
34 | detect_3d=true
35 | svg/scale=1.0
36 |
--------------------------------------------------------------------------------
/godot-csharp/EntityComponent/Shared/tileset.svg:
--------------------------------------------------------------------------------
1 |
2 |
292 |
--------------------------------------------------------------------------------
/godot-csharp/EntityComponent/Shared/tileset.svg.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="StreamTexture"
5 | path="res://.import/tileset.svg-5e64a4ffd02ef8c7e1f4b5122a94507b.stex"
6 | metadata={
7 | "vram_texture": false
8 | }
9 |
10 | [deps]
11 |
12 | source_file="res://EntityComponent/Shared/tileset.svg"
13 | dest_files=[ "res://.import/tileset.svg-5e64a4ffd02ef8c7e1f4b5122a94507b.stex" ]
14 |
15 | [params]
16 |
17 | compress/mode=0
18 | compress/lossy_quality=0.7
19 | compress/hdr_mode=0
20 | compress/bptc_ldr=0
21 | compress/normal_map=0
22 | flags/repeat=0
23 | flags/filter=true
24 | flags/mipmaps=false
25 | flags/anisotropic=false
26 | flags/srgb=2
27 | process/fix_alpha_border=true
28 | process/premult_alpha=false
29 | process/HDR_as_SRGB=false
30 | process/invert_color=false
31 | process/normal_map_invert_y=false
32 | stream=false
33 | size_limit=0
34 | detect_3d=true
35 | svg/scale=1.0
36 |
--------------------------------------------------------------------------------
/godot-csharp/EntityComponent/Shared/tileset.tres:
--------------------------------------------------------------------------------
1 | [gd_resource type="TileSet" load_steps=2 format=2]
2 |
3 | [ext_resource path="res://EntityComponent/Shared/tileset.svg" type="Texture" id=1]
4 |
5 | [resource]
6 | 0/name = "tileset.svg 0"
7 | 0/texture = ExtResource( 1 )
8 | 0/tex_offset = Vector2( 0, 0 )
9 | 0/modulate = Color( 1, 1, 1, 1 )
10 | 0/region = Rect2( 10, 10, 100, 100 )
11 | 0/tile_mode = 0
12 | 0/occluder_offset = Vector2( 0, 0 )
13 | 0/navigation_offset = Vector2( 0, 0 )
14 | 0/shape_offset = Vector2( 0, 0 )
15 | 0/shape_transform = Transform2D( 1, 0, 0, 1, 0, 0 )
16 | 0/shape_one_way = false
17 | 0/shape_one_way_margin = 0.0
18 | 0/shapes = [ ]
19 | 0/z_index = 0
20 |
--------------------------------------------------------------------------------
/godot-csharp/Godot Design Pattern csharp demo.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | Tools
4 | {BF2F76E5-AC42-4490-A763-E95D8BC76269}
5 | Library
6 | GodotDesignPatterncsharpdemo
7 | Godot Design Pattern csharp demo
8 | 1.0.7333.3918
9 | net472
10 |
12 | false
13 | false
14 | false
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/godot-csharp/Godot Design Pattern csharp demo.csproj.old:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Tools
5 | AnyCPU
6 | {BF2F76E5-AC42-4490-A763-E95D8BC76269}
7 | Library
8 | .mono\temp\bin\$(Configuration)
9 | GodotDesignPatterncsharpdemo
10 | Godot Design Pattern csharp demo
11 | v4.7
12 | 1.0.7333.3918
13 | .mono\temp\obj
14 | $(BaseIntermediateOutputPath)\$(Configuration)
15 | Debug
16 | Release
17 |
18 |
19 | true
20 | portable
21 | false
22 | $(GodotDefineConstants);GODOT;DEBUG;
23 | prompt
24 | 4
25 | false
26 |
27 |
28 | portable
29 | true
30 | $(GodotDefineConstants);GODOT;
31 | prompt
32 | 4
33 | false
34 |
35 |
36 | true
37 | portable
38 | false
39 | $(GodotDefineConstants);GODOT;DEBUG;TOOLS;
40 | prompt
41 | 4
42 | false
43 |
44 |
45 |
46 | False
47 | $(ProjectDir)/.mono/assemblies/$(ApiConfiguration)/GodotSharp.dll
48 |
49 |
50 | False
51 | $(ProjectDir)/.mono/assemblies/$(ApiConfiguration)/GodotSharpEditor.dll
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
--------------------------------------------------------------------------------
/godot-csharp/Godot Design Pattern csharp demo.sln:
--------------------------------------------------------------------------------
1 | Microsoft Visual Studio Solution File, Format Version 12.00
2 | # Visual Studio 2012
3 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Godot Design Pattern csharp demo", "Godot Design Pattern csharp demo.csproj", "{BF2F76E5-AC42-4490-A763-E95D8BC76269}"
4 | EndProject
5 | Global
6 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
7 | Debug|Any CPU = Debug|Any CPU
8 | ExportDebug|Any CPU = ExportDebug|Any CPU
9 | ExportRelease|Any CPU = ExportRelease|Any CPU
10 | EndGlobalSection
11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
12 | {BF2F76E5-AC42-4490-A763-E95D8BC76269}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
13 | {BF2F76E5-AC42-4490-A763-E95D8BC76269}.Debug|Any CPU.Build.0 = Debug|Any CPU
14 | {BF2F76E5-AC42-4490-A763-E95D8BC76269}.ExportDebug|Any CPU.ActiveCfg = ExportDebug|Any CPU
15 | {BF2F76E5-AC42-4490-A763-E95D8BC76269}.ExportDebug|Any CPU.Build.0 = ExportDebug|Any CPU
16 | {BF2F76E5-AC42-4490-A763-E95D8BC76269}.ExportRelease|Any CPU.ActiveCfg = ExportRelease|Any CPU
17 | {BF2F76E5-AC42-4490-A763-E95D8BC76269}.ExportRelease|Any CPU.Build.0 = ExportRelease|Any CPU
18 | EndGlobalSection
19 | EndGlobal
20 |
--------------------------------------------------------------------------------
/godot-csharp/Godot Design Pattern csharp demo.sln.old:
--------------------------------------------------------------------------------
1 | Microsoft Visual Studio Solution File, Format Version 12.00
2 | # Visual Studio 2012
3 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Godot Design Pattern csharp demo", "Godot Design Pattern csharp demo.csproj", "{BF2F76E5-AC42-4490-A763-E95D8BC76269}"
4 | EndProject
5 | Global
6 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
7 | Debug|Any CPU = Debug|Any CPU
8 | Release|Any CPU = Release|Any CPU
9 | Tools|Any CPU = Tools|Any CPU
10 | EndGlobalSection
11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
12 | {BF2F76E5-AC42-4490-A763-E95D8BC76269}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
13 | {BF2F76E5-AC42-4490-A763-E95D8BC76269}.Debug|Any CPU.Build.0 = Debug|Any CPU
14 | {BF2F76E5-AC42-4490-A763-E95D8BC76269}.Release|Any CPU.ActiveCfg = Release|Any CPU
15 | {BF2F76E5-AC42-4490-A763-E95D8BC76269}.Release|Any CPU.Build.0 = Release|Any CPU
16 | {BF2F76E5-AC42-4490-A763-E95D8BC76269}.Tools|Any CPU.ActiveCfg = Tools|Any CPU
17 | {BF2F76E5-AC42-4490-A763-E95D8BC76269}.Tools|Any CPU.Build.0 = Tools|Any CPU
18 | EndGlobalSection
19 | EndGlobal
20 |
--------------------------------------------------------------------------------
/godot-csharp/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 |
3 | // Information about this assembly is defined by the following attributes.
4 | // Change them to the values specific to your project.
5 |
6 | [assembly: AssemblyTitle("Godot Design Pattern csharp demo")]
7 | [assembly: AssemblyDescription("")]
8 | [assembly: AssemblyConfiguration("")]
9 | [assembly: AssemblyCompany("")]
10 | [assembly: AssemblyProduct("")]
11 | [assembly: AssemblyCopyright("")]
12 | [assembly: AssemblyTrademark("")]
13 | [assembly: AssemblyCulture("")]
14 |
15 | // The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
16 | // The form "{Major}.{Minor}.*" will automatically update the build and revision,
17 | // and "{Major}.{Minor}.{Build}.*" will update just the revision.
18 |
19 | [assembly: AssemblyVersion("1.0.*")]
20 |
21 | // The following attributes are used to specify the signing key for the assembly,
22 | // if desired. See the Mono documentation for more information about signing.
23 |
24 | //[assembly: AssemblyDelaySign(false)]
25 | //[assembly: AssemblyKeyFile("")]
26 |
--------------------------------------------------------------------------------
/godot-csharp/Shared/background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gdquest-demos/godot-design-patterns/34c16b71db6d97decb46f0253984aa4cd9259a5d/godot-csharp/Shared/background.png
--------------------------------------------------------------------------------
/godot-csharp/Shared/background.png.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="StreamTexture"
5 | path="res://.import/background.png-d8b19effa74161a3ece6b68995ea2cc7.stex"
6 | metadata={
7 | "vram_texture": false
8 | }
9 |
10 | [deps]
11 |
12 | source_file="res://Shared/background.png"
13 | dest_files=[ "res://.import/background.png-d8b19effa74161a3ece6b68995ea2cc7.stex" ]
14 |
15 | [params]
16 |
17 | compress/mode=0
18 | compress/lossy_quality=0.7
19 | compress/hdr_mode=0
20 | compress/bptc_ldr=0
21 | compress/normal_map=0
22 | flags/repeat=0
23 | flags/filter=true
24 | flags/mipmaps=false
25 | flags/anisotropic=false
26 | flags/srgb=2
27 | process/fix_alpha_border=true
28 | process/premult_alpha=false
29 | process/HDR_as_SRGB=false
30 | process/invert_color=false
31 | stream=false
32 | size_limit=0
33 | detect_3d=true
34 | svg/scale=1.0
35 |
--------------------------------------------------------------------------------
/godot-csharp/Shared/monserrate_bold.tres:
--------------------------------------------------------------------------------
1 | [gd_resource type="DynamicFont" load_steps=2 format=2]
2 |
3 | [ext_resource path="res://Shared/montserrat_extrabold.otf" type="DynamicFontData" id=1]
4 |
5 | [resource]
6 | size = 22
7 | font_data = ExtResource( 1 )
8 |
--------------------------------------------------------------------------------
/godot-csharp/Shared/montserrat_extrabold.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gdquest-demos/godot-design-patterns/34c16b71db6d97decb46f0253984aa4cd9259a5d/godot-csharp/Shared/montserrat_extrabold.otf
--------------------------------------------------------------------------------
/godot-csharp/Shared/player.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gdquest-demos/godot-design-patterns/34c16b71db6d97decb46f0253984aa4cd9259a5d/godot-csharp/Shared/player.png
--------------------------------------------------------------------------------
/godot-csharp/Shared/player.png.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="StreamTexture"
5 | path="res://.import/player.png-0e3f197cea916321015378cec296c5b4.stex"
6 | metadata={
7 | "vram_texture": false
8 | }
9 |
10 | [deps]
11 |
12 | source_file="res://Shared/player.png"
13 | dest_files=[ "res://.import/player.png-0e3f197cea916321015378cec296c5b4.stex" ]
14 |
15 | [params]
16 |
17 | compress/mode=0
18 | compress/lossy_quality=0.7
19 | compress/hdr_mode=0
20 | compress/bptc_ldr=0
21 | compress/normal_map=0
22 | flags/repeat=0
23 | flags/filter=true
24 | flags/mipmaps=false
25 | flags/anisotropic=false
26 | flags/srgb=2
27 | process/fix_alpha_border=true
28 | process/premult_alpha=false
29 | process/HDR_as_SRGB=false
30 | process/invert_color=false
31 | stream=false
32 | size_limit=0
33 | detect_3d=true
34 | svg/scale=1.0
35 |
--------------------------------------------------------------------------------
/godot-csharp/Shared/tileset_platformer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gdquest-demos/godot-design-patterns/34c16b71db6d97decb46f0253984aa4cd9259a5d/godot-csharp/Shared/tileset_platformer.png
--------------------------------------------------------------------------------
/godot-csharp/Shared/tileset_platformer.png.import:
--------------------------------------------------------------------------------
1 | [remap]
2 |
3 | importer="texture"
4 | type="StreamTexture"
5 | path="res://.import/tileset_platformer.png-a00bea6b34edff2d6015c50f9a248ee5.stex"
6 | metadata={
7 | "vram_texture": false
8 | }
9 |
10 | [deps]
11 |
12 | source_file="res://Shared/tileset_platformer.png"
13 | dest_files=[ "res://.import/tileset_platformer.png-a00bea6b34edff2d6015c50f9a248ee5.stex" ]
14 |
15 | [params]
16 |
17 | compress/mode=0
18 | compress/lossy_quality=0.7
19 | compress/hdr_mode=0
20 | compress/bptc_ldr=0
21 | compress/normal_map=0
22 | flags/repeat=0
23 | flags/filter=true
24 | flags/mipmaps=false
25 | flags/anisotropic=false
26 | flags/srgb=2
27 | process/fix_alpha_border=true
28 | process/premult_alpha=false
29 | process/HDR_as_SRGB=false
30 | process/invert_color=false
31 | stream=false
32 | size_limit=0
33 | detect_3d=true
34 | svg/scale=1.0
35 |
--------------------------------------------------------------------------------
/godot-csharp/Shared/tileset_platformer.tres:
--------------------------------------------------------------------------------
1 | [gd_resource type="TileSet" load_steps=8 format=2]
2 |
3 | [ext_resource path="res://Shared/tileset_platformer.png" type="Texture" id=1]
4 |
5 | [sub_resource type="OccluderPolygon2D" id=1]
6 | polygon = PoolVector2Array( 0, 0, 80, 0, 80, 80, 0, 80 )
7 |
8 | [sub_resource type="ConvexPolygonShape2D" id=2]
9 | points = PoolVector2Array( 0, 0, 80, 0, 80, 80, 0, 80 )
10 |
11 | [sub_resource type="OccluderPolygon2D" id=3]
12 | polygon = PoolVector2Array( 0, 0, 80, 0, 80, 80, 0, 80 )
13 |
14 | [sub_resource type="ConvexPolygonShape2D" id=4]
15 | points = PoolVector2Array( 0, 0, 80, 0, 80, 80, 0, 80 )
16 |
17 | [sub_resource type="ConvexPolygonShape2D" id=5]
18 | points = PoolVector2Array( 0, 80, 80, 0, 80, 80 )
19 |
20 | [sub_resource type="ConvexPolygonShape2D" id=6]
21 | points = PoolVector2Array( 0, 80, 160, 0, 160, 80 )
22 |
23 | [resource]
24 | 0/name = "tileset.png 0"
25 | 0/texture = ExtResource( 1 )
26 | 0/tex_offset = Vector2( 0, 0 )
27 | 0/modulate = Color( 1, 1, 1, 1 )
28 | 0/region = Rect2( 0, 0, 80, 80 )
29 | 0/tile_mode = 0
30 | 0/occluder_offset = Vector2( 0, 0 )
31 | 0/occluder = SubResource( 1 )
32 | 0/navigation_offset = Vector2( 0, 0 )
33 | 0/shapes = [ {
34 | "autotile_coord": Vector2( 0, 0 ),
35 | "one_way": false,
36 | "one_way_margin": 1.0,
37 | "shape": SubResource( 2 ),
38 | "shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 )
39 | } ]
40 | 0/z_index = 0
41 | 1/name = "tileset.png 1"
42 | 1/texture = ExtResource( 1 )
43 | 1/tex_offset = Vector2( 0, 0 )
44 | 1/modulate = Color( 1, 1, 1, 1 )
45 | 1/region = Rect2( 80, 0, 80, 80 )
46 | 1/tile_mode = 0
47 | 1/occluder_offset = Vector2( 0, 0 )
48 | 1/occluder = SubResource( 3 )
49 | 1/navigation_offset = Vector2( 0, 0 )
50 | 1/shapes = [ {
51 | "autotile_coord": Vector2( 0, 0 ),
52 | "one_way": true,
53 | "one_way_margin": 1.0,
54 | "shape": SubResource( 4 ),
55 | "shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 )
56 | } ]
57 | 1/z_index = 0
58 | 2/name = "tileset.png 2"
59 | 2/texture = ExtResource( 1 )
60 | 2/tex_offset = Vector2( 0, 0 )
61 | 2/modulate = Color( 1, 1, 1, 1 )
62 | 2/region = Rect2( 0, 80, 80, 80 )
63 | 2/tile_mode = 0
64 | 2/occluder_offset = Vector2( 0, 0 )
65 | 2/navigation_offset = Vector2( 0, 0 )
66 | 2/shapes = [ {
67 | "autotile_coord": Vector2( 0, 0 ),
68 | "one_way": false,
69 | "one_way_margin": 1.0,
70 | "shape": SubResource( 5 ),
71 | "shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 )
72 | } ]
73 | 2/z_index = 0
74 | 3/name = "tileset.png 3"
75 | 3/texture = ExtResource( 1 )
76 | 3/tex_offset = Vector2( 0, 0 )
77 | 3/modulate = Color( 1, 1, 1, 1 )
78 | 3/region = Rect2( 0, 160, 160, 80 )
79 | 3/tile_mode = 0
80 | 3/occluder_offset = Vector2( 0, 0 )
81 | 3/navigation_offset = Vector2( 0, 0 )
82 | 3/shapes = [ {
83 | "autotile_coord": Vector2( 0, 0 ),
84 | "one_way": false,
85 | "one_way_margin": 1.0,
86 | "shape": SubResource( 6 ),
87 | "shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 )
88 | } ]
89 | 3/z_index = 0
90 |
--------------------------------------------------------------------------------
/godot-csharp/StateMachine/Player/Air.cs:
--------------------------------------------------------------------------------
1 | using Godot;
2 | using System;
3 | using System.Collections.Generic;
4 |
5 | // The GD tutorial has this class named "Jump.gd". However, in C#,
6 | // the name of a class is also its type, and should always be the node's
7 | // name to avoid problems down the line.
8 | public class Air : PlayerState
9 | {
10 | ///
11 | /// If we get a message asking us to jump, we jump.
12 | ///
13 | ///
14 | public override void Enter(Dictionary message = null)
15 | {
16 | if (message != null &&
17 | message.ContainsKey("doJump") &&
18 | message["doJump"] == true)
19 | {
20 | _player.Velocity.y = -_player.JumpImpulse;
21 | }
22 | }
23 |
24 | public override void PhysicsUpdate(float delta)
25 | {
26 | // Horizontal movement
27 | var inputDirectionX = Input.GetActionStrength("move_right") - Input.GetActionStrength("move_left");
28 |
29 | // Vertical Movement
30 | _player.Velocity.x = _player.Speed * inputDirectionX;
31 | _player.Velocity.y += _player.Gravity * delta;
32 | _player.Velocity = _player.MoveAndSlide(_player.Velocity, Vector2.Up);
33 |
34 | // Landing
35 | if (_player.IsOnFloor())
36 | {
37 | if (Godot.Mathf.IsEqualApprox(_player.Velocity.x, 0.0f))
38 | {
39 | _stateMachine.TransitionTo("Idle");
40 | }
41 | else
42 | {
43 | _stateMachine.TransitionTo("Run");
44 | }
45 | }
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/godot-csharp/StateMachine/Player/Idle.cs:
--------------------------------------------------------------------------------
1 | using Godot;
2 | using System;
3 | using System.Collections.Generic;
4 |
5 | public class Idle : PlayerState
6 | {
7 | ///
8 | /// Upon entering the state, we set the Player node's velocity to zero.
9 | ///
10 | ///
11 | public override void Enter(Dictionary message = null)
12 | {
13 | // We must declare all the properties we access through `owner` in the `Player.cs` script.
14 | _player.Velocity = Vector2.Zero;
15 | }
16 |
17 | public override void PhysicsUpdate(float delta)
18 | {
19 | // If you have platforms that break when standing on them, you need that check for the character to fall.
20 | if (!_player.IsOnFloor())
21 | {
22 | _stateMachine.TransitionTo("Air");
23 | return;
24 | }
25 |
26 | if (Input.IsActionJustPressed("move_up"))
27 | {
28 | // As we'll only have one air state for both jump and fall, we use the `msg` dictionary
29 | // to tell the next state that we want to jump.
30 | var message = new Dictionary()
31 | {
32 | { "doJump", true }
33 | };
34 | _stateMachine.TransitionTo("Air", message);
35 | }
36 | else if (Input.IsActionPressed("move_left") || Input.IsActionPressed("move_right"))
37 | {
38 | _stateMachine.TransitionTo("Run");
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/godot-csharp/StateMachine/Player/Player.cs:
--------------------------------------------------------------------------------
1 | using Godot;
2 | using System;
3 |
4 | public class Player : KinematicBody2D
5 | {
6 | public int Speed = 500;
7 | public int JumpImpulse = 1200;
8 | public int Gravity = 3500;
9 |
10 | public Vector2 Velocity = new Vector2();
11 |
12 | public Label label;
13 | public StateMachine _stateMachine;
14 |
15 | public override void _Ready()
16 | {
17 | label = GetNode