After the player leaves the room, the previous room vision is deprived and enemies are frozen.
玩家离开房间后上个房间视野将被剥夺,敌人被冻结。
This commit is contained in:
parent
38c0bdff2a
commit
5b0803f85f
|
@ -113,4 +113,8 @@ log_dll_type_length,位于{0}的dll文件内,共包含{1}个类型。,"The DLL
|
|||
log_item_pickup_disables_collision_damage,物品捡起禁用碰撞伤害。,Item pickup disables collision damage.,アイテムのピックアップが衝突によるダメージを無効にする
|
||||
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_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,画面を終了します。
|
|
|
@ -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
|
||||
|
|
|
@ -23,6 +23,7 @@ animations = [{
|
|||
}]
|
||||
|
||||
[node name="Player" type="CharacterBody2D"]
|
||||
light_mask = 2
|
||||
collision_layer = 4
|
||||
collision_mask = 162
|
||||
platform_floor_layers = 4294967042
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -392,6 +392,8 @@ public partial class Player : CharacterTemplate
|
|||
//将Hp设置为当前Hp的目的是,使生命条刷新。
|
||||
healthBarUi.CurrentHp = CurrentHp;
|
||||
}
|
||||
ProcessMode = ProcessModeEnum.Inherit;
|
||||
Show();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -70,18 +70,24 @@ public static class LogCat
|
|||
/// <para>模组加载器</para>
|
||||
/// </summary>
|
||||
public const string ModLoader = "ModLoader";
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// <para>PickAble Template</para>
|
||||
/// <para>可拾取物模板</para>
|
||||
/// </summary>
|
||||
public const string PickAbleTemplate = "PickAbleTemplate";
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// <para>ContactInjury</para>
|
||||
/// <para>物品碰撞伤害</para>
|
||||
/// </summary>
|
||||
public const string ContactInjury = "ContactInjury";
|
||||
|
||||
/// <summary>
|
||||
/// <para>Room</para>
|
||||
/// <para>房间</para>
|
||||
/// </summary>
|
||||
public const string Room = "Room";
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
123
scripts/utils/LightMaskUtils.cs
Normal file
123
scripts/utils/LightMaskUtils.cs
Normal 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]);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user