Can generate a preview and place it in the mini-map.

能够生成预览图并将其放置到迷你地图内了。
This commit is contained in:
Cold-Mint 2024-09-01 23:24:35 +08:00
parent c1a3bfa266
commit 1429b879e8
Signed by: Cold-Mint
GPG Key ID: C5A9BF8A98E0CE99
17 changed files with 190 additions and 70 deletions

View File

@ -1,10 +1,11 @@
[gd_scene load_steps=7 format=3 uid="uid://bnftvkj2cido7"]
[gd_scene load_steps=8 format=3 uid="uid://bnftvkj2cido7"]
[ext_resource type="Script" path="res://scripts/loader/sceneLoader/GameSceneLoader.cs" id="1_mqdgt"]
[ext_resource type="Texture2D" uid="uid://cs6e0af876ss5" path="res://sprites/ui/HeartEmpty.png" id="2_n1yht"]
[ext_resource type="Script" path="res://scripts/inventory/HotBar.cs" id="2_owrhq"]
[ext_resource type="Script" path="res://scripts/HealthBarUi.cs" id="2_xrm3v"]
[ext_resource type="Script" path="res://scripts/FpsLabel.cs" id="5_dis4v"]
[ext_resource type="PackedScene" uid="uid://c74180dtf7j7a" path="res://scenes/mapContainer.tscn" id="6_ljdj4"]
[ext_resource type="PackedScene" uid="uid://bb188382q7btp" path="res://scenes/gameOverMenu.tscn" id="6_yjmrv"]
[node name="Game" type="Node2D"]
@ -90,6 +91,9 @@ offset_right = 20.0
offset_bottom = 25.0
grow_horizontal = 2
[node name="MapContainer" parent="CanvasLayer/Control" instance=ExtResource("6_ljdj4")]
layout_mode = 1
[node name="BackpackUIContainer" type="Control" parent="CanvasLayer"]
visible = false
layout_mode = 3

43
scenes/mapContainer.tscn Normal file
View File

@ -0,0 +1,43 @@
[gd_scene load_steps=2 format=3 uid="uid://c74180dtf7j7a"]
[ext_resource type="Texture2D" uid="uid://c35bsle7thcnh" path="res://sprites/ui/MiniMapBg.png" id="1_h88bi"]
[node name="MapContainer" type="Control"]
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
mouse_filter = 2
[node name="ColorRect" type="ColorRect" parent="."]
visible = false
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
mouse_filter = 2
[node name="MiniMap" type="NinePatchRect" parent="."]
layout_mode = 1
anchors_preset = 3
anchor_left = 1.0
anchor_top = 1.0
anchor_right = 1.0
anchor_bottom = 1.0
offset_left = -174.0
offset_top = -177.0
offset_right = -24.0
offset_bottom = -27.0
grow_horizontal = 0
grow_vertical = 0
texture = ExtResource("1_h88bi")
patch_margin_left = 7
patch_margin_top = 7
patch_margin_right = 7
patch_margin_bottom = 7
[node name="RoomPreviewContainer" type="Node2D" parent="MiniMap"]

View File

@ -8,11 +8,17 @@ using Godot;
namespace ColdMint.scripts;
/// <summary>
/// <para>The node holder within the game scene</para>
/// <para>游戏场景内的节点持有者</para>
/// <para>Dependencies on the runtime of the game scene</para>
/// <para>游戏场景运行时的依赖</para>
/// </summary>
public static class GameSceneNodeHolder
public static class GameSceneDepend
{
/// <summary>
/// <para>The midpoint of the minimap</para>
/// <para>迷你地图的中点</para>
/// </summary>
public static Vector2 MiniMapMidpointCoordinate;
private static Player? _player;
/// <summary>
@ -41,6 +47,12 @@ public static class GameSceneNodeHolder
/// </summary>
public static Node2D? TemporaryTargetNode { get; set; }
/// <summary>
/// <para>MiniMapContainerNode</para>
/// <para>迷你地图容器节点</para>
/// </summary>
public static Node2D? MiniMapContainerNode { get; set; }
/// <summary>
/// <para>ProjectileContainer</para>
/// <para>抛射体容器</para>

View File

@ -315,9 +315,9 @@ public partial class CharacterTemplate : CharacterBody2D
public override void _ExitTree()
{
base._ExitTree();
if (GameSceneNodeHolder.TemporaryTargetNode == this)
if (GameSceneDepend.TemporaryTargetNode == this)
{
GameSceneNodeHolder.TemporaryTargetNode = null;
GameSceneDepend.TemporaryTargetNode = null;
}
}
@ -326,13 +326,13 @@ public partial class CharacterTemplate : CharacterBody2D
public override void _MouseEnter()
{
if (GameSceneNodeHolder.Player != null)
if (GameSceneDepend.Player != null)
{
var targetCamp = CampManager.GetCamp(CampId);
var playerCamp = CampManager.GetCamp(GameSceneNodeHolder.Player.CampId);
var playerCamp = CampManager.GetCamp(GameSceneDepend.Player.CampId);
if (CampManager.CanCauseHarm(targetCamp, playerCamp))
{
GameSceneNodeHolder.TemporaryTargetNode = this;
GameSceneDepend.TemporaryTargetNode = this;
}
}
@ -511,7 +511,7 @@ public partial class CharacterTemplate : CharacterBody2D
return;
}
if (GameSceneNodeHolder.Player == null)
if (GameSceneDepend.Player == null)
{
//We didn't know who the player was, so we showed it as a hostile color
//我们不知道玩家是谁,所以我们将其显示为敌对颜色
@ -522,7 +522,7 @@ public partial class CharacterTemplate : CharacterBody2D
//If we set up a player node, then compare the injured party ID to the player's party ID
//如果我们设置了玩家节点那么将受伤者的阵营ID与玩家的阵营ID进行比较
var targetCamp = CampManager.GetCamp(CampId);
var playerCamp = CampManager.GetCamp(GameSceneNodeHolder.Player.CampId);
var playerCamp = CampManager.GetCamp(GameSceneDepend.Player.CampId);
if (CampManager.CanCauseHarm(targetCamp, playerCamp))
{
if (targetCamp != null && playerCamp != null)
@ -618,6 +618,10 @@ public partial class CharacterTemplate : CharacterBody2D
/// <param name="force"></param>
public void AddForce(Vector2 force)
{
if (_additionalForce != Vector2.Zero)
{
throw new InvalidOperationException("AddForce called more than once");
}
_additionalForce = force;
}
@ -792,7 +796,7 @@ public partial class CharacterTemplate : CharacterBody2D
switch (item)
{
case PickAbleTemplate pickAbleTemplate:
if (GameSceneNodeHolder.WeaponContainer == null)
if (GameSceneDepend.WeaponContainer == null)
{
return;
}

View File

@ -46,7 +46,7 @@ public partial class Player : CharacterTemplate
_parabola = GetNode<Line2D>("Parabola");
_platformDetectionRayCast2D = GetNode<RayCast2D>("PlatformDetectionRayCast");
UpdateOperationTip();
var healthBarUi = GameSceneNodeHolder.HealthBarUi;
var healthBarUi = GameSceneDepend.HealthBarUi;
if (healthBarUi != null)
{
healthBarUi.MaxHp = MaxHp;
@ -89,7 +89,7 @@ public partial class Player : CharacterTemplate
private void SelectedItemSlotChangeEvent(SelectedItemSlotChangeEvent selectedItemSlotChangeEvent)
{
var item = selectedItemSlotChangeEvent.NewItemSlotNode?.GetItem();
GameSceneNodeHolder.HideBackpackUiContainerIfVisible();
GameSceneDepend.HideBackpackUiContainerIfVisible();
if (item is Node2D node2D)
{
CurrentItem = node2D;
@ -114,7 +114,7 @@ public partial class Player : CharacterTemplate
/// </summary>
private void UpdateOperationTip()
{
var operationTipLabel = GameSceneNodeHolder.OperationTipLabel;
var operationTipLabel = GameSceneDepend.OperationTipLabel;
if (operationTipLabel == null)
{
return;
@ -303,7 +303,7 @@ public partial class Player : CharacterTemplate
}
ThrowItem(ItemContainer.GetSelectIndex(), 1, GetThrowVelocity());
GameSceneNodeHolder.HideBackpackUiContainerIfVisible();
GameSceneDepend.HideBackpackUiContainerIfVisible();
CurrentItem = null;
}
}
@ -385,7 +385,7 @@ public partial class Player : CharacterTemplate
public override void Revive(int newHp)
{
base.Revive(newHp);
var healthBarUi = GameSceneNodeHolder.HealthBarUi;
var healthBarUi = GameSceneDepend.HealthBarUi;
if (healthBarUi != null)
{
//The purpose of setting Hp to the current Hp is to cause the life bar to refresh.
@ -451,7 +451,7 @@ public partial class Player : CharacterTemplate
protected override void OnHit(DamageTemplate damageTemplate)
{
base.OnHit(damageTemplate);
var healthBarUi = GameSceneNodeHolder.HealthBarUi;
var healthBarUi = GameSceneDepend.HealthBarUi;
if (healthBarUi != null)
{
healthBarUi.CurrentHp = CurrentHp;

View File

@ -15,7 +15,9 @@ public class ErrorRecord
/// </summary>
[Key]
[MaxLength(255)]
// ReSharper disable UnusedAutoPropertyAccessor.Global
public string? Message { get; set; }
// ReSharper restore UnusedAutoPropertyAccessor.Global
/// <summary>
/// <para>Count</para>

View File

@ -46,7 +46,7 @@ public partial class Packsack : PickAbleTemplate
}
}
GameSceneNodeHolder.BackpackUiContainer?.Show();
GameSceneDepend.BackpackUiContainer?.Show();
_packsackUi?.Show();
}

View File

@ -23,39 +23,46 @@ public partial class GameSceneLoader : SceneLoaderTemplate
//Loading the blood bar scene
//加载血条场景
var healthBarUi = GetNode<HealthBarUi>("CanvasLayer/Control/VBoxContainer/HealthBarUi");
GameSceneNodeHolder.HealthBarUi = healthBarUi;
GameSceneDepend.HealthBarUi = healthBarUi;
//Load HotBar
//加载HotBar
var hotBar = GetNode<HotBar>("CanvasLayer/Control/VBoxContainer/HotBar");
GameSceneNodeHolder.HotBar = hotBar;
GameSceneDepend.HotBar = hotBar;
//Backpack Ui container
//背包Ui容器
var backpackUiContainer = GetNode<Control>("CanvasLayer/BackpackUIContainer");
GameSceneNodeHolder.BackpackUiContainer = backpackUiContainer;
GameSceneDepend.BackpackUiContainer = backpackUiContainer;
//Load operation prompt
//加载操作提示
var operationTip = GetNode<RichTextLabel>("CanvasLayer/Control/VBoxContainer/OperationTip");
GameSceneNodeHolder.OperationTipLabel = operationTip;
GameSceneDepend.OperationTipLabel = operationTip;
//Loaded weapon container
//加载武器容器
var weaponContainer = GetNode<Node2D>("WeaponContainer");
GameSceneNodeHolder.WeaponContainer = weaponContainer;
GameSceneDepend.WeaponContainer = weaponContainer;
//Load projectile container
//加载抛射体容器
var projectileContainer = GetNode<Node2D>("ProjectileContainer");
GameSceneNodeHolder.ProjectileContainer = projectileContainer;
GameSceneDepend.ProjectileContainer = projectileContainer;
//Load Packsack container
//加载背包容器
var packsackContainer = GetNode<Node2D>("PacksackContainer");
GameSceneNodeHolder.PacksackContainer = packsackContainer;
GameSceneDepend.PacksackContainer = packsackContainer;
//Load AICharacter container
//加载AICharacter容器
var aiCharacterContainer = GetNode<Node2D>("AICharacterContainer");
GameSceneNodeHolder.AiCharacterContainer = aiCharacterContainer;
GameSceneDepend.AiCharacterContainer = aiCharacterContainer;
//Load player container
//加载玩家容器
var playerContainer = GetNode<Node2D>("PlayerContainer");
GameSceneNodeHolder.PlayerContainer = playerContainer;
GameSceneDepend.PlayerContainer = playerContainer;
//Load the room container node
//加载房间容器节点
var miniMapContainerNode = GetNode<Node2D>("CanvasLayer/Control/MapContainer/MiniMap/RoomPreviewContainer");
GameSceneDepend.MiniMapContainerNode = miniMapContainerNode;
//计算迷你地图的中点
var mapContainer = GetNode<NinePatchRect>("CanvasLayer/Control/MapContainer/MiniMap");
GameSceneDepend.MiniMapMidpointCoordinate = mapContainer.Size / 2;
return Task.CompletedTask;
}
@ -96,6 +103,7 @@ public partial class GameSceneLoader : SceneLoaderTemplate
var seedInfo = TranslationServerUtils.TranslateWithFormat("ui_seed_info", MapGenerator.Seed);
_seedLabel.Text = seedInfo ?? $"Seed: {MapGenerator.Seed}";
}
await MapGenerator.GenerateMap();
}
}

View File

@ -107,7 +107,7 @@ public partial class PacksackUi : UiLoaderTemplate
{
_exitButton.Pressed += () =>
{
GameSceneNodeHolder.BackpackUiContainer?.Hide();
GameSceneDepend.BackpackUiContainer?.Hide();
Hide();
};
}

View File

@ -33,7 +33,7 @@ public partial class AiCharacterSpawn : Marker2D
/// <param name="aiCharacterGenerateEvent"></param>
public void OnAiCharacterGenerateEvent(AiCharacterGenerateEvent aiCharacterGenerateEvent)
{
if (GameSceneNodeHolder.AiCharacterContainer == null)
if (GameSceneDepend.AiCharacterContainer == null)
{
return;
}
@ -49,7 +49,7 @@ public partial class AiCharacterSpawn : Marker2D
return;
}
NodeUtils.CallDeferredAddChild(GameSceneNodeHolder.AiCharacterContainer, aiCharacter);
NodeUtils.CallDeferredAddChild(GameSceneDepend.AiCharacterContainer, aiCharacter);
aiCharacter.GlobalPosition = GlobalPosition;
}

View File

@ -149,9 +149,14 @@ public static class MapGenerator
return;
}
if (GameSceneNodeHolder.AiCharacterContainer != null)
if (GameSceneDepend.MiniMapContainerNode != null)
{
NodeUtils.DeleteAllChild(GameSceneNodeHolder.AiCharacterContainer);
NodeUtils.DeleteAllChild(GameSceneDepend.MiniMapContainerNode);
}
if (GameSceneDepend.AiCharacterContainer != null)
{
NodeUtils.DeleteAllChild(GameSceneDepend.AiCharacterContainer);
}
NodeUtils.DeleteAllChild(_mapRoot);
@ -336,21 +341,29 @@ public static class MapGenerator
return false;
}
//Create a room preview image.
//创建房间预览图。
var image = RoomPreview.CreateImage(roomPlacementData.NewRoom.GetTileMapLayer(Config.TileMapLayerName.Ground));
if (GameSceneDepend.MiniMapContainerNode == null || roomPlacementData.Position == null ||
image == null)
{
return false;
}
var sprite = new Sprite2D();
sprite.Scale = new Vector2(5, 5);
sprite.Texture = image;
//TODOCalculate the coordinates of the room preview view.
//TODO计算房间预览图的坐标。
sprite.Position = GameSceneDepend.MiniMapMidpointCoordinate +
roomPlacementData.Position.Value / Config.CellSize;
NodeUtils.CallDeferredAddChild(GameSceneDepend.MiniMapContainerNode, sprite);
//Rooms are added to the dictionary only after the preview is created.
//创建预览图后才将房间添加到字典。
dictionary.Add(roomNodeDataId, roomPlacementData.NewRoom);
LogCat.LogWithFormat("room_placement_information", LogCat.LogLabel.Default, LogCat.UploadFormat, roomNodeDataId,
roomPlacementData.Position.ToString());
//Create a room preview image.
//创建房间预览图。
var rootNode = roomPlacementData.NewRoom.RootNode;
var image = RoomPreview.CreateImage(roomPlacementData.NewRoom.GetTileMapLayer(Config.TileMapLayerName.Ground));
if (rootNode != null && image != null)
{
var sprite = new Sprite2D();
sprite.Scale = new Vector2(10, 10);
sprite.Texture = image;
NodeUtils.CallDeferredAddChild(rootNode, sprite);
}
return true;
}
}

View File

@ -25,10 +25,10 @@ public partial class PlayerSpawn : Marker2D
private void GameReplayEvent(GameReplayEvent gameReplayEvent)
{
if (GameSceneNodeHolder.Player != null)
if (GameSceneDepend.Player != null)
{
GameSceneNodeHolder.Player.Revive(GameSceneNodeHolder.Player.MaxHp);
GameSceneNodeHolder.Player.GlobalPosition = GlobalPosition;
GameSceneDepend.Player.Revive(GameSceneDepend.Player.MaxHp);
GameSceneDepend.Player.GlobalPosition = GlobalPosition;
return;
}
@ -41,7 +41,7 @@ public partial class PlayerSpawn : Marker2D
/// </summary>
private void SpawnPlayer()
{
if (GameSceneNodeHolder.PlayerContainer == null)
if (GameSceneDepend.PlayerContainer == null)
{
return;
}
@ -59,10 +59,10 @@ public partial class PlayerSpawn : Marker2D
return;
}
//The player's parent node must be GameSceneNodeHolder PlayerContainer.
//玩家的父节点必须是GameSceneNodeHolder.PlayerContainer。
NodeUtils.CallDeferredAddChild(GameSceneNodeHolder.PlayerContainer, playerNode);
var itemContainer = GameSceneNodeHolder.HotBar?.GetItemContainer();
//The player's parent node must be GameSceneDepend PlayerContainer.
//玩家的父节点必须是GameSceneDepend.PlayerContainer。
NodeUtils.CallDeferredAddChild(GameSceneDepend.PlayerContainer, playerNode);
var itemContainer = GameSceneDepend.HotBar?.GetItemContainer();
if (itemContainer == null)
{
//Throws an exception when the item container is empty.
@ -71,7 +71,7 @@ public partial class PlayerSpawn : Marker2D
}
playerNode.ItemContainer = itemContainer;
GameSceneNodeHolder.Player = playerNode;
GameSceneDepend.Player = playerNode;
playerNode.GlobalPosition = GlobalPosition;
}
@ -79,7 +79,7 @@ public partial class PlayerSpawn : Marker2D
{
//After the map is generated, create the player instance.
//当地图生成完成后,创建玩家实例。
if (GameSceneNodeHolder.Player != null)
if (GameSceneDepend.Player != null)
{
//An existing player instance will not be created.
//已经存在玩家实例,不再创建。

View File

@ -60,7 +60,7 @@ public static class RoomPreview
//填充像素点
foreach (var vector2I in cellsArray)
{
image.SetPixel(vector2I.X + offsetVector2.X, vector2I.Y + offsetVector2.Y, new Color(100, 221, 23));
image.SetPixel(vector2I.X + offsetVector2.X, vector2I.Y + offsetVector2.Y, Colors.Blue);
}
//Create texture.

View File

@ -225,29 +225,29 @@ public static class NodeUtils
/// <returns></returns>
public static Node FindContainerNode(Node childNode, Node defaultParentNode)
{
if (GameSceneNodeHolder.AiCharacterContainer!= null && childNode is AiCharacter)
if (GameSceneDepend.AiCharacterContainer!= null && childNode is AiCharacter)
{
return GameSceneNodeHolder.AiCharacterContainer;
return GameSceneDepend.AiCharacterContainer;
}
if (GameSceneNodeHolder.ProjectileContainer != null && childNode is Projectile)
if (GameSceneDepend.ProjectileContainer != null && childNode is Projectile)
{
return GameSceneNodeHolder.ProjectileContainer;
return GameSceneDepend.ProjectileContainer;
}
if (GameSceneNodeHolder.WeaponContainer != null && childNode is WeaponTemplate)
if (GameSceneDepend.WeaponContainer != null && childNode is WeaponTemplate)
{
return GameSceneNodeHolder.WeaponContainer;
return GameSceneDepend.WeaponContainer;
}
if (GameSceneNodeHolder.PacksackContainer != null && childNode is Packsack)
if (GameSceneDepend.PacksackContainer != null && childNode is Packsack)
{
return GameSceneNodeHolder.PacksackContainer;
return GameSceneDepend.PacksackContainer;
}
if (GameSceneNodeHolder.BackpackUiContainer != null && childNode is PacksackUi)
if (GameSceneDepend.BackpackUiContainer != null && childNode is PacksackUi)
{
return GameSceneNodeHolder.BackpackUiContainer;
return GameSceneDepend.BackpackUiContainer;
}
return defaultParentNode;

View File

@ -136,7 +136,7 @@ public partial class ProjectileWeapon : WeaponTemplate
return;
}
if (GameSceneNodeHolder.ProjectileContainer == null)
if (GameSceneDepend.ProjectileContainer == null)
{
LogCat.LogError("projectile_container_is_null");
return;
@ -167,9 +167,9 @@ public partial class ProjectileWeapon : WeaponTemplate
projectile.AddProjectileDecorator(nodeSpawnOnKillCharacterDecorator);
}
NodeUtils.CallDeferredAddChild(GameSceneNodeHolder.ProjectileContainer, projectile);
NodeUtils.CallDeferredAddChild(GameSceneDepend.ProjectileContainer, projectile);
projectile.Owner = owner;
projectile.TargetNode = GameSceneNodeHolder.TemporaryTargetNode;
projectile.TargetNode = GameSceneDepend.TemporaryTargetNode;
projectile.Velocity =
(_marker2D.GlobalPosition.DirectionTo(enemyGlobalPosition) * projectile.Speed)
.Rotated(GetRandomAngle());

BIN
sprites/ui/MiniMapBg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 277 B

View File

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://c35bsle7thcnh"
path="res://.godot/imported/MiniMapBg.png-d798deffd210ae6fbca7a397a2bc688e.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://sprites/ui/MiniMapBg.png"
dest_files=["res://.godot/imported/MiniMapBg.png-d798deffd210ae6fbca7a397a2bc688e.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1