Implement BeamComponent in C# and enhance marketplace button functionality

This commit is contained in:
2025-07-21 22:02:05 +02:00
parent cce93286be
commit 4326ca850d
7 changed files with 154 additions and 15 deletions

View File

@@ -0,0 +1,7 @@
<Project Sdk="Godot.NET.Sdk/4.4.1">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<EnableDynamicLoading>true</EnableDynamicLoading>
<RootNamespace>Mr.BrickAdventures</RootNamespace>
</PropertyGroup>
</Project>

19
Mr. Brick Adventures.sln Normal file
View File

@@ -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

View File

@@ -0,0 +1,4 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ACollisionShape2D_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FSourcesCache_003F2ca9b7334678f5c97c7c2a9fbe4837be71cae11b6a30408dd4791b18f997e4a_003FCollisionShape2D_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ARectangleShape2D_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FSourcesCache_003Fa1cc98873548652da0c14ecefa4737431426fcbb24a7f0641e3d9c266c3_003FRectangleShape2D_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AShape2D_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FSourcesCache_003F3671dbbd9b17cdf2bf9075b468b6bd7e3ab13fc3be7a116484085d3b6cc9fe_003FShape2D_002Ecs/@EntryIndexedValue">ForceIncluded</s:String></wpf:ResourceDictionary>

View File

@@ -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;
}
}

View File

@@ -0,0 +1 @@
uid://df1llrbm80e02

View File

@@ -1,4 +1,4 @@
class_name BeamComponent # class_name BeamComponent
extends Node2D extends Node2D
@export var expansion_speed: float = 16.0 @export var expansion_speed: float = 16.0

View File

@@ -13,7 +13,6 @@ extends Node
@onready var game_manager: GM = $"/root/GameManager" @onready var game_manager: GM = $"/root/GameManager"
var unlock_buttons: Array[Button] = [] var unlock_buttons: Array[Button] = []
var skill_buttons: Array[SkillButton] = [] var skill_buttons: Array[SkillButton] = []
@@ -36,6 +35,14 @@ func _ready() -> void:
skill_unlocker.skill_unlocked.connect(on_skill_unlocked) 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: func _input(event: InputEvent) -> void:
if event.is_action_pressed("show_marketplace"): 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) return tr(skill.name) + " " + str(skill.cost)
func create_upgrade_button(skill: SkillData) -> void: func create_upgrade_button(skill: SkillData) -> void:
var button := marketplace_button.instantiate() as MarketplaceButton var button := marketplace_button.instantiate() as MarketplaceButton
button.text = get_button_text(skill) button.text = get_button_text(skill)
@@ -102,17 +108,14 @@ func _on_button_pressed(skill: SkillData) -> void:
func on_skill_unlocked(skill: SkillData) -> void: func on_skill_unlocked(skill: SkillData) -> void:
# need to fix this method
if not skill: if not skill:
return return
if skill_buttons.size() == 0:
create_skill_button(skill)
for button in skill_buttons: for btn in skill_buttons:
if button.skill_data.is_active: if btn.skill_data and btn.skill_data.name == skill.name:
button.activate() return
else:
button.deactivate() create_skill_button(skill)
func on_skill_button_pressed(button: SkillButton) -> void: func on_skill_button_pressed(button: SkillButton) -> void:
@@ -120,8 +123,4 @@ func on_skill_button_pressed(button: SkillButton) -> void:
return return
skill_unlocker.skill_manager.toggle_skill_activation(button.skill_data) 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()