This commit is contained in:
redglow
2026-07-21 20:49:24 +02:00
parent c540b99eb6
commit e7dbb9cabb
31 changed files with 394 additions and 76 deletions
+11 -2
View File
@@ -1,13 +1,22 @@
using GodotHostTest.Interfaces; using GodotHostTest.Interfaces;
using R3;
namespace GodotHostTest.Game.Level; namespace GodotHostTest.Game.Level;
public class CurrentLevel : ICurrentLevel public class CurrentLevel : ICurrentLevel
{ {
public int LevelNumber { get; private set; } = 1; private readonly ReactiveProperty<int> _levelNumber;
public CurrentLevel()
{
_levelNumber = new ReactiveProperty<int>(1);
LevelNumber = _levelNumber.ToReadOnlyReactiveProperty();
}
public ReadOnlyReactiveProperty<int> LevelNumber { get; }
public void NextLevel() public void NextLevel()
{ {
LevelNumber++; _levelNumber.Value++;
} }
} }
+3 -11
View File
@@ -1,21 +1,13 @@
using Godot; using Godot;
using GodotHostTest.Helpers;
using GodotHostTest.Interfaces;
using Microsoft.Extensions.Logging;
using OwofGames.AetherBind;
using R3;
namespace GodotHostTest.Game.Projectile; namespace GodotHostTest.Game.Projectile;
public partial class Projectile : Node2D public partial class Projectile : Node2D
{ {
[Inject] private ILogger<Projectile> _logger = null!; [Export] private float _speed = 100;
[Inject] private ITargetSpawner _targetSpawner = null!;
// Called when the node enters the scene tree for the first time. public override void _PhysicsProcess(double delta)
public override void _Ready()
{ {
_targetSpawner.TargetSpawned Position += (float)delta * _speed * Vector2.Up.Rotated(Rotation);
.Subscribe(_ => _logger.LogInformation("Projectile got informed of target spawning")).AddTo(this);
} }
} }
+26
View File
@@ -0,0 +1,26 @@
[gd_scene format=3 uid="uid://brbufibn7hi3o"]
[ext_resource type="Script" uid="uid://dc5mvle8lc40j" path="res://Game/Projectile/Projectile.cs" id="1_g2gsk"]
[ext_resource type="Script" uid="uid://qjonl8stia46" path="res://addons/AetherBind/ServiceSource.cs" id="2_g4q5f"]
[ext_resource type="Texture2D" uid="uid://blwkfvcupjt0v" path="res://Game/Projectile/towerDefense_tile252.png" id="3_r0joc"]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_u8d0v"]
size = Vector2(22, 39)
[node name="Projectile" type="Node2D" unique_id=1686616504]
script = ExtResource("1_g2gsk")
_speed = 600.0
[node name="Scope" type="Node" parent="." unique_id=513224818 node_paths=PackedStringArray("InjectedNodes")]
script = ExtResource("2_g4q5f")
InjectedNodes = [NodePath("..")]
[node name="Sprite2D" type="Sprite2D" parent="." unique_id=1021740171]
texture = ExtResource("3_r0joc")
[node name="Area2D" type="Area2D" parent="." unique_id=863162079]
collision_mask = 2
[node name="CollisionShape2D" type="CollisionShape2D" parent="Area2D" unique_id=1209287052]
position = Vector2(0, 0.5)
shape = SubResource("RectangleShape2D_u8d0v")
Binary file not shown.

After

Width:  |  Height:  |  Size: 702 B

@@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://blwkfvcupjt0v"
path="res://.godot/imported/towerDefense_tile252.png-d5810a59d75c81747798b425c2f018dc.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://Game/Projectile/towerDefense_tile252.png"
dest_files=["res://.godot/imported/towerDefense_tile252.png-d5810a59d75c81747798b425c2f018dc.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
+7 -1
View File
@@ -1,5 +1,8 @@
using Godot; using Godot;
using GodotHostTest.Game.Level; using GodotHostTest.Game.Level;
using GodotHostTest.Game.Score;
using GodotHostTest.Game.Target;
using GodotHostTest.Interfaces;
using OwofGames.GodotLume; using OwofGames.GodotLume;
using RootServiceSource = GodotHostTest.AetherBind.RootServiceSource; using RootServiceSource = GodotHostTest.AetherBind.RootServiceSource;
@@ -11,6 +14,9 @@ public partial class GameServiceSource : RootServiceSource
protected override void Configure(Builder builder) protected override void Configure(Builder builder)
{ {
builder.AddLevelServices(_levelsData); builder
.AddSingleton<ITargetEventBus, TargetEventBus>()
.AddSingleton<IScore, TotalScore>()
.AddLevelServices(_levelsData);
} }
} }
+1 -1
View File
@@ -20,7 +20,7 @@ public partial class Root : Node2D
[WithProvider] [WithProvider]
private void OnInstantiate(IValueSetter<ILevel> levelValueSetter) private void OnInstantiate(IValueSetter<ILevel> levelValueSetter)
{ {
var levelData = _levelDataProvider.GetLevelData(_currentLevel.LevelNumber); var levelData = _levelDataProvider.GetLevelData(_currentLevel.LevelNumber.CurrentValue);
levelValueSetter.Set(levelData); levelValueSetter.Set(levelData);
} }
} }
+9 -15
View File
@@ -6,34 +6,28 @@ using R3;
namespace GodotHostTest.Game.Score; namespace GodotHostTest.Game.Score;
public partial class Score : Control, IScore public partial class Score : Control
{ {
[Export] private AnimationPlayer _animationPlayer = null!; [Export] private AnimationPlayer _animationPlayer = null!;
[Inject] private ICurrentLevel _currentLevel = null!;
[Export] private Label _label = null!; [Export] private Label _label = null!;
private int _score; [Inject] private IScore _score = null!;
[Inject] private ITargetSpawner _targetSpawner = null!;
int IScore.Score => _score;
public override void _Ready() public override void _Ready()
{ {
_targetSpawner.TargetSpawned.Subscribe(OnTargetSpawned).AddTo(this); _score.Score.Subscribe(UpdateScore).AddTo(this);
base._Ready(); _score.Score.Chunk(2, 1).Where(values => values.Length == 2 && values[1] < values[0])
.Subscribe(OnScoreDecreasing).AddTo(this);
} }
private void OnTargetSpawned(ITarget target) private void OnScoreDecreasing<T>(T _)
{ {
_animationPlayer.Play("wiggle"); _animationPlayer.Play("wiggle");
target.Hit.Select(_ => 20).Merge(target.TimedOut.Select(_ => -5)).SubscribeOnce(delta =>
{
_score += delta;
UpdateScore();
}).AddTo(this);
} }
private void UpdateScore() private void UpdateScore(int newScore)
{ {
_label.Text = $"Score: {_score}"; _label.Text = $"Level {_currentLevel.LevelNumber} - Score: {newScore}";
} }
} }
+29
View File
@@ -0,0 +1,29 @@
using System;
using GodotHostTest.Interfaces;
using R3;
namespace GodotHostTest.Game.Score;
public class TotalScore : IScore, IDisposable
{
private readonly IDisposable _connectedObservableDisposable;
public TotalScore(ITargetEventBus targetEventBus)
{
var connectedObservable = targetEventBus.Hit.Select(_ => 20)
.Merge(targetEventBus.TimedOut.Select(_ => -5))
.Scan(0, (x1, x2) => x1 + x2)
.Prepend(0)
.Replay(1);
_connectedObservableDisposable = connectedObservable.Connect();
Score = connectedObservable.AsObservable();
}
public void Dispose()
{
_connectedObservableDisposable.Dispose();
GC.SuppressFinalize(this);
}
public Observable<int> Score { get; }
}
+1
View File
@@ -0,0 +1 @@
uid://gymu1u4w882o
+20
View File
@@ -0,0 +1,20 @@
using GodotHostTest.Helpers;
using GodotHostTest.Interfaces;
using R3;
namespace GodotHostTest.Game.Target;
public class TargetEventBus : ITargetEventBus
{
private readonly Pipe<Unit> _hitOutPipe = new();
private readonly Pipe<Unit> _timedOutPipe = new();
public Observable<Unit> TimedOut => _timedOutPipe.Observable;
public Observable<Unit> Hit => _hitOutPipe.Observable;
public void NewTargetSpawner(ITargetSpawner targetSpawner)
{
_timedOutPipe.PipeIn(targetSpawner.TargetSpawned.SelectMany(target => target.TimedOut));
_hitOutPipe.PipeIn(targetSpawner.TargetSpawned.SelectMany(target => target.Hit));
}
}
+1
View File
@@ -0,0 +1 @@
uid://clr4u1sedssqu
+2
View File
@@ -15,6 +15,7 @@ public partial class TargetSpawner : Node2D, ITargetCollector, ITargetSpawner
[Export] public required Timer Timer; [Export] public required Timer Timer;
[Inject] private ILevel _level = null!; [Inject] private ILevel _level = null!;
[Inject] private ITargetEventBus _targetEventBus = null!;
public void NewTarget(ITarget target) public void NewTarget(ITarget target)
{ {
@@ -26,6 +27,7 @@ public partial class TargetSpawner : Node2D, ITargetCollector, ITargetSpawner
public override void _Ready() public override void _Ready()
{ {
_targetEventBus.NewTargetSpawner(this);
Spawn(); Spawn();
Timer.Start(_level.TimeBetweenSpawns.TotalSeconds); Timer.Start(_level.TimeBetweenSpawns.TotalSeconds);
} }
+13 -11
View File
@@ -1,29 +1,31 @@
[gd_scene format=3 uid="uid://3v8kq1rfwhmr"] [gd_scene format=3 uid="uid://3v8kq1rfwhmr"]
[ext_resource type="Texture2D" uid="uid://y1ros3y7hag2" path="res://icon.svg" id="1_032qf"] [ext_resource type="Script" uid="uid://bv2hat41dyxiv" path="res://Game/Target/Target.cs" id="1_ouani"]
[ext_resource type="Script" uid="uid://bv2hat41dyxiv" path="res://Game/Target.cs" id="1_c0a8e"] [ext_resource type="Texture2D" uid="uid://m4pvy8kkw7k4" path="res://Game/Target/towerDefense_tile136.png" id="2_olsqn"]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_u8d0v"] [sub_resource type="CircleShape2D" id="CircleShape2D_uqpd1"]
size = Vector2(128, 128) radius = 60.033325
[node name="Target" type="Node2D" unique_id=2101558052 node_paths=PackedStringArray("TimeOutTimer", "Image", "CollisionArea")] [node name="Target" type="Node2D" unique_id=2101558052 node_paths=PackedStringArray("CollisionArea", "Image", "TimeOutTimer")]
script = ExtResource("1_c0a8e") script = ExtResource("1_ouani")
CollisionArea = NodePath("CollisionArea")
Image = NodePath("Sprite2D")
TimeOutDurationInSeconds = 7.0 TimeOutDurationInSeconds = 7.0
TimeOutTimer = NodePath("TimeOutTimer") TimeOutTimer = NodePath("TimeOutTimer")
Image = NodePath("Sprite2D")
CollisionArea = NodePath("CollisionArea")
[node name="Sprite2D" type="Sprite2D" parent="." unique_id=31059524] [node name="Sprite2D" type="Sprite2D" parent="." unique_id=31059524]
visible = false visible = false
modulate = Color(1, 0.20392157, 0.015686275, 1) position = Vector2(3.8146973e-06, 3.8146973e-06)
texture = ExtResource("1_032qf") scale = Vector2(1.9687501, 1.9687501)
texture = ExtResource("2_olsqn")
[node name="CollisionArea" type="Area2D" parent="." unique_id=116681968] [node name="CollisionArea" type="Area2D" parent="." unique_id=116681968]
collision_layer = 2
monitoring = false monitoring = false
monitorable = false monitorable = false
[node name="CollisionShape2D" type="CollisionShape2D" parent="CollisionArea" unique_id=1558252366] [node name="CollisionShape2D" type="CollisionShape2D" parent="CollisionArea" unique_id=1558252366]
shape = SubResource("RectangleShape2D_u8d0v") shape = SubResource("CircleShape2D_uqpd1")
[node name="TimeOutTimer" type="Timer" parent="." unique_id=1079777109] [node name="TimeOutTimer" type="Timer" parent="." unique_id=1079777109]
one_shot = true one_shot = true
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

@@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://m4pvy8kkw7k4"
path="res://.godot/imported/towerDefense_tile136.png-16575e41e8dd7b30e746b25e42404084.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://Game/Target/towerDefense_tile136.png"
dest_files=["res://.godot/imported/towerDefense_tile136.png-16575e41e8dd7b30e746b25e42404084.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
+27 -2
View File
@@ -6,11 +6,36 @@ namespace GodotHostTest.Game.Turret;
public partial class Turret : Sprite2D public partial class Turret : Sprite2D
{ {
[Export] private Node2D _launcher = null!;
[Export] private PackedScene _projectilePackedScene = null!; [Export] private PackedScene _projectilePackedScene = null!;
private double _rotationDirection;
[Export] private double _rotationSpeed = 6;
[Inject] private ISceneInstantiator _sceneInstantiator = null!; [Inject] private ISceneInstantiator _sceneInstantiator = null!;
public override void _Ready() private void OnTimerTimeout()
{ {
GetTree().CreateTimer(1).Timeout += () => AddChild(_sceneInstantiator.Instantiate(_projectilePackedScene)); var projectile = _sceneInstantiator.Instantiate<Node2D>(_projectilePackedScene);
projectile.Rotation = _launcher.Rotation;
AddChild(projectile);
}
public override void _Input(InputEvent @event)
{
_rotationDirection = 0;
if (@event.IsActionPressed("rotate_clockwise")) _rotationDirection = 1;
if (@event.IsActionPressed("rotate_counterclockwise")) _rotationDirection = -1;
}
public override void _PhysicsProcess(double delta)
{
_rotationDirection = 0;
if (Input.IsActionPressed("rotate_clockwise")) _rotationDirection = 1;
if (Input.IsActionPressed("rotate_counterclockwise")) _rotationDirection = -1;
_launcher.Rotation += (float)(_rotationSpeed * delta * _rotationDirection);
base._PhysicsProcess(delta);
} }
} }
Binary file not shown.

After

Width:  |  Height:  |  Size: 515 B

@@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://wq1ylxxdyo3t"
path="res://.godot/imported/towerDefense_tile181.png-175b1fdaaa15393876652158f79f62d1.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://Game/Turret/towerDefense_tile181.png"
dest_files=["res://.godot/imported/towerDefense_tile181.png-175b1fdaaa15393876652158f79f62d1.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
Binary file not shown.

After

Width:  |  Height:  |  Size: 921 B

@@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://ce3yr5qcy6tn8"
path="res://.godot/imported/towerDefense_tile206.png-1691c021ff92a454ed8143a8198835e0.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://Game/Turret/towerDefense_tile206.png"
dest_files=["res://.godot/imported/towerDefense_tile206.png-1691c021ff92a454ed8143a8198835e0.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
+29
View File
@@ -0,0 +1,29 @@
[gd_scene format=3 uid="uid://cgixjjrc2kdui"]
[ext_resource type="Texture2D" uid="uid://wq1ylxxdyo3t" path="res://Game/Turret/towerDefense_tile181.png" id="1_fa2t6"]
[ext_resource type="Script" uid="uid://ce7gnp1lcrrdv" path="res://Game/Turret/Turret.cs" id="2_tkk1n"]
[ext_resource type="PackedScene" uid="uid://brbufibn7hi3o" path="res://Game/Projectile/projectile.tscn" id="3_eoix6"]
[ext_resource type="Texture2D" uid="uid://ce3yr5qcy6tn8" path="res://Game/Turret/towerDefense_tile206.png" id="4_q6l7p"]
[sub_resource type="Curve" id="Curve_u8d0v"]
_data = [Vector2(0, 1), 0.0, -1.0, 0, 1, Vector2(1, 0), -1.0, 0.0, 1, 0]
point_count = 2
[node name="Turret" type="Sprite2D" unique_id=682995021 node_paths=PackedStringArray("_launcher")]
texture = ExtResource("1_fa2t6")
script = ExtResource("2_tkk1n")
_projectilePackedScene = ExtResource("3_eoix6")
_launcher = NodePath("Launcher")
[node name="Launcher" type="Sprite2D" parent="." unique_id=1492355681]
texture = ExtResource("4_q6l7p")
[node name="Line2D" type="Line2D" parent="Launcher" unique_id=777442120]
points = PackedVector2Array(0, 0, 0, -270)
width_curve = SubResource("Curve_u8d0v")
default_color = Color(1, 0.1764706, 0.19215687, 0.38039216)
[node name="Timer" type="Timer" parent="." unique_id=95651717]
autostart = true
[connection signal="timeout" from="Timer" to="." method="OnTimerTimeout"]
+3 -9
View File
@@ -1,12 +1,10 @@
[gd_scene format=3 uid="uid://xfd48ep5qi1k"] [gd_scene format=3 uid="uid://xfd48ep5qi1k"]
[ext_resource type="Script" uid="uid://dk578xnlxjwrr" path="res://Game/Level/LevelServiceSource.cs" id="1_5saw1"] [ext_resource type="Script" uid="uid://dk578xnlxjwrr" path="res://Game/Level/LevelServiceSource.cs" id="1_5saw1"]
[ext_resource type="PackedScene" uid="uid://3v8kq1rfwhmr" path="res://Game/target.tscn" id="1_y7rhs"] [ext_resource type="PackedScene" uid="uid://3v8kq1rfwhmr" path="res://Game/Target/target.tscn" id="1_y7rhs"]
[ext_resource type="Script" uid="uid://cxfrtglku2gfa" path="res://Game/Target/TargetSpawner.cs" id="2_5saw1"] [ext_resource type="Script" uid="uid://cxfrtglku2gfa" path="res://Game/Target/TargetSpawner.cs" id="2_5saw1"]
[ext_resource type="Script" uid="uid://bgrjeadxhgmvi" path="res://Game/Score/Score.cs" id="3_spj1u"] [ext_resource type="Script" uid="uid://bgrjeadxhgmvi" path="res://Game/Score/Score.cs" id="3_spj1u"]
[ext_resource type="Texture2D" uid="uid://y1ros3y7hag2" path="res://icon.svg" id="4_esqs7"] [ext_resource type="PackedScene" uid="uid://cgixjjrc2kdui" path="res://Game/Turret/turret.tscn" id="5_m3hgq"]
[ext_resource type="Script" uid="uid://ce7gnp1lcrrdv" path="res://Game/Turret/Turret.cs" id="5_himod"]
[ext_resource type="PackedScene" uid="uid://brbufibn7hi3o" path="res://Game/projectile.tscn" id="6_sin03"]
[sub_resource type="Animation" id="Animation_bbjqm"] [sub_resource type="Animation" id="Animation_bbjqm"]
length = 0.001 length = 0.001
@@ -133,11 +131,7 @@ vertical_alignment = 1
root_node = NodePath("../..") root_node = NodePath("../..")
libraries/ = SubResource("AnimationLibrary_rckqj") libraries/ = SubResource("AnimationLibrary_rckqj")
[node name="Turret" type="Sprite2D" parent="." unique_id=152356196] [node name="Turret" parent="." unique_id=682995021 instance=ExtResource("5_m3hgq")]
modulate = Color(1.92523e-07, 0.88004553, 0.8802661, 1)
position = Vector2(539, 307) position = Vector2(539, 307)
texture = ExtResource("4_esqs7")
script = ExtResource("5_himod")
_projectilePackedScene = ExtResource("6_sin03")
[connection signal="timeout" from="Spawner/Timer" to="Spawner" method="OnTimer"] [connection signal="timeout" from="Spawner/Timer" to="Spawner" method="OnTimer"]
-18
View File
@@ -1,18 +0,0 @@
[gd_scene format=3 uid="uid://brbufibn7hi3o"]
[ext_resource type="Script" uid="uid://dc5mvle8lc40j" path="res://Game/Projectile.cs" id="1_80yud"]
[ext_resource type="Script" uid="uid://qjonl8stia46" path="res://addons/GodotDI/ServiceSource.cs" id="2_3kmdq"]
[ext_resource type="Texture2D" uid="uid://y1ros3y7hag2" path="res://icon.svg" id="3_1i54g"]
[node name="Projectile" type="Node2D" unique_id=1686616504]
script = ExtResource("1_80yud")
[node name="Scope" type="Node" parent="." unique_id=513224818 node_paths=PackedStringArray("InjectedNodes")]
script = ExtResource("2_3kmdq")
InjectedNodes = [NodePath("..")]
[node name="Sprite2D" type="Sprite2D" parent="." unique_id=1021740171]
modulate = Color(1, 1, 0, 1)
rotation = 0.7853982
scale = Vector2(0.3, 0.3)
texture = ExtResource("3_1i54g")
+3 -1
View File
@@ -1,7 +1,9 @@
using R3;
namespace GodotHostTest.Interfaces; namespace GodotHostTest.Interfaces;
public interface ICurrentLevel public interface ICurrentLevel
{ {
public int LevelNumber { get; } public ReadOnlyReactiveProperty<int> LevelNumber { get; }
public void NextLevel(); public void NextLevel();
} }
+3 -1
View File
@@ -1,3 +1,5 @@
using R3;
namespace GodotHostTest.Interfaces; namespace GodotHostTest.Interfaces;
/// <summary> /// <summary>
@@ -8,5 +10,5 @@ public interface IScore
/// <summary> /// <summary>
/// The current score. /// The current score.
/// </summary> /// </summary>
public int Score { get; } public Observable<int> Score { get; }
} }
+3 -2
View File
@@ -8,12 +8,13 @@ namespace GodotHostTest.Interfaces;
public interface ITarget public interface ITarget
{ {
/// <summary> /// <summary>
/// The target hasn't been hit in the allotted time and has timed out. /// The target hasn't been hit in the allotted time and has timed out; once this observable emits an event, both
/// it and <see cref="Hit"/> complete.
/// </summary> /// </summary>
Observable<Unit> TimedOut { get; } Observable<Unit> TimedOut { get; }
/// <summary> /// <summary>
/// The target has been hit. /// The target has been hit; once this observable emits an event, both it and <see cref="TimedOut"/> complete.
/// </summary> /// </summary>
Observable<Unit> Hit { get; } Observable<Unit> Hit { get; }
+22
View File
@@ -0,0 +1,22 @@
using R3;
namespace GodotHostTest.Interfaces;
public interface ITargetEventBus
{
/// <summary>
/// A target has timed out and disappeared.
/// </summary>
Observable<Unit> TimedOut { get; }
/// <summary>
/// A target has been hit.
/// </summary>
Observable<Unit> Hit { get; }
/// <summary>
/// A new target spawner has been added.
/// </summary>
/// <param name="targetSpawner"></param>
void NewTargetSpawner(ITargetSpawner targetSpawner);
}
+1
View File
@@ -0,0 +1 @@
uid://bgexc7hcs5r4n
@@ -17,7 +17,7 @@ public static class SceneInstantiatorExtensions
/// scene, with the provider as argument. /// scene, with the provider as argument.
/// </param> /// </param>
/// <returns>The created node, with its dependencies satisfied.</returns> /// <returns>The created node, with its dependencies satisfied.</returns>
private static T Instantiate<T>(this ISceneInstantiator sceneInstantiator, PackedScene packedScene, public static T Instantiate<T>(this ISceneInstantiator sceneInstantiator, PackedScene packedScene,
Action<IProvider>? onScopeCreated = null) where T : Node Action<IProvider>? onScopeCreated = null) where T : Node
{ {
return (T)sceneInstantiator.Instantiate(packedScene, onScopeCreated); return (T)sceneInstantiator.Instantiate(packedScene, onScopeCreated);
+18
View File
@@ -28,6 +28,24 @@ project/assembly_name="godot-host-test"
enabled=PackedStringArray("res://addons/AetherBind/plugin.cfg") enabled=PackedStringArray("res://addons/AetherBind/plugin.cfg")
[input]
rotate_clockwise={
"deadzone": 0.2,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194321,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
]
}
rotate_counterclockwise={
"deadzone": 0.2,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194319,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
]
}
[layer_names]
2d_physics/layer_1="Projectiles"
2d_physics/layer_2="Targets"
[physics] [physics]
3d/physics_engine="Jolt Physics" 3d/physics_engine="Jolt Physics"