From 4326ca850d12f1bd1caac1361e2a7668916e8f59 Mon Sep 17 00:00:00 2001 From: Gabriel Kaszewski Date: Mon, 21 Jul 2025 22:02:05 +0200 Subject: [PATCH] Implement BeamComponent in C# and enhance marketplace button functionality --- Mr. Brick Adventures.csproj | 7 ++ Mr. Brick Adventures.sln | 19 ++++ Mr. Brick Adventures.sln.DotSettings.user | 4 + scripts/components/BeamComponent.cs | 109 ++++++++++++++++++++++ scripts/components/BeamComponent.cs.uid | 1 + scripts/components/beam_component.gd | 2 +- scripts/ui/marketplace.gd | 27 +++--- 7 files changed, 154 insertions(+), 15 deletions(-) create mode 100644 Mr. Brick Adventures.csproj create mode 100644 Mr. Brick Adventures.sln create mode 100644 Mr. Brick Adventures.sln.DotSettings.user create mode 100644 scripts/components/BeamComponent.cs create mode 100644 scripts/components/BeamComponent.cs.uid diff --git a/Mr. Brick Adventures.csproj b/Mr. Brick Adventures.csproj new file mode 100644 index 0000000..8d43770 --- /dev/null +++ b/Mr. Brick Adventures.csproj @@ -0,0 +1,7 @@ + + + net8.0 + true + Mr.BrickAdventures + + \ No newline at end of file diff --git a/Mr. Brick Adventures.sln b/Mr. Brick Adventures.sln new file mode 100644 index 0000000..7ef00af --- /dev/null +++ b/Mr. Brick Adventures.sln @@ -0,0 +1,19 @@ +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2012 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mr. Brick Adventures", "Mr. Brick Adventures.csproj", "{A1D482B9-207B-4D6C-A0A0-D9E6D1AE2356}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + ExportDebug|Any CPU = ExportDebug|Any CPU + ExportRelease|Any CPU = ExportRelease|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {A1D482B9-207B-4D6C-A0A0-D9E6D1AE2356}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A1D482B9-207B-4D6C-A0A0-D9E6D1AE2356}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A1D482B9-207B-4D6C-A0A0-D9E6D1AE2356}.ExportDebug|Any CPU.ActiveCfg = ExportDebug|Any CPU + {A1D482B9-207B-4D6C-A0A0-D9E6D1AE2356}.ExportDebug|Any CPU.Build.0 = ExportDebug|Any CPU + {A1D482B9-207B-4D6C-A0A0-D9E6D1AE2356}.ExportRelease|Any CPU.ActiveCfg = ExportRelease|Any CPU + {A1D482B9-207B-4D6C-A0A0-D9E6D1AE2356}.ExportRelease|Any CPU.Build.0 = ExportRelease|Any CPU + EndGlobalSection +EndGlobal diff --git a/Mr. Brick Adventures.sln.DotSettings.user b/Mr. Brick Adventures.sln.DotSettings.user new file mode 100644 index 0000000..e8e9aa0 --- /dev/null +++ b/Mr. Brick Adventures.sln.DotSettings.user @@ -0,0 +1,4 @@ + + ForceIncluded + ForceIncluded + ForceIncluded \ No newline at end of file diff --git a/scripts/components/BeamComponent.cs b/scripts/components/BeamComponent.cs new file mode 100644 index 0000000..8f667e0 --- /dev/null +++ b/scripts/components/BeamComponent.cs @@ -0,0 +1,109 @@ +using Godot; + +namespace Mr.BrickAdventures.scripts.components; + +[GlobalClass] +public partial class BeamComponent : Node2D +{ + private float _currentLength = 0.0f; + private const float PixelSize = 16.0f; // Assuming 16 pixels per unit for scaling + + [Export] + public float ExpansionSpeed { get; set; } = 100.0f; + [Export] + public float MaxLength { get; set; } = 512.0f; + [Export] + public Vector2 Direction { get; set; } = Vector2.Down; + [Export] + public Node2D Root { get; set; } + [Export] + public Sprite2D Sprite { get; set; } + [Export] + public CollisionShape2D CollisionShape { get; set; } + + public override void _Ready() + { + if (Root == null) + { + GD.PrintErr("Root node is not set for BeamComponent."); + } + if (Sprite == null) + { + GD.PrintErr("Sprite node is not set for BeamComponent."); + } + if (CollisionShape == null) + { + GD.PrintErr("CollisionShape node is not set for BeamComponent."); + } + + var shape = CollisionShape?.Shape as RectangleShape2D; + shape?.SetSize(new Vector2(_currentLength / 2.0f, _currentLength / 2.0f)); + Sprite?.SetScale(new Vector2(1f, 1f)); + CollisionShape?.SetPosition(Vector2.Zero); + } + + public override void _Process(double delta) + { + var newLength = _currentLength + ExpansionSpeed * (float)delta; + if (newLength > MaxLength) newLength = MaxLength; + + if (!CheckForObstacle(newLength)) ExpandBeam(newLength); + } + + private void ExpandBeam(float newLength) + { + _currentLength = newLength; + + if (Direction == Vector2.Up) + { + var pos = Sprite.Position; + var scale = Sprite.Scale; + var shape = CollisionShape?.Shape as RectangleShape2D; + Sprite.SetScale(new Vector2(scale.X, _currentLength / PixelSize)); + Sprite.SetPosition(new Vector2(pos.X, -_currentLength / 2.0f)); + shape?.SetSize(new Vector2(PixelSize / 2f, _currentLength / 2.0f)); + CollisionShape?.SetPosition(new Vector2(CollisionShape.Position.X, -_currentLength / 2.0f)); + } else if (Direction == Vector2.Down) + { + var pos = Sprite.Position; + var scale = Sprite.Scale; + var shape = CollisionShape?.Shape as RectangleShape2D; + Sprite.SetScale(new Vector2(scale.X, _currentLength / PixelSize)); + Sprite.SetPosition(new Vector2(pos.X, _currentLength / 2.0f)); + shape?.SetSize(new Vector2(PixelSize / 2f, _currentLength / 2.0f)); + CollisionShape?.SetPosition(new Vector2(CollisionShape.Position.X, _currentLength / 2.0f)); + } else if (Direction == Vector2.Left) + { + var pos = Sprite.Position; + var scale = Sprite.Scale; + var shape = CollisionShape?.Shape as RectangleShape2D; + Sprite.SetScale(new Vector2(_currentLength / PixelSize, scale.Y)); + Sprite.SetPosition(new Vector2(-_currentLength / 2.0f, pos.Y)); + shape?.SetSize(new Vector2(_currentLength / 2.0f, PixelSize / 2f)); + CollisionShape?.SetPosition(new Vector2(-_currentLength / 2.0f, CollisionShape.Position.Y)); + } else if (Direction == Vector2.Right) + { + var pos = Sprite.Position; + var scale = Sprite.Scale; + var shape = CollisionShape?.Shape as RectangleShape2D; + Sprite.SetScale(new Vector2(_currentLength / PixelSize, scale.Y)); + Sprite.SetPosition(new Vector2(_currentLength / 2.0f, pos.Y)); + shape?.SetSize(new Vector2(_currentLength / 2.0f, PixelSize / 2f)); + CollisionShape?.SetPosition(new Vector2(_currentLength / 2.0f, CollisionShape.Position.Y)); + } + } + + private bool CheckForObstacle(float newLength) + { + var spaceState = GetWorld2D().DirectSpaceState; + var queryStart = GlobalPosition; + var queryEnd = queryStart + Direction.Normalized() * newLength; + var query = PhysicsRayQueryParameters2D.Create(queryStart, queryEnd); + + query.CollideWithAreas = false; + query.CollideWithBodies = true; + + var result = spaceState.IntersectRay(query); + return result.Count > 0; + } +} \ No newline at end of file diff --git a/scripts/components/BeamComponent.cs.uid b/scripts/components/BeamComponent.cs.uid new file mode 100644 index 0000000..440ee32 --- /dev/null +++ b/scripts/components/BeamComponent.cs.uid @@ -0,0 +1 @@ +uid://df1llrbm80e02 diff --git a/scripts/components/beam_component.gd b/scripts/components/beam_component.gd index 844734e..69bda9f 100644 --- a/scripts/components/beam_component.gd +++ b/scripts/components/beam_component.gd @@ -1,4 +1,4 @@ -class_name BeamComponent +# class_name BeamComponent extends Node2D @export var expansion_speed: float = 16.0 diff --git a/scripts/ui/marketplace.gd b/scripts/ui/marketplace.gd index 172aadb..41a5309 100644 --- a/scripts/ui/marketplace.gd +++ b/scripts/ui/marketplace.gd @@ -13,7 +13,6 @@ extends Node @onready var game_manager: GM = $"/root/GameManager" - var unlock_buttons: Array[Button] = [] var skill_buttons: Array[SkillButton] = [] @@ -36,6 +35,14 @@ func _ready() -> void: skill_unlocker.skill_unlocked.connect(on_skill_unlocked) +func _process(_delta: float) -> void: + for btn in skill_buttons: + if not btn.skill_data: + continue + if btn.skill_data.is_active: + btn.activate() + else: + btn.deactivate() func _input(event: InputEvent) -> void: if event.is_action_pressed("show_marketplace"): @@ -53,7 +60,6 @@ func get_button_text(skill: SkillData) -> String: return tr(skill.name) + " " + str(skill.cost) - func create_upgrade_button(skill: SkillData) -> void: var button := marketplace_button.instantiate() as MarketplaceButton button.text = get_button_text(skill) @@ -102,26 +108,19 @@ func _on_button_pressed(skill: SkillData) -> void: func on_skill_unlocked(skill: SkillData) -> void: - # need to fix this method if not skill: return - if skill_buttons.size() == 0: - create_skill_button(skill) - for button in skill_buttons: - if button.skill_data.is_active: - button.activate() - else: - button.deactivate() + for btn in skill_buttons: + if btn.skill_data and btn.skill_data.name == skill.name: + return + create_skill_button(skill) + func on_skill_button_pressed(button: SkillButton) -> void: if not skill_unlocker or not button.skill_data: return skill_unlocker.skill_manager.toggle_skill_activation(button.skill_data) - button.activate() - for other_button in skill_buttons: - if other_button != button: - other_button.deactivate()