Adjust the time of spawns of items and enemies in the map to when the player first enters the room.

将地图中物品,敌人生成的时机调整到玩家首次进入房间时。
This commit is contained in:
Cold-Mint 2024-10-08 16:11:51 +08:00
parent 5371d31d99
commit d80c49ab02
Signed by: Cold-Mint
GPG Key ID: C5A9BF8A98E0CE99
14 changed files with 200 additions and 196 deletions

View File

@ -55,7 +55,6 @@ shape = SubResource("RectangleShape2D_7tsse")
[node name="Marker2D" type="Marker2D" parent="."] [node name="Marker2D" type="Marker2D" parent="."]
position = Vector2(260, 87) position = Vector2(260, 87)
script = ExtResource("1_y2vgj") script = ExtResource("1_y2vgj")
ResPath = "res://prefab/entitys/DelivererOfDarkMagic.tscn"
[node name="NavigationRegion2D" type="NavigationRegion2D" parent="."] [node name="NavigationRegion2D" type="NavigationRegion2D" parent="."]
navigation_polygon = SubResource("NavigationPolygon_rh1gx") navigation_polygon = SubResource("NavigationPolygon_rh1gx")

View File

@ -54,7 +54,6 @@ shape = SubResource("RectangleShape2D_7tsse")
[node name="Marker2D" type="Marker2D" parent="."] [node name="Marker2D" type="Marker2D" parent="."]
position = Vector2(260, 87) position = Vector2(260, 87)
script = ExtResource("2_wamhd") script = ExtResource("2_wamhd")
ResPath = "res://prefab/entitys/DelivererOfDarkMagic.tscn"
[node name="NavigationRegion2D" type="NavigationRegion2D" parent="."] [node name="NavigationRegion2D" type="NavigationRegion2D" parent="."]
navigation_polygon = SubResource("NavigationPolygon_rh1gx") navigation_polygon = SubResource("NavigationPolygon_rh1gx")

View File

@ -37,7 +37,7 @@ position = Vector2(751.5, 289.438)
shape = SubResource("RectangleShape2D_jxmys") shape = SubResource("RectangleShape2D_jxmys")
debug_color = Color(0, 0.6, 0.701961, 0.419608) debug_color = Color(0, 0.6, 0.701961, 0.419608)
[node name="Marker2D" type="Marker2D" parent="."] [node name="PlayerSpawn" type="Marker2D" parent="."]
position = Vector2(54, 256) position = Vector2(54, 256)
script = ExtResource("1_q04qt") script = ExtResource("1_q04qt")
@ -73,16 +73,6 @@ position = Vector2(386, 178)
scale = Vector2(23.9375, 11.0625) scale = Vector2(23.9375, 11.0625)
texture = ExtResource("3_atgj7") texture = ExtResource("3_atgj7")
[node name="Marker2D2" type="Marker2D" parent="."]
position = Vector2(100, 250)
script = ExtResource("4_6ihp7")
ItemId = "staff_necromancy"
[node name="Marker2D3" type="Marker2D" parent="."]
position = Vector2(134, 248)
script = ExtResource("4_6ihp7")
ItemId = "necromancy"
[node name="Label" type="Label" parent="."] [node name="Label" type="Label" parent="."]
offset_left = 37.0 offset_left = 37.0
offset_top = 46.0 offset_top = 46.0
@ -115,3 +105,15 @@ position = Vector2(715, 162)
[node name="WoodenBox4" parent="." instance=ExtResource("7_jybe6")] [node name="WoodenBox4" parent="." instance=ExtResource("7_jybe6")]
position = Vector2(714, 122) position = Vector2(714, 122)
[node name="AutoSpawn" type="Node2D" parent="."]
[node name="necromancy" type="Marker2D" parent="AutoSpawn"]
position = Vector2(134, 248)
script = ExtResource("4_6ihp7")
ItemId = "necromancy"
[node name="staff_necromancy" type="Marker2D" parent="AutoSpawn"]
position = Vector2(100, 250)
script = ExtResource("4_6ihp7")
ItemId = "staff_necromancy"

View File

@ -91,11 +91,6 @@ offset_right = 453.0
offset_bottom = 151.0 offset_bottom = 151.0
text = "ui_tutorial_combine_more_powerful_spells" text = "ui_tutorial_combine_more_powerful_spells"
[node name="Marker2D" type="Marker2D" parent="."]
position = Vector2(434, 105)
script = ExtResource("4_fh50l")
ItemId = "x3"
[node name="WoodenBox" parent="." instance=ExtResource("4_60glh")] [node name="WoodenBox" parent="." instance=ExtResource("4_60glh")]
position = Vector2(711, 179) position = Vector2(711, 179)
@ -129,3 +124,10 @@ position = Vector2(473, 285)
[node name="TripleShotSpell" type="Sprite2D" parent="."] [node name="TripleShotSpell" type="Sprite2D" parent="."]
position = Vector2(637, 85) position = Vector2(637, 85)
texture = ExtResource("6_2qcf3") texture = ExtResource("6_2qcf3")
[node name="AutoSpawn" type="Node2D" parent="."]
[node name="x3" type="Marker2D" parent="AutoSpawn"]
position = Vector2(434, 105)
script = ExtResource("4_fh50l")
ItemId = "x3"

View File

@ -9,12 +9,6 @@ namespace ColdMint.scripts;
/// </summary> /// </summary>
public static class EventBus public static class EventBus
{ {
/// <summary>
/// <para>Event when the AI character is generated</para>
/// <para>AI角色生成事件</para>
/// </summary>
public static Action<AiCharacterGenerateEvent>? AiCharacterGenerateEvent;
/// <summary> /// <summary>
/// <para>Game Over Event</para> /// <para>Game Over Event</para>
/// <para>游戏结束事件</para> /// <para>游戏结束事件</para>

View File

@ -1,5 +1,5 @@
using ColdMint.scripts.character; using ColdMint.scripts.character;
using ColdMint.scripts.map.events; using ColdMint.scripts.map.room;
using ColdMint.scripts.utils; using ColdMint.scripts.utils;
using Godot; using Godot;
@ -9,52 +9,45 @@ namespace ColdMint.scripts.map;
/// <para>Ai character generation point</para> /// <para>Ai character generation point</para>
/// <para>Ai角色生成点</para> /// <para>Ai角色生成点</para>
/// </summary> /// </summary>
public partial class AiCharacterSpawn : Marker2D public partial class AiCharacterSpawn : Marker2D, ISpawnMarker
{ {
private PackedScene? _packedScene; private PackedScene? _packedScene;
[Export] [Export] private string? _resPath;
public string? ResPath;
public override void _Ready() public override void _Ready()
{ {
base._Ready(); base._Ready();
if (!string.IsNullOrEmpty(ResPath)) if (!string.IsNullOrEmpty(_resPath))
{ {
_packedScene = GD.Load<PackedScene>(ResPath); _packedScene = GD.Load<PackedScene>(_resPath);
}
} }
EventBus.AiCharacterGenerateEvent += OnAiCharacterGenerateEvent; public Node2D? Spawn()
}
/// <summary>
/// <para>When an event is triggered</para>
/// <para>当触发事件时</para>
/// </summary>
/// <param name="aiCharacterGenerateEvent"></param>
public void OnAiCharacterGenerateEvent(AiCharacterGenerateEvent aiCharacterGenerateEvent)
{ {
if (GameSceneDepend.AiCharacterContainer == null) if (GameSceneDepend.AiCharacterContainer == null || _packedScene == null)
{ {
return; return null;
}
if (_packedScene == null)
{
return;
} }
var aiCharacter = NodeUtils.InstantiatePackedScene<AiCharacter>(_packedScene); var aiCharacter = NodeUtils.InstantiatePackedScene<AiCharacter>(_packedScene);
if (aiCharacter == null) if (aiCharacter == null)
{ {
return; return null;
} }
NodeUtils.CallDeferredAddChild(GameSceneDepend.AiCharacterContainer, aiCharacter); NodeUtils.CallDeferredAddChild(GameSceneDepend.AiCharacterContainer, aiCharacter);
aiCharacter.GlobalPosition = GlobalPosition; aiCharacter.GlobalPosition = GlobalPosition;
return aiCharacter;
} }
public override void _ExitTree() public bool CanQueueFree()
{ {
EventBus.AiCharacterGenerateEvent -= OnAiCharacterGenerateEvent; return true;
}
public void DoQueueFree()
{
QueueFree();
} }
} }

View File

@ -1,6 +1,6 @@
using ColdMint.scripts.debug; using ColdMint.scripts.debug;
using ColdMint.scripts.inventory; using ColdMint.scripts.inventory;
using ColdMint.scripts.map.events; using ColdMint.scripts.map.room;
using Godot; using Godot;
namespace ColdMint.scripts.map; namespace ColdMint.scripts.map;
@ -9,36 +9,34 @@ namespace ColdMint.scripts.map;
/// <para>ItemSpawn</para> /// <para>ItemSpawn</para>
/// <para>物品出生点</para> /// <para>物品出生点</para>
/// </summary> /// </summary>
public partial class ItemSpawn : Marker2D public partial class ItemSpawn : Marker2D, ISpawnMarker
{ {
[Export] public string? ItemId { get; private set; } [Export] private string? ItemId { get; set; }
public override void _Ready() public Node2D? Spawn()
{ {
base._Ready(); if (string.IsNullOrEmpty(ItemId))
EventBus.MapGenerationCompleteEvent += MapGenerationCompleteEvent;
}
private void MapGenerationCompleteEvent(MapGenerationCompleteEvent mapGenerationCompleteEvent)
{ {
//After the map is generated, create the item instance. return null;
//当地图生成完成后,创建物品实例。
if (ItemId == null)
{
return;
} }
var item = ItemTypeManager.CreateItem(ItemId, this); var item = ItemTypeManager.CreateItem(ItemId, this);
LogCat.LogWithFormat("generated_item_is_empty",LogCat.LogLabel.ItemSpawn,true,ItemId,item == null); LogCat.LogWithFormat("generated_item_is_empty", LogCat.LogLabel.ItemSpawn, true, ItemId, item == null);
if (item is Node2D node2D) if (item is not Node2D node2D)
{ {
node2D.GlobalPosition = GlobalPosition; return null;
} }
node2D.GlobalPosition = GlobalPosition;
return node2D;
} }
public override void _ExitTree() public bool CanQueueFree()
{ {
base._ExitTree(); return true;
EventBus.MapGenerationCompleteEvent -= MapGenerationCompleteEvent; }
public void DoQueueFree()
{
QueueFree();
} }
} }

View File

@ -311,11 +311,6 @@ public static class MapGenerator
RoomDictionary = roomDictionary RoomDictionary = roomDictionary
}; };
EventBus.MapGenerationCompleteEvent?.Invoke(eventObj); EventBus.MapGenerationCompleteEvent?.Invoke(eventObj);
var aiCharacterGenerateEvent = new AiCharacterGenerateEvent
{
Tag = AiCharacterGenerateEvent.TagMapGenerationComplete
};
EventBus.AiCharacterGenerateEvent?.Invoke(aiCharacterGenerateEvent);
} }

View File

@ -2,6 +2,7 @@
using ColdMint.scripts.character; using ColdMint.scripts.character;
using ColdMint.scripts.debug; using ColdMint.scripts.debug;
using ColdMint.scripts.map.events; using ColdMint.scripts.map.events;
using ColdMint.scripts.map.room;
using ColdMint.scripts.utils; using ColdMint.scripts.utils;
using Godot; using Godot;
@ -11,7 +12,7 @@ namespace ColdMint.scripts.map;
/// <para>PlayerSpawn</para> /// <para>PlayerSpawn</para>
/// <para>玩家出生点</para> /// <para>玩家出生点</para>
/// </summary> /// </summary>
public partial class PlayerSpawn : Marker2D public partial class PlayerSpawn : Marker2D,ISpawnMarker
{ {
private PackedScene? _playerPackedScene; private PackedScene? _playerPackedScene;
@ -31,32 +32,49 @@ public partial class PlayerSpawn : Marker2D
GameSceneDepend.Player.GlobalPosition = GlobalPosition; GameSceneDepend.Player.GlobalPosition = GlobalPosition;
return; return;
} }
Spawn();
SpawnPlayer();
} }
/// <summary>
/// <para>Generate player instance</para> private void MapGenerationCompleteEvent(MapGenerationCompleteEvent mapGenerationCompleteEvent)
/// <para>生成玩家实例</para> {
/// </summary> //After the map is generated, create the player instance.
private void SpawnPlayer() //当地图生成完成后,创建玩家实例。
if (GameSceneDepend.Player != null)
{
//An existing player instance will not be created.
//已经存在玩家实例,不再创建。
return;
}
Spawn();
}
public override void _ExitTree()
{
base._ExitTree();
EventBus.MapGenerationCompleteEvent -= MapGenerationCompleteEvent;
EventBus.GameReplayEvent -= GameReplayEvent;
}
public Node2D? Spawn()
{ {
if (GameSceneDepend.PlayerContainer == null) if (GameSceneDepend.PlayerContainer == null)
{ {
return; return null;
} }
if (_playerPackedScene == null) if (_playerPackedScene == null)
{ {
LogCat.LogError("player_packed_scene_not_exist"); LogCat.LogError("player_packed_scene_not_exist");
return; return null;
} }
var playerNode = var playerNode =
NodeUtils.InstantiatePackedScene<Player>(_playerPackedScene); NodeUtils.InstantiatePackedScene<Player>(_playerPackedScene);
if (playerNode == null) if (playerNode == null)
{ {
return; return null;
} }
//The player's parent node must be GameSceneDepend PlayerContainer. //The player's parent node must be GameSceneDepend PlayerContainer.
@ -73,26 +91,16 @@ public partial class PlayerSpawn : Marker2D
playerNode.ItemContainer = itemContainer; playerNode.ItemContainer = itemContainer;
GameSceneDepend.Player = playerNode; GameSceneDepend.Player = playerNode;
playerNode.GlobalPosition = GlobalPosition; playerNode.GlobalPosition = GlobalPosition;
return playerNode;
} }
private void MapGenerationCompleteEvent(MapGenerationCompleteEvent mapGenerationCompleteEvent) public bool CanQueueFree()
{ {
//After the map is generated, create the player instance. return false;
//当地图生成完成后,创建玩家实例。
if (GameSceneDepend.Player != null)
{
//An existing player instance will not be created.
//已经存在玩家实例,不再创建。
return;
} }
SpawnPlayer(); public void DoQueueFree()
}
public override void _ExitTree()
{ {
base._ExitTree(); QueueFree();
EventBus.MapGenerationCompleteEvent -= MapGenerationCompleteEvent;
EventBus.GameReplayEvent -= GameReplayEvent;
} }
} }

View File

@ -1,23 +0,0 @@
namespace ColdMint.scripts.map.events;
/// <summary>
/// <para>AiCharacterGenerateEvent</para>
/// <para>Ai角色生成事件</para>
/// </summary>
public class AiCharacterGenerateEvent
{
/// <summary>
/// <para>Map generation completed Tag</para>
/// <para>地图生成完成的Tag</para>
/// </summary>
public const string TagMapGenerationComplete = "MapGenerationComplete";
/// <summary>
/// <para>The Tag used to generate the role</para>
/// <para>生成角色时使用的Tag</para>
/// </summary>
// ReSharper disable UnusedAutoPropertyAccessor.Global
public string? Tag { get; set; }
// ReSharper restore UnusedAutoPropertyAccessor.Global
}

View File

@ -19,7 +19,11 @@ public interface IEnterRoomEventHandler
/// <para>When entering the room</para> /// <para>When entering the room</para>
/// <para>当进入房间时</para> /// <para>当进入房间时</para>
/// </summary> /// </summary>
/// <param name="playerRoomVisitCount">
///<para>The number of times the player visits the room, 1 is the first visit.</para>
///<para>玩家访问房间的次数为1则代表首次访问。</para>
/// </param>
/// <param name="node"></param> /// <param name="node"></param>
/// <param name="room"></param> /// <param name="room"></param>
void OnEnterRoom(Node node,Room room); void OnEnterRoom(int playerRoomVisitCount,Node node,Room room);
} }

View File

@ -0,0 +1,33 @@
using Godot;
namespace ColdMint.scripts.map.room;
/// <summary>
/// <para>The tag of the generated entity</para>
/// <para>生成实体的标记</para>
/// </summary>
public interface ISpawnMarker
{
/// <summary>
/// <para>Generating entity</para>
/// <para>生成实体</para>
/// </summary>
/// <remarks>
///<para>Return the result of the generation. If null is returned, the generation fails.</para>
///<para>返回生成结果为null则生成失败。</para>
/// </remarks>
Node2D? Spawn();
/// <summary>
/// <para>Can Queue Free</para>
/// <para>可释放节点吗</para>
/// </summary>
/// <returns></returns>
bool CanQueueFree();
/// <summary>
/// <para>Execute Queue Free</para>
/// <para>执行释放节点</para>
/// </summary>
void DoQueueFree();
}

View File

@ -29,6 +29,18 @@ public class Room
private bool _hasPlayer; private bool _hasPlayer;
private readonly List<CharacterTemplate> _characterTemplateList = []; private readonly List<CharacterTemplate> _characterTemplateList = [];
/// <summary>
/// <para>When the player first enters the room, all <see cref="ISpawnMarker"/> nodes under this node are executed</para>
/// <para>当玩家首次进入房间时,会执行此节点下所有<see cref="ISpawnMarker"/>节点</para>
/// </summary>
private Node2D? _autoSpawn;
/// <summary>
/// <para>The number of times the player visits the room</para>
/// <para>玩家访问房间的次数</para>
/// </summary>
private int PlayerRoomVisitCount { get; set; }
public string? EnterRoomEventHandlerId { get; set; } public string? EnterRoomEventHandlerId { get; set; }
public string? ExitRoomEventHandlerId { get; set; } public string? ExitRoomEventHandlerId { get; set; }
@ -51,47 +63,31 @@ public class Room
} }
/// <summary> /// <summary>
/// <para>Places a barrier in a slot where a match has been found.</para> /// <para>Place barriers in all slots</para>
/// <para>在找到匹配的槽位放置屏障。</para> /// <para>在所有的槽位放置屏障</para>
/// </summary> /// </summary>
private void PlaceBarrierInMatchedSlot() public void PlaceBarriersInAllSlots()
{ {
ProcessRoomSlots(action: (roomSlot, ground, barrier, i) => var barrier = GetTileMapLayer(Config.TileMapLayerName.Barrier);
{ if (barrier == null)
if (!roomSlot.Matched)
{ {
return; return;
} }
var cellSourceId = barrier.GetCellSourceId(i); barrier.Enabled = true;
if (cellSourceId == -1)
{
return;
}
ground.SetCell(i, cellSourceId, barrier.GetCellAtlasCoords(i), barrier.GetCellAlternativeTile(i));
});
} }
/// <summary> /// <summary>
/// <para>Clear the barrier that finds a matching slot</para> /// <para>Clear all matched barriers</para>
/// <para>清空找到匹配的槽位的屏障。</para> /// <para>清空所有已匹配位置的屏障</para>
/// </summary> /// </summary>
private void ClearBarriersInMatchedSlots() public void ClearAllMatchedBarriers()
{ {
ProcessRoomSlots(action: (roomSlot, ground, barrier, i) => var barrier = GetTileMapLayer(Config.TileMapLayerName.Barrier);
{ if (barrier == null)
if (!roomSlot.Matched)
{ {
return; return;
} }
var cellSourceId = barrier.GetCellSourceId(i); barrier.Enabled = false;
if (cellSourceId == -1)
{
return;
}
ground.SetCell(i, cellSourceId, barrier.GetCellAtlasCoords(i), barrier.GetCellAlternativeTile(i));
});
} }
/// <summary> /// <summary>
@ -99,32 +95,6 @@ public class Room
/// <para>在未匹配的槽位放置屏障。</para> /// <para>在未匹配的槽位放置屏障。</para>
/// </summary> /// </summary>
public void PlaceBarrierInUnmatchedSlots() public void PlaceBarrierInUnmatchedSlots()
{
ProcessRoomSlots(action: (roomSlot, ground, barrier, i) =>
{
if (roomSlot.Matched)
{
return;
}
var cellSourceId = barrier.GetCellSourceId(i);
if (cellSourceId == -1)
{
return;
}
ground.SetCell(i, cellSourceId, barrier.GetCellAtlasCoords(i), barrier.GetCellAlternativeTile(i));
});
}
/// <summary>
/// <para>Executes a callback for each room slot, providing the corresponding coordinates in the barrier and ground layers.</para>
/// <para>对每个房间槽位执行回调提供barrier层和ground层对应的坐标。</para>
/// </summary>
/// <param name="action">
///<para>The callback action to be executed, which takes the barrier layer, ground layer, and coordinates as parameters.</para>
///<para>要执行的回调操作,它以屏障层、底层和坐标作为参数。</para>
/// </param>
private void ProcessRoomSlots(Action<RoomSlot, TileMapLayer, TileMapLayer, Vector2I> action)
{ {
var ground = GetTileMapLayer(Config.TileMapLayerName.Ground); var ground = GetTileMapLayer(Config.TileMapLayerName.Ground);
var barrier = GetTileMapLayer(Config.TileMapLayerName.Barrier); var barrier = GetTileMapLayer(Config.TileMapLayerName.Barrier);
@ -149,12 +119,22 @@ public class Room
//将屏障层的对应坐标瓦片放到地面层。 //将屏障层的对应坐标瓦片放到地面层。
CoordinateUtils.ForEachCell(roomSlot.StartPosition, roomSlot.EndPosition, i => CoordinateUtils.ForEachCell(roomSlot.StartPosition, roomSlot.EndPosition, i =>
{ {
action.Invoke(roomSlot, ground, barrier, i); if (roomSlot.Matched)
{
return;
}
var cellSourceId = barrier.GetCellSourceId(i);
if (cellSourceId == -1)
{
return;
}
ground.SetCell(i, cellSourceId, barrier.GetCellAtlasCoords(i), barrier.GetCellAlternativeTile(i));
}); });
} }
barrier.QueueFree(); barrier.Enabled = false;
} }
/// <summary> /// <summary>
/// <para>ShowAllCharacterTemplate</para> /// <para>ShowAllCharacterTemplate</para>
/// <para>显示所有角色模板</para> /// <para>显示所有角色模板</para>
@ -200,6 +180,15 @@ public class Room
{ {
_characterTemplateList.Add(player); _characterTemplateList.Add(player);
_hasPlayer = true; _hasPlayer = true;
PlayerRoomVisitCount++;
if (PlayerRoomVisitCount == 1 && _autoSpawn != null)
{
NodeUtils.ForEachNode<ISpawnMarker>(_autoSpawn, marker =>
{
marker.Spawn();
return false;
});
}
//The player enters the room, opening up their view. //The player enters the room, opening up their view.
//玩家进入了房间,开放视野。 //玩家进入了房间,开放视野。
if (_pointLight2D != null) if (_pointLight2D != null)
@ -231,7 +220,7 @@ public class Room
} }
var enterRoomEventHandler = RoomEventManager.GetEnterRoomEventHandler(EnterRoomEventHandlerId); var enterRoomEventHandler = RoomEventManager.GetEnterRoomEventHandler(EnterRoomEventHandlerId);
enterRoomEventHandler?.OnEnterRoom(node, this); enterRoomEventHandler?.OnEnterRoom(PlayerRoomVisitCount, node, this);
} }
@ -260,8 +249,18 @@ public class Room
_pointLight2D.Show(); _pointLight2D.Show();
_pointLight2D.Texture = AssetHolder.White25; _pointLight2D.Texture = AssetHolder.White25;
} }
HideAllCharacterTemplate(); HideAllCharacterTemplate();
if (PlayerRoomVisitCount == 1 && _autoSpawn != null)
{
NodeUtils.ForEachNode<ISpawnMarker>(_autoSpawn, marker =>
{
if (marker.CanQueueFree())
{
marker.DoQueueFree();
}
return false;
});
}
} }
else if (node is CharacterTemplate characterTemplate && characterTemplate.Visible) else if (node is CharacterTemplate characterTemplate && characterTemplate.Visible)
{ {
@ -312,8 +311,8 @@ public class Room
return; return;
} }
var node2D = NodeUtils.InstantiatePackedScene<Node2D>(packedScene); var rootNode = NodeUtils.InstantiatePackedScene<Node2D>(packedScene);
if (node2D == null) if (rootNode == null)
{ {
//The room node is not of Node2D type. An exception is thrown //The room node is not of Node2D type. An exception is thrown
//房间节点不是Node2D类型抛出异常 //房间节点不是Node2D类型抛出异常
@ -321,15 +320,15 @@ public class Room
return; return;
} }
_rootNode = node2D; _rootNode = rootNode;
var tileMapNode = node2D.GetNode<Node2D>("TileMap"); var tileMapNode = rootNode.GetNode<Node2D>("TileMap");
NodeUtils.ForEachNode<TileMapLayer>(tileMapNode, node => NodeUtils.ForEachNode<TileMapLayer>(tileMapNode, node =>
{ {
_tileMapLayers ??= []; _tileMapLayers ??= [];
_tileMapLayers.Add(node); _tileMapLayers.Add(node);
return false; return false;
}); });
_area2D = node2D.GetNode<Area2D>("RoomArea"); _area2D = rootNode.GetNode<Area2D>("RoomArea");
_area2D.Monitoring = true; _area2D.Monitoring = true;
_area2D.SetCollisionLayerValue(Config.LayerNumber.RoomArea, true); _area2D.SetCollisionLayerValue(Config.LayerNumber.RoomArea, true);
//Sets the collision layer that can be detected in the current room area. //Sets the collision layer that can be detected in the current room area.
@ -340,12 +339,13 @@ public class Room
_area2D.BodyEntered += OnEnterRoom; _area2D.BodyEntered += OnEnterRoom;
_collisionShape2D = _area2D.GetChild<CollisionShape2D>(0); _collisionShape2D = _area2D.GetChild<CollisionShape2D>(0);
_roomSlots = GetRoomSlots(GetTileMapLayer(Config.TileMapLayerName.Ground), _area2D, _roomSlots = GetRoomSlots(GetTileMapLayer(Config.TileMapLayerName.Ground), _area2D,
node2D.GetNode<Node2D>("RoomSlotList")); rootNode.GetNode<Node2D>("RoomSlotList"));
_pointLight2D = node2D.GetNodeOrNull<PointLight2D>("PointLight2D"); _pointLight2D = rootNode.GetNodeOrNull<PointLight2D>("PointLight2D");
if (_pointLight2D != null) if (_pointLight2D != null)
{ {
_pointLight2D.BlendMode = Light2D.BlendModeEnum.Mix; _pointLight2D.BlendMode = Light2D.BlendModeEnum.Mix;
} }
_autoSpawn = rootNode.GetNodeOrNull<Node2D>("AutoSpawn");
} }
public Node2D? RootNode => _rootNode; public Node2D? RootNode => _rootNode;

View File

@ -131,10 +131,10 @@ public static class NodeUtils
///<para>用于处理回调的函数返回true终止遍历节点</para> ///<para>用于处理回调的函数返回true终止遍历节点</para>
/// </param> /// </param>
/// <typeparam name="T"> /// <typeparam name="T">
///<para>When the type is specified as Node, all child nodes are returned.</para> ///<para>Specifies the generic type</para>
///<para>当指定类型为Node时将返回所有子节点。</para> ///<para>指定的泛型</para>
/// </typeparam> /// </typeparam>
public static void ForEachNode<T>(Node parent, Func<T, bool> func) where T : Node public static void ForEachNode<T>(Node parent, Func<T, bool> func) where T : class
{ {
var count = parent.GetChildCount(); var count = parent.GetChildCount();
if (count <= 0) if (count <= 0)