After the player leaves the room, the previous room vision is deprived and enemies are frozen.

玩家离开房间后上个房间视野将被剥夺,敌人被冻结。
This commit is contained in:
Cold-Mint 2024-08-25 18:49:48 +08:00
parent 38c0bdff2a
commit 5b0803f85f
Signed by: Cold-Mint
GPG Key ID: C5A9BF8A98E0CE99
11 changed files with 219 additions and 42 deletions

View File

@ -114,3 +114,7 @@ log_item_pickup_disables_collision_damage,物品捡起禁用碰撞伤害。,Item
log_item_thrown_restore_collision_damage,物品扔出恢复碰撞伤害。,Item Throw restores collision damage.,アイテム投げは衝突ダメージを回復する。
log_after_no_longer_in_contact_with_any_tiles,不再与任何瓦片接触后,可以造成伤害。,"After no longer coming into contact with any tiles, it can cause damage",タイルと接触しなくなった後、損傷を引き起こす可能性があります。
log_contact_with_tiles_disables_damage,与瓦片接触禁用伤害。,"Disabling damage on contact with tiles",タイルとの接触によるダメージの無効化
log_hide_all_node,隐藏{0}个节点。,Hide {0} nodes.,{0}ノードを非表示にします。
log_show_all_node,显示{0}个节点。,Show {0} nodes.,{0}ノードが表示されます。
log_enter_the_screen,进入屏幕。,Enter screen,画面に移動。
log_exit_the_screen,退出屏幕。,Exit screen,画面を終了します。
1 id zh en ja
114 log_item_thrown_restore_collision_damage 物品扔出恢复碰撞伤害。 Item Throw restores collision damage. アイテム投げは衝突ダメージを回復する。
115 log_after_no_longer_in_contact_with_any_tiles 不再与任何瓦片接触后,可以造成伤害。 After no longer coming into contact with any tiles, it can cause damage タイルと接触しなくなった後、損傷を引き起こす可能性があります。
116 log_contact_with_tiles_disables_damage 与瓦片接触禁用伤害。 Disabling damage on contact with tiles タイルとの接触によるダメージの無効化
117 log_hide_all_node 隐藏{0}个节点。 Hide {0} nodes. {0}ノードを非表示にします。
118 log_show_all_node 显示{0}个节点。 Show {0} nodes. {0}ノードが表示されます。
119 log_enter_the_screen 进入屏幕。 Enter screen 画面に移動。
120 log_exit_the_screen 退出屏幕。 Exit screen 画面を終了します。

View File

@ -88,10 +88,6 @@ shape = SubResource("CircleShape2D_c61vr")
position = Vector2(0, -79)
script = ExtResource("5_y2fh5")
[node name="VisibleOnScreenEnabler2D" type="VisibleOnScreenEnabler2D" parent="."]
position = Vector2(0, 5.5)
scale = Vector2(2.04, 3.05)
[node name="ScoutArea2D" type="Area2D" parent="."]
collision_layer = 0
collision_mask = 76

View File

@ -23,6 +23,7 @@ animations = [{
}]
[node name="Player" type="CharacterBody2D"]
light_mask = 2
collision_layer = 4
collision_mask = 162
platform_floor_layers = 4294967042

View File

@ -44,7 +44,7 @@ position = Vector2(0, 4)
shape = SubResource("CapsuleShape2D_bb8wt")
[node name="Area2DPickingArea" type="Area2D" parent="."]
collision_layer = 0
collision_layer = 64
collision_mask = 8
[node name="CollisionShape2D" type="CollisionShape2D" parent="Area2DPickingArea"]
@ -89,10 +89,6 @@ shape = SubResource("CircleShape2D_c61vr")
position = Vector2(0, -79)
script = ExtResource("5_y2fh5")
[node name="VisibleOnScreenEnabler2D" type="VisibleOnScreenEnabler2D" parent="."]
position = Vector2(0, 5.5)
scale = Vector2(2.04, 3.05)
[node name="ScoutArea2D" type="Area2D" parent="."]
collision_layer = 0
collision_mask = 76

View File

@ -154,7 +154,6 @@ locale/translations=PackedStringArray("res://locals/DeathInfo.en.translation", "
[layer_names]
2d_render/layer_1="Fog"
2d_physics/layer_1="RoomArea"
2d_physics/layer_2="Floor"
2d_physics/layer_3="Player"

View File

@ -62,9 +62,6 @@ public sealed partial class AiCharacter : CharacterTemplate
/// </remarks>
private RayCast2D? _attackObstacleDetection;
private VisibleOnScreenEnabler2D? _screenEnabler2D;
/// <summary>
/// <para>Navigation agent</para>
/// <para>导航代理</para>
@ -118,22 +115,9 @@ public sealed partial class AiCharacter : CharacterTemplate
{
base._Ready();
_enemyInTheAttackRange = new List<CharacterTemplate>();
_enemyInTheScoutRange = new List<CharacterTemplate>();
_weaponInTheScoutRange = new List<WeaponTemplate>();
_screenEnabler2D = GetNode<VisibleOnScreenEnabler2D>("VisibleOnScreenEnabler2D");
_screenEnabler2D.ScreenEntered += () =>
{
//When the character enters the screen.
//当角色进入屏幕。
ProcessMode = ProcessModeEnum.Disabled;
};
_screenEnabler2D.ScreenExited += () =>
{
//When the character leaves the screen.
//当角色离开屏幕。
ProcessMode = ProcessModeEnum.Inherit;
};
_enemyInTheAttackRange = [];
_enemyInTheScoutRange = [];
_weaponInTheScoutRange = [];
_bubbleMarker = GetNode<BubbleMarker>("BubbleMarker");
if (_bubbleMarker != null)
{

View File

@ -392,6 +392,8 @@ public partial class Player : CharacterTemplate
//将Hp设置为当前Hp的目的是使生命条刷新。
healthBarUi.CurrentHp = CurrentHp;
}
ProcessMode = ProcessModeEnum.Inherit;
Show();
}
/// <summary>

View File

@ -82,6 +82,12 @@ public static class LogCat
/// <para>物品碰撞伤害</para>
/// </summary>
public const string ContactInjury = "ContactInjury";
/// <summary>
/// <para>Room</para>
/// <para>房间</para>
/// </summary>
public const string Room = "Room";
}

View File

@ -27,9 +27,8 @@ public partial class PlayerSpawn : Marker2D
{
if (GameSceneNodeHolder.Player != null)
{
GameSceneNodeHolder.Player.ProcessMode = ProcessModeEnum.Inherit;
GameSceneNodeHolder.Player.GlobalPosition = GlobalPosition;
GameSceneNodeHolder.Player.Revive(GameSceneNodeHolder.Player.MaxHp);
GameSceneNodeHolder.Player.GlobalPosition = GlobalPosition;
return;
}

View File

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using ColdMint.scripts.character;
using ColdMint.scripts.debug;
using ColdMint.scripts.map.dateBean;
using ColdMint.scripts.utils;
@ -25,6 +26,8 @@ public class Room
private Area2D? _area2D;
private PointLight2D? _pointLight2D;
private CollisionShape2D? _collisionShape2D;
private bool _hasPlayer;
private readonly List<CharacterTemplate> _characterTemplateList = [];
public string? EnterRoomEventHandlerId { get; set; }
@ -47,6 +50,34 @@ public class Room
return _tileMapLayers?.FirstOrDefault(tileMapLayer => tileMapLayer.Name == layerName);
}
/// <summary>
/// <para>ShowAllCharacterTemplate</para>
/// <para>显示所有角色模板</para>
/// </summary>
private void ShowAllCharacterTemplate()
{
LogCat.LogWithFormat("show_all_node", LogCat.LogLabel.Room, LogCat.UploadFormat,
_characterTemplateList.Count);
foreach (var characterTemplate in _characterTemplateList)
{
characterTemplate.Show();
}
}
/// <summary>
/// <para>HideAllCharacterTemplate</para>
/// <para>隐藏所有角色模板</para>
/// </summary>
private void HideAllCharacterTemplate()
{
LogCat.LogWithFormat("hide_all_node", LogCat.LogLabel.Room, LogCat.UploadFormat,
_characterTemplateList.Count);
foreach (var characterTemplate in _characterTemplateList)
{
characterTemplate.Hide();
}
}
/// <summary>
/// <para>When a node enters the room</para>
/// <para>当有节点进入房间时</para>
@ -60,12 +91,31 @@ public class Room
_rootNode.Name);
}
if (_pointLight2D != null && GameSceneNodeHolder.Player != null && node == GameSceneNodeHolder.Player)
if (node is Player player)
{
_characterTemplateList.Add(player);
_hasPlayer = true;
//The player enters the room, opening up their view.
//玩家进入了房间,开放视野。
_pointLight2D.Show();
_pointLight2D.Texture = AssetHolder.White100;
if (_pointLight2D != null)
{
_pointLight2D.Show();
_pointLight2D.Texture = AssetHolder.White100;
}
ShowAllCharacterTemplate();
}else if (node is CharacterTemplate characterTemplate)
{
if (_hasPlayer)
{
characterTemplate.Show();
}
else
{
characterTemplate.Hide();
}
_characterTemplateList.Add(characterTemplate);
}
if (string.IsNullOrEmpty(EnterRoomEventHandlerId))
@ -91,12 +141,24 @@ public class Room
_rootNode.Name);
}
if (_pointLight2D != null && GameSceneNodeHolder.Player != null && node == GameSceneNodeHolder.Player)
if (node is Player player)
{
//The player enters the room, opening up their view.
//玩家进入了房间,开放视野。
_pointLight2D.Show();
_pointLight2D.Texture = AssetHolder.White25;
//The player leaves the room, hiding the view.
//玩家离开了房间,隐藏视野。
_characterTemplateList.Remove(player);
_hasPlayer = false;
if (_pointLight2D != null)
{
_pointLight2D.Show();
_pointLight2D.Texture = AssetHolder.White25;
}
HideAllCharacterTemplate();
}
else if (node is CharacterTemplate characterTemplate && characterTemplate.Visible)
{
_characterTemplateList.Remove(characterTemplate);
}
if (string.IsNullOrEmpty(ExitRoomEventHandlerId))
@ -166,12 +228,17 @@ public class Room
//Sets the collision layer that can be detected in the current room area.
//设置当前房间区域可检测到的碰撞层。
_area2D.SetCollisionMaskValue(Config.LayerNumber.Player, true);
_area2D.SetCollisionMaskValue(Config.LayerNumber.Mob, true);
_area2D.BodyExited += OnExitRoom;
_area2D.BodyEntered += OnEnterRoom;
_collisionShape2D = _area2D.GetChild<CollisionShape2D>(0);
_roomSlots = GetRoomSlots(GetTileMapLayer(Config.TileMapLayerName.Ground), _area2D,
node2D.GetNode<Node2D>("RoomSlotList"));
_pointLight2D = node2D.GetNodeOrNull<PointLight2D>("PointLight2D");
if (_pointLight2D != null)
{
_pointLight2D.BlendMode = Light2D.BlendModeEnum.Mix;
}
}
public Node2D? RootNode => _rootNode;

View File

@ -0,0 +1,123 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace ColdMint.scripts.utils;
/// <summary>
/// <para>Light layer utils</para>
/// <para>光照层工具</para>
/// </summary>
public static class LightMaskUtils
{
private static readonly int[] PowInts =
[1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 262144, 524288];
/// <summary>
/// <para>Pass in a number and return the largest subscript that matches it.</para>
/// <para>传入一个数字,返回与其匹配的最大下标</para>
/// </summary>
/// <param name="number"></param>
/// <param name="startIndex"></param>
/// <returns></returns>
private static int GetMaxPow(int number, int startIndex)
{
for (var i = startIndex - 1; i >= 0; i--)
{
var pow = PowInts[i];
if (number >= pow)
{
return i;
}
}
return -1;
}
/// <summary>
/// <para>ParseMaskValue</para>
/// <para>解析Mask的值</para>
/// </summary>
/// <param name="maskValue">
///<para>maskValue</para>
///<para>值</para>
/// </param>
/// <param name="afterParsingTheValue">
///<para>This callback returns true when the value is parsed, stopping the parsing immediately.</para>
///<para>当解析到值时此回调返回true立即停止解析。</para>
/// </param>
/// <returns>
///<para>The position of the element corresponding to its value, For example, passing in 10, returning [1,3]</para>
///<para>与其值对应的元素位置例如传入10,返回[1,3]</para>
/// </returns>
public static int[] ParseMaskValue(int maskValue, Func<int, bool>? afterParsingTheValue = null)
{
var result = new List<int>();
var startIndex = PowInts.Length;
var indexInPowIntArray = GetMaxPow(maskValue, startIndex);
while (indexInPowIntArray > -1)
{
result.Insert(0, indexInPowIntArray);
if (afterParsingTheValue != null)
{
if (afterParsingTheValue.Invoke(indexInPowIntArray))
{
//If it needs to be stopped, then the result is returned directly.
//如果需要停止,那么直接返回结果。
return result.ToArray();
}
}
maskValue -= PowInts[indexInPowIntArray];
startIndex = indexInPowIntArray;
indexInPowIntArray = GetMaxPow(maskValue, startIndex);
}
return result.ToArray();
}
/// <summary>
/// <para>Is there a location within the mask value?</para>
/// <para>mask值内是否包含某个位置</para>
/// </summary>
/// <param name="maskValue"></param>
/// <param name="index"></param>
/// <returns></returns>
public static bool ContainsMaskValue(int maskValue, int index)
{
var result = false;
ParseMaskValue(maskValue, i =>
{
result = i == index;
return result;
});
return result;
}
/// <summary>
/// <para>Add a location to MaskValue</para>
/// <para>为MaskValue添加某个位置</para>
/// </summary>
/// <param name="maskValue"></param>
/// <param name="index"></param>
/// <returns></returns>
public static int AddIndexToMaskValue(int maskValue, int index)
{
if (ContainsMaskValue(maskValue,index))
{
return maskValue;
}
return maskValue + PowInts[index];
}
/// <summary>
/// <para>Converting an array to its corresponding value</para>
/// <para>将数组转化为与其对应的值</para>
/// </summary>
/// <param name="array"></param>
/// <returns></returns>
public static int ArrayToMaskValue(int[] array)
{
return array.Sum(index => PowInts[index]);
}
}