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:
parent
5371d31d99
commit
d80c49ab02
|
@ -55,7 +55,6 @@ shape = SubResource("RectangleShape2D_7tsse")
|
|||
[node name="Marker2D" type="Marker2D" parent="."]
|
||||
position = Vector2(260, 87)
|
||||
script = ExtResource("1_y2vgj")
|
||||
ResPath = "res://prefab/entitys/DelivererOfDarkMagic.tscn"
|
||||
|
||||
[node name="NavigationRegion2D" type="NavigationRegion2D" parent="."]
|
||||
navigation_polygon = SubResource("NavigationPolygon_rh1gx")
|
||||
|
|
|
@ -54,7 +54,6 @@ shape = SubResource("RectangleShape2D_7tsse")
|
|||
[node name="Marker2D" type="Marker2D" parent="."]
|
||||
position = Vector2(260, 87)
|
||||
script = ExtResource("2_wamhd")
|
||||
ResPath = "res://prefab/entitys/DelivererOfDarkMagic.tscn"
|
||||
|
||||
[node name="NavigationRegion2D" type="NavigationRegion2D" parent="."]
|
||||
navigation_polygon = SubResource("NavigationPolygon_rh1gx")
|
||||
|
|
|
@ -37,7 +37,7 @@ position = Vector2(751.5, 289.438)
|
|||
shape = SubResource("RectangleShape2D_jxmys")
|
||||
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)
|
||||
script = ExtResource("1_q04qt")
|
||||
|
||||
|
@ -73,16 +73,6 @@ position = Vector2(386, 178)
|
|||
scale = Vector2(23.9375, 11.0625)
|
||||
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="."]
|
||||
offset_left = 37.0
|
||||
offset_top = 46.0
|
||||
|
@ -115,3 +105,15 @@ position = Vector2(715, 162)
|
|||
|
||||
[node name="WoodenBox4" parent="." instance=ExtResource("7_jybe6")]
|
||||
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"
|
||||
|
|
|
@ -91,11 +91,6 @@ offset_right = 453.0
|
|||
offset_bottom = 151.0
|
||||
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")]
|
||||
position = Vector2(711, 179)
|
||||
|
||||
|
@ -129,3 +124,10 @@ position = Vector2(473, 285)
|
|||
[node name="TripleShotSpell" type="Sprite2D" parent="."]
|
||||
position = Vector2(637, 85)
|
||||
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"
|
||||
|
|
|
@ -9,12 +9,6 @@ namespace ColdMint.scripts;
|
|||
/// </summary>
|
||||
public static class EventBus
|
||||
{
|
||||
/// <summary>
|
||||
/// <para>Event when the AI character is generated</para>
|
||||
/// <para>AI角色生成事件</para>
|
||||
/// </summary>
|
||||
public static Action<AiCharacterGenerateEvent>? AiCharacterGenerateEvent;
|
||||
|
||||
/// <summary>
|
||||
/// <para>Game Over Event</para>
|
||||
/// <para>游戏结束事件</para>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
using ColdMint.scripts.character;
|
||||
using ColdMint.scripts.map.events;
|
||||
using ColdMint.scripts.map.room;
|
||||
using ColdMint.scripts.utils;
|
||||
using Godot;
|
||||
|
||||
|
@ -9,52 +9,45 @@ namespace ColdMint.scripts.map;
|
|||
/// <para>Ai character generation point</para>
|
||||
/// <para>Ai角色生成点</para>
|
||||
/// </summary>
|
||||
public partial class AiCharacterSpawn : Marker2D
|
||||
public partial class AiCharacterSpawn : Marker2D, ISpawnMarker
|
||||
{
|
||||
private PackedScene? _packedScene;
|
||||
[Export]
|
||||
public string? ResPath;
|
||||
[Export] private string? _resPath;
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
base._Ready();
|
||||
if (!string.IsNullOrEmpty(ResPath))
|
||||
if (!string.IsNullOrEmpty(_resPath))
|
||||
{
|
||||
_packedScene = GD.Load<PackedScene>(ResPath);
|
||||
_packedScene = GD.Load<PackedScene>(_resPath);
|
||||
}
|
||||
}
|
||||
|
||||
EventBus.AiCharacterGenerateEvent += OnAiCharacterGenerateEvent;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>When an event is triggered</para>
|
||||
/// <para>当触发事件时</para>
|
||||
/// </summary>
|
||||
/// <param name="aiCharacterGenerateEvent"></param>
|
||||
public void OnAiCharacterGenerateEvent(AiCharacterGenerateEvent aiCharacterGenerateEvent)
|
||||
public Node2D? Spawn()
|
||||
{
|
||||
if (GameSceneDepend.AiCharacterContainer == null)
|
||||
if (GameSceneDepend.AiCharacterContainer == null || _packedScene == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (_packedScene == null)
|
||||
{
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
|
||||
var aiCharacter = NodeUtils.InstantiatePackedScene<AiCharacter>(_packedScene);
|
||||
if (aiCharacter == null)
|
||||
{
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
|
||||
NodeUtils.CallDeferredAddChild(GameSceneDepend.AiCharacterContainer, aiCharacter);
|
||||
aiCharacter.GlobalPosition = GlobalPosition;
|
||||
return aiCharacter;
|
||||
}
|
||||
|
||||
public override void _ExitTree()
|
||||
public bool CanQueueFree()
|
||||
{
|
||||
EventBus.AiCharacterGenerateEvent -= OnAiCharacterGenerateEvent;
|
||||
return true;
|
||||
}
|
||||
|
||||
public void DoQueueFree()
|
||||
{
|
||||
QueueFree();
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
using ColdMint.scripts.debug;
|
||||
using ColdMint.scripts.inventory;
|
||||
using ColdMint.scripts.map.events;
|
||||
using ColdMint.scripts.map.room;
|
||||
using Godot;
|
||||
|
||||
namespace ColdMint.scripts.map;
|
||||
|
@ -9,36 +9,34 @@ namespace ColdMint.scripts.map;
|
|||
/// <para>ItemSpawn</para>
|
||||
/// <para>物品出生点</para>
|
||||
/// </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();
|
||||
EventBus.MapGenerationCompleteEvent += MapGenerationCompleteEvent;
|
||||
}
|
||||
|
||||
private void MapGenerationCompleteEvent(MapGenerationCompleteEvent mapGenerationCompleteEvent)
|
||||
if (string.IsNullOrEmpty(ItemId))
|
||||
{
|
||||
//After the map is generated, create the item instance.
|
||||
//当地图生成完成后,创建物品实例。
|
||||
if (ItemId == null)
|
||||
{
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
|
||||
var item = ItemTypeManager.CreateItem(ItemId, this);
|
||||
LogCat.LogWithFormat("generated_item_is_empty",LogCat.LogLabel.ItemSpawn,true,ItemId,item == null);
|
||||
if (item is Node2D node2D)
|
||||
LogCat.LogWithFormat("generated_item_is_empty", LogCat.LogLabel.ItemSpawn, true, ItemId, item == null);
|
||||
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();
|
||||
EventBus.MapGenerationCompleteEvent -= MapGenerationCompleteEvent;
|
||||
return true;
|
||||
}
|
||||
|
||||
public void DoQueueFree()
|
||||
{
|
||||
QueueFree();
|
||||
}
|
||||
}
|
|
@ -311,11 +311,6 @@ public static class MapGenerator
|
|||
RoomDictionary = roomDictionary
|
||||
};
|
||||
EventBus.MapGenerationCompleteEvent?.Invoke(eventObj);
|
||||
var aiCharacterGenerateEvent = new AiCharacterGenerateEvent
|
||||
{
|
||||
Tag = AiCharacterGenerateEvent.TagMapGenerationComplete
|
||||
};
|
||||
EventBus.AiCharacterGenerateEvent?.Invoke(aiCharacterGenerateEvent);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
using ColdMint.scripts.character;
|
||||
using ColdMint.scripts.debug;
|
||||
using ColdMint.scripts.map.events;
|
||||
using ColdMint.scripts.map.room;
|
||||
using ColdMint.scripts.utils;
|
||||
using Godot;
|
||||
|
||||
|
@ -11,7 +12,7 @@ namespace ColdMint.scripts.map;
|
|||
/// <para>PlayerSpawn</para>
|
||||
/// <para>玩家出生点</para>
|
||||
/// </summary>
|
||||
public partial class PlayerSpawn : Marker2D
|
||||
public partial class PlayerSpawn : Marker2D,ISpawnMarker
|
||||
{
|
||||
private PackedScene? _playerPackedScene;
|
||||
|
||||
|
@ -31,32 +32,49 @@ public partial class PlayerSpawn : Marker2D
|
|||
GameSceneDepend.Player.GlobalPosition = GlobalPosition;
|
||||
return;
|
||||
}
|
||||
|
||||
SpawnPlayer();
|
||||
Spawn();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>Generate player instance</para>
|
||||
/// <para>生成玩家实例</para>
|
||||
/// </summary>
|
||||
private void SpawnPlayer()
|
||||
|
||||
private void MapGenerationCompleteEvent(MapGenerationCompleteEvent mapGenerationCompleteEvent)
|
||||
{
|
||||
//After the map is generated, create the player instance.
|
||||
//当地图生成完成后,创建玩家实例。
|
||||
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)
|
||||
{
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
|
||||
if (_playerPackedScene == null)
|
||||
{
|
||||
LogCat.LogError("player_packed_scene_not_exist");
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
|
||||
var playerNode =
|
||||
NodeUtils.InstantiatePackedScene<Player>(_playerPackedScene);
|
||||
if (playerNode == null)
|
||||
{
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
|
||||
//The player's parent node must be GameSceneDepend PlayerContainer.
|
||||
|
@ -73,26 +91,16 @@ public partial class PlayerSpawn : Marker2D
|
|||
playerNode.ItemContainer = itemContainer;
|
||||
GameSceneDepend.Player = playerNode;
|
||||
playerNode.GlobalPosition = GlobalPosition;
|
||||
return playerNode;
|
||||
}
|
||||
|
||||
private void MapGenerationCompleteEvent(MapGenerationCompleteEvent mapGenerationCompleteEvent)
|
||||
public bool CanQueueFree()
|
||||
{
|
||||
//After the map is generated, create the player instance.
|
||||
//当地图生成完成后,创建玩家实例。
|
||||
if (GameSceneDepend.Player != null)
|
||||
{
|
||||
//An existing player instance will not be created.
|
||||
//已经存在玩家实例,不再创建。
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
SpawnPlayer();
|
||||
}
|
||||
|
||||
public override void _ExitTree()
|
||||
public void DoQueueFree()
|
||||
{
|
||||
base._ExitTree();
|
||||
EventBus.MapGenerationCompleteEvent -= MapGenerationCompleteEvent;
|
||||
EventBus.GameReplayEvent -= GameReplayEvent;
|
||||
QueueFree();
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -19,7 +19,11 @@ public interface IEnterRoomEventHandler
|
|||
/// <para>When entering the room</para>
|
||||
/// <para>当进入房间时</para>
|
||||
/// </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="room"></param>
|
||||
void OnEnterRoom(Node node,Room room);
|
||||
void OnEnterRoom(int playerRoomVisitCount,Node node,Room room);
|
||||
}
|
33
scripts/map/room/ISpawnMarker.cs
Normal file
33
scripts/map/room/ISpawnMarker.cs
Normal 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();
|
||||
}
|
|
@ -29,6 +29,18 @@ public class Room
|
|||
private bool _hasPlayer;
|
||||
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? ExitRoomEventHandlerId { get; set; }
|
||||
|
@ -51,47 +63,31 @@ public class Room
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>Places a barrier in a slot where a match has been found.</para>
|
||||
/// <para>在找到匹配的槽位放置屏障。</para>
|
||||
/// <para>Place barriers in all slots</para>
|
||||
/// <para>在所有的槽位放置屏障</para>
|
||||
/// </summary>
|
||||
private void PlaceBarrierInMatchedSlot()
|
||||
public void PlaceBarriersInAllSlots()
|
||||
{
|
||||
ProcessRoomSlots(action: (roomSlot, ground, barrier, i) =>
|
||||
{
|
||||
if (!roomSlot.Matched)
|
||||
var barrier = GetTileMapLayer(Config.TileMapLayerName.Barrier);
|
||||
if (barrier == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
var cellSourceId = barrier.GetCellSourceId(i);
|
||||
if (cellSourceId == -1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ground.SetCell(i, cellSourceId, barrier.GetCellAtlasCoords(i), barrier.GetCellAlternativeTile(i));
|
||||
});
|
||||
barrier.Enabled = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>Clear the barrier that finds a matching slot</para>
|
||||
/// <para>清空找到匹配的槽位的屏障。</para>
|
||||
/// <para>Clear all matched barriers</para>
|
||||
/// <para>清空所有已匹配位置的屏障</para>
|
||||
/// </summary>
|
||||
private void ClearBarriersInMatchedSlots()
|
||||
public void ClearAllMatchedBarriers()
|
||||
{
|
||||
ProcessRoomSlots(action: (roomSlot, ground, barrier, i) =>
|
||||
{
|
||||
if (!roomSlot.Matched)
|
||||
var barrier = GetTileMapLayer(Config.TileMapLayerName.Barrier);
|
||||
if (barrier == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
var cellSourceId = barrier.GetCellSourceId(i);
|
||||
if (cellSourceId == -1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ground.SetCell(i, cellSourceId, barrier.GetCellAtlasCoords(i), barrier.GetCellAlternativeTile(i));
|
||||
});
|
||||
barrier.Enabled = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -99,32 +95,6 @@ public class Room
|
|||
/// <para>在未匹配的槽位放置屏障。</para>
|
||||
/// </summary>
|
||||
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 barrier = GetTileMapLayer(Config.TileMapLayerName.Barrier);
|
||||
|
@ -149,12 +119,22 @@ public class Room
|
|||
//将屏障层的对应坐标瓦片放到地面层。
|
||||
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>
|
||||
/// <para>ShowAllCharacterTemplate</para>
|
||||
/// <para>显示所有角色模板</para>
|
||||
|
@ -200,6 +180,15 @@ public class Room
|
|||
{
|
||||
_characterTemplateList.Add(player);
|
||||
_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.
|
||||
//玩家进入了房间,开放视野。
|
||||
if (_pointLight2D != null)
|
||||
|
@ -231,7 +220,7 @@ public class Room
|
|||
}
|
||||
|
||||
var enterRoomEventHandler = RoomEventManager.GetEnterRoomEventHandler(EnterRoomEventHandlerId);
|
||||
enterRoomEventHandler?.OnEnterRoom(node, this);
|
||||
enterRoomEventHandler?.OnEnterRoom(PlayerRoomVisitCount, node, this);
|
||||
}
|
||||
|
||||
|
||||
|
@ -260,8 +249,18 @@ public class Room
|
|||
_pointLight2D.Show();
|
||||
_pointLight2D.Texture = AssetHolder.White25;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -312,8 +311,8 @@ public class Room
|
|||
return;
|
||||
}
|
||||
|
||||
var node2D = NodeUtils.InstantiatePackedScene<Node2D>(packedScene);
|
||||
if (node2D == null)
|
||||
var rootNode = NodeUtils.InstantiatePackedScene<Node2D>(packedScene);
|
||||
if (rootNode == null)
|
||||
{
|
||||
//The room node is not of Node2D type. An exception is thrown
|
||||
//房间节点不是Node2D类型,抛出异常
|
||||
|
@ -321,15 +320,15 @@ public class Room
|
|||
return;
|
||||
}
|
||||
|
||||
_rootNode = node2D;
|
||||
var tileMapNode = node2D.GetNode<Node2D>("TileMap");
|
||||
_rootNode = rootNode;
|
||||
var tileMapNode = rootNode.GetNode<Node2D>("TileMap");
|
||||
NodeUtils.ForEachNode<TileMapLayer>(tileMapNode, node =>
|
||||
{
|
||||
_tileMapLayers ??= [];
|
||||
_tileMapLayers.Add(node);
|
||||
return false;
|
||||
});
|
||||
_area2D = node2D.GetNode<Area2D>("RoomArea");
|
||||
_area2D = rootNode.GetNode<Area2D>("RoomArea");
|
||||
_area2D.Monitoring = true;
|
||||
_area2D.SetCollisionLayerValue(Config.LayerNumber.RoomArea, true);
|
||||
//Sets the collision layer that can be detected in the current room area.
|
||||
|
@ -340,12 +339,13 @@ public class Room
|
|||
_area2D.BodyEntered += OnEnterRoom;
|
||||
_collisionShape2D = _area2D.GetChild<CollisionShape2D>(0);
|
||||
_roomSlots = GetRoomSlots(GetTileMapLayer(Config.TileMapLayerName.Ground), _area2D,
|
||||
node2D.GetNode<Node2D>("RoomSlotList"));
|
||||
_pointLight2D = node2D.GetNodeOrNull<PointLight2D>("PointLight2D");
|
||||
rootNode.GetNode<Node2D>("RoomSlotList"));
|
||||
_pointLight2D = rootNode.GetNodeOrNull<PointLight2D>("PointLight2D");
|
||||
if (_pointLight2D != null)
|
||||
{
|
||||
_pointLight2D.BlendMode = Light2D.BlendModeEnum.Mix;
|
||||
}
|
||||
_autoSpawn = rootNode.GetNodeOrNull<Node2D>("AutoSpawn");
|
||||
}
|
||||
|
||||
public Node2D? RootNode => _rootNode;
|
||||
|
|
|
@ -131,10 +131,10 @@ public static class NodeUtils
|
|||
///<para>用于处理回调的函数,返回true终止遍历节点</para>
|
||||
/// </param>
|
||||
/// <typeparam name="T">
|
||||
///<para>When the type is specified as Node, all child nodes are returned.</para>
|
||||
///<para>当指定类型为Node时,将返回所有子节点。</para>
|
||||
///<para>Specifies the generic type</para>
|
||||
///<para>指定的泛型</para>
|
||||
/// </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();
|
||||
if (count <= 0)
|
||||
|
|
Loading…
Reference in New Issue
Block a user