Support split-wave Spawn monsters now.
支持分波次刷出怪物了。
This commit is contained in:
parent
d80c49ab02
commit
53889ef2fd
|
@ -31,7 +31,7 @@ room_node_data_list:
|
|||
title: 房间3
|
||||
description: ''
|
||||
room_template_set:
|
||||
- res://prefab/roomTemplates/dungeon/
|
||||
- res://prefab/roomTemplates/dungeon/utilityRoom.tscn
|
||||
tags:
|
||||
room_injection_processor_data: ''
|
||||
enter_room_event_handler_id:
|
||||
|
|
|
@ -1,36 +0,0 @@
|
|||
[gd_scene load_steps=5 format=3 uid="uid://bdxgx5vcof8em"]
|
||||
|
||||
[ext_resource type="Script" path="res://scripts/projectile/Projectile.cs" id="1_ib3qh"]
|
||||
[ext_resource type="Texture2D" uid="uid://b1twcink38sh0" path="res://sprites/Player.png" id="2_dxg46"]
|
||||
|
||||
[sub_resource type="CircleShape2D" id="CircleShape2D_dgro2"]
|
||||
|
||||
[sub_resource type="CircleShape2D" id="CircleShape2D_8117d"]
|
||||
radius = 11.0
|
||||
|
||||
[node name="curseOfTheUndead" type="CharacterBody2D"]
|
||||
collision_layer = 16
|
||||
collision_mask = 102
|
||||
slide_on_ceiling = false
|
||||
platform_floor_layers = 4294967042
|
||||
platform_wall_layers = 32
|
||||
script = ExtResource("1_ib3qh")
|
||||
Speed = 300.0
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
|
||||
shape = SubResource("CircleShape2D_dgro2")
|
||||
|
||||
[node name="CollisionDetectionArea" type="Area2D" parent="."]
|
||||
collision_layer = 16
|
||||
collision_mask = 78
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="CollisionDetectionArea"]
|
||||
shape = SubResource("CircleShape2D_8117d")
|
||||
|
||||
[node name="AudioStreamPlayer2D" type="AudioStreamPlayer2D" parent="."]
|
||||
bus = &"SoundEffect"
|
||||
area_mask = 16
|
||||
|
||||
[node name="Player" type="Sprite2D" parent="."]
|
||||
scale = Vector2(0.3, 0.3)
|
||||
texture = ExtResource("2_dxg46")
|
|
@ -11,8 +11,8 @@ collision_mask = 0
|
|||
script = ExtResource("1_ib3qh")
|
||||
_life = 5000
|
||||
_durability = 1.0
|
||||
_maxDamage = 10
|
||||
_minDamage = 1
|
||||
_maxDamage = 7
|
||||
_minDamage = 3
|
||||
_damageType = 2
|
||||
Speed = 500.0
|
||||
_targetDiesDestroyProjectile = true
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
[gd_scene load_steps=8 format=4 uid="uid://c57cc1tyreybb"]
|
||||
[gd_scene load_steps=9 format=4 uid="uid://c57cc1tyreybb"]
|
||||
|
||||
[ext_resource type="TileSet" uid="uid://c4wpp12rr44hi" path="res://tileSets/dungeon.tres" id="1_rn2om"]
|
||||
[ext_resource type="Texture2D" uid="uid://drw45jlmfo0su" path="res://sprites/light/White_100.png" id="2_1ctsj"]
|
||||
[ext_resource type="Script" path="res://scripts/map/AiCharacterSpawn.cs" id="3_u5h84"]
|
||||
|
||||
[sub_resource type="RectangleShape2D" id="RectangleShape2D_kiih8"]
|
||||
size = Vector2(728, 509)
|
||||
|
@ -72,7 +73,6 @@ tile_map_data = PackedByteArray("AAAAAAAAAQAAAAMAAAAAAAEAAQACAAEAAAAAAAIAAQACAAE
|
|||
tile_set = ExtResource("1_rn2om")
|
||||
|
||||
[node name="Barrier" type="TileMapLayer" parent="TileMap"]
|
||||
visible = false
|
||||
use_parent_material = true
|
||||
tile_map_data = PackedByteArray("AAAWAA0AAQAAAAEAAAAWAA4AAQAAAAEAAAAWAAEAAQAAAAEAAAAWAAIAAQAAAAEAAAAAAA0AAQACAAEAAAAAAA4AAQACAAEAAAA=")
|
||||
tile_set = ExtResource("1_rn2om")
|
||||
|
@ -82,3 +82,15 @@ visible = false
|
|||
position = Vector2(367.5, 258)
|
||||
scale = Vector2(23.0938, 16.25)
|
||||
texture = ExtResource("2_1ctsj")
|
||||
|
||||
[node name="AutoSpawn" type="Node2D" parent="."]
|
||||
|
||||
[node name="Marker2D" type="Marker2D" parent="AutoSpawn"]
|
||||
position = Vector2(121, 178)
|
||||
script = ExtResource("3_u5h84")
|
||||
_resPathArray = PackedStringArray("res://prefab/entitys/BlackenedAboriginalWarrior.tscn", "res://prefab/entitys/BlackenedAboriginalWarrior.tscn", "", "res://prefab/entitys/BlackenedAboriginalWarrior.tscn")
|
||||
|
||||
[node name="Marker2D2" type="Marker2D" parent="AutoSpawn"]
|
||||
position = Vector2(545, 438)
|
||||
script = ExtResource("3_u5h84")
|
||||
_resPathArray = PackedStringArray("res://prefab/entitys/BlackenedAboriginalWarrior.tscn", "", "res://prefab/entitys/BlackenedAboriginalWarrior.tscn", "")
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
[ext_resource type="PackedScene" uid="uid://dld3qttpsdjpe" path="res://prefab/furnitures/WoodenBox.tscn" id="7_jybe6"]
|
||||
|
||||
[sub_resource type="RectangleShape2D" id="RectangleShape2D_kiih8"]
|
||||
size = Vector2(709, 296)
|
||||
size = Vector2(758, 342)
|
||||
|
||||
[sub_resource type="RectangleShape2D" id="RectangleShape2D_jxmys"]
|
||||
size = Vector2(23, 54.875)
|
||||
|
@ -25,7 +25,7 @@ source_geometry_group_name = &"navigation_polygon_source_group"
|
|||
[node name="RoomArea" type="Area2D" parent="."]
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="RoomArea"]
|
||||
position = Vector2(383.5, 176)
|
||||
position = Vector2(383, 175)
|
||||
shape = SubResource("RectangleShape2D_kiih8")
|
||||
|
||||
[node name="RoomSlotList" type="Node2D" parent="."]
|
||||
|
@ -111,9 +111,9 @@ position = Vector2(714, 122)
|
|||
[node name="necromancy" type="Marker2D" parent="AutoSpawn"]
|
||||
position = Vector2(134, 248)
|
||||
script = ExtResource("4_6ihp7")
|
||||
ItemId = "necromancy"
|
||||
_itemIdList = PackedStringArray("necromancy")
|
||||
|
||||
[node name="staff_necromancy" type="Marker2D" parent="AutoSpawn"]
|
||||
position = Vector2(100, 250)
|
||||
script = ExtResource("4_6ihp7")
|
||||
ItemId = "staff_necromancy"
|
||||
_itemIdList = PackedStringArray("staff_necromancy")
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
[ext_resource type="Texture2D" uid="uid://kgodvs3ilxbs" path="res://sprites/tutorials/tripleShotSpell.png" id="6_2qcf3"]
|
||||
|
||||
[sub_resource type="RectangleShape2D" id="RectangleShape2D_kiih8"]
|
||||
size = Vector2(709, 296)
|
||||
size = Vector2(755, 340)
|
||||
|
||||
[sub_resource type="RectangleShape2D" id="RectangleShape2D_jxmys"]
|
||||
size = Vector2(23, 54.875)
|
||||
|
@ -130,4 +130,4 @@ texture = ExtResource("6_2qcf3")
|
|||
[node name="x3" type="Marker2D" parent="AutoSpawn"]
|
||||
position = Vector2(434, 105)
|
||||
script = ExtResource("4_fh50l")
|
||||
ItemId = "x3"
|
||||
_itemIdList = PackedStringArray("x3")
|
||||
|
|
|
@ -11,26 +11,33 @@ namespace ColdMint.scripts.map;
|
|||
/// </summary>
|
||||
public partial class AiCharacterSpawn : Marker2D, ISpawnMarker
|
||||
{
|
||||
private PackedScene? _packedScene;
|
||||
[Export] private string? _resPath;
|
||||
[Export] private string[]? _resPathArray;
|
||||
|
||||
public override void _Ready()
|
||||
public Node2D? Spawn(int waveNumber)
|
||||
{
|
||||
base._Ready();
|
||||
if (!string.IsNullOrEmpty(_resPath))
|
||||
{
|
||||
_packedScene = GD.Load<PackedScene>(_resPath);
|
||||
}
|
||||
}
|
||||
|
||||
public Node2D? Spawn()
|
||||
{
|
||||
if (GameSceneDepend.AiCharacterContainer == null || _packedScene == null)
|
||||
if (GameSceneDepend.AiCharacterContainer == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var aiCharacter = NodeUtils.InstantiatePackedScene<AiCharacter>(_packedScene);
|
||||
if (_resPathArray == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if (waveNumber < 0 || waveNumber >= _resPathArray.Length)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
var resPath = _resPathArray[waveNumber];
|
||||
if (string.IsNullOrEmpty(resPath))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
var packedScene = GD.Load<PackedScene>(resPath);
|
||||
if (packedScene == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
var aiCharacter = NodeUtils.InstantiatePackedScene<AiCharacter>(packedScene);
|
||||
if (aiCharacter == null)
|
||||
{
|
||||
return null;
|
||||
|
@ -41,6 +48,11 @@ public partial class AiCharacterSpawn : Marker2D, ISpawnMarker
|
|||
return aiCharacter;
|
||||
}
|
||||
|
||||
public int GetMaxWaveNumber()
|
||||
{
|
||||
return _resPathArray?.Length ?? 0;
|
||||
}
|
||||
|
||||
public bool CanQueueFree()
|
||||
{
|
||||
return true;
|
||||
|
|
|
@ -11,17 +11,26 @@ namespace ColdMint.scripts.map;
|
|||
/// </summary>
|
||||
public partial class ItemSpawn : Marker2D, ISpawnMarker
|
||||
{
|
||||
[Export] private string? ItemId { get; set; }
|
||||
[Export] private string[]? _itemIdList;
|
||||
|
||||
public Node2D? Spawn()
|
||||
public Node2D? Spawn(int waveNumber)
|
||||
{
|
||||
if (string.IsNullOrEmpty(ItemId))
|
||||
if (_itemIdList == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var item = ItemTypeManager.CreateItem(ItemId, this);
|
||||
LogCat.LogWithFormat("generated_item_is_empty", LogCat.LogLabel.ItemSpawn, true, ItemId, item == null);
|
||||
if (waveNumber < 0 || waveNumber >= _itemIdList.Length)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
var itemId = _itemIdList[waveNumber];
|
||||
if (string.IsNullOrEmpty(itemId))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
var item = ItemTypeManager.CreateItem(itemId, this);
|
||||
LogCat.LogWithFormat("generated_item_is_empty", LogCat.LogLabel.ItemSpawn, true, itemId, item == null);
|
||||
if (item is not Node2D node2D)
|
||||
{
|
||||
return null;
|
||||
|
@ -30,6 +39,11 @@ public partial class ItemSpawn : Marker2D, ISpawnMarker
|
|||
return node2D;
|
||||
}
|
||||
|
||||
public int GetMaxWaveNumber()
|
||||
{
|
||||
return _itemIdList?.Length ?? 0;
|
||||
}
|
||||
|
||||
public bool CanQueueFree()
|
||||
{
|
||||
return true;
|
||||
|
|
|
@ -12,9 +12,14 @@ namespace ColdMint.scripts.map;
|
|||
/// <para>PlayerSpawn</para>
|
||||
/// <para>玩家出生点</para>
|
||||
/// </summary>
|
||||
public partial class PlayerSpawn : Marker2D,ISpawnMarker
|
||||
public partial class PlayerSpawn : Marker2D, ISpawnMarker
|
||||
{
|
||||
private PackedScene? _playerPackedScene;
|
||||
/// <summary>
|
||||
/// <para>The player's generated wave count</para>
|
||||
/// <para>玩家的生成波数</para>
|
||||
/// </summary>
|
||||
private static readonly int PlayerWaveNumber = 1;
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
|
@ -32,7 +37,7 @@ public partial class PlayerSpawn : Marker2D,ISpawnMarker
|
|||
GameSceneDepend.Player.GlobalPosition = GlobalPosition;
|
||||
return;
|
||||
}
|
||||
Spawn();
|
||||
Spawn(PlayerWaveNumber);
|
||||
}
|
||||
|
||||
|
||||
|
@ -47,7 +52,7 @@ public partial class PlayerSpawn : Marker2D,ISpawnMarker
|
|||
return;
|
||||
}
|
||||
|
||||
Spawn();
|
||||
Spawn(PlayerWaveNumber);
|
||||
}
|
||||
|
||||
public override void _ExitTree()
|
||||
|
@ -57,8 +62,13 @@ public partial class PlayerSpawn : Marker2D,ISpawnMarker
|
|||
EventBus.GameReplayEvent -= GameReplayEvent;
|
||||
}
|
||||
|
||||
public Node2D? Spawn()
|
||||
|
||||
public Node2D? Spawn(int waveNumber)
|
||||
{
|
||||
if (waveNumber != PlayerWaveNumber)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if (GameSceneDepend.PlayerContainer == null)
|
||||
{
|
||||
return null;
|
||||
|
@ -94,6 +104,11 @@ public partial class PlayerSpawn : Marker2D,ISpawnMarker
|
|||
return playerNode;
|
||||
}
|
||||
|
||||
public int GetMaxWaveNumber()
|
||||
{
|
||||
return PlayerWaveNumber;
|
||||
}
|
||||
|
||||
public bool CanQueueFree()
|
||||
{
|
||||
return false;
|
||||
|
|
|
@ -12,11 +12,22 @@ public interface ISpawnMarker
|
|||
/// <para>Generating entity</para>
|
||||
/// <para>生成实体</para>
|
||||
/// </summary>
|
||||
/// <param name="waveNumber">
|
||||
///<para>Spawning waves</para>
|
||||
///<para>刷怪的波次</para>
|
||||
/// </param>
|
||||
/// <remarks>
|
||||
///<para>Return the result of the generation. If null is returned, the generation fails.</para>
|
||||
///<para>返回生成结果,为null则生成失败。</para>
|
||||
/// </remarks>
|
||||
Node2D? Spawn();
|
||||
Node2D? Spawn(int waveNumber);
|
||||
|
||||
/// <summary>
|
||||
/// <para>GetMaxWaveNumber</para>
|
||||
/// <para>获取生成器支持的最大生成波数</para>
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
int GetMaxWaveNumber();
|
||||
|
||||
/// <summary>
|
||||
/// <para>Can Queue Free</para>
|
||||
|
|
|
@ -35,6 +35,20 @@ public class Room
|
|||
/// </summary>
|
||||
private Node2D? _autoSpawn;
|
||||
|
||||
/// <summary>
|
||||
/// <para>Current generated wave number</para>
|
||||
/// <para>当前生成波数</para>
|
||||
/// </summary>
|
||||
private int _currentWaveNumber;
|
||||
|
||||
private readonly List<CharacterTemplate> _spawnedCharacterTemplateList = [];
|
||||
|
||||
/// <summary>
|
||||
/// <para>Max generated wave number</para>
|
||||
/// <para>最大的生成波数</para>
|
||||
/// </summary>
|
||||
private int _maxWaveNumber;
|
||||
|
||||
/// <summary>
|
||||
/// <para>The number of times the player visits the room</para>
|
||||
/// <para>玩家访问房间的次数</para>
|
||||
|
@ -162,6 +176,76 @@ public class Room
|
|||
characterTemplate.Hide();
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// <para>Spawn a wave of entities</para>
|
||||
/// <para>生成一波实体</para>
|
||||
/// </summary>
|
||||
private void SpawnEnemyWave()
|
||||
{
|
||||
if (PlayerRoomVisitCount != 1 || _autoSpawn == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (_maxWaveNumber > 0 && _currentWaveNumber == _maxWaveNumber)
|
||||
{
|
||||
//Complete all waves.
|
||||
//完成所有的波次。
|
||||
ClearAllMatchedBarriers();
|
||||
GameSceneDepend.MiniMap?.Show();
|
||||
return;
|
||||
}
|
||||
NodeUtils.ForEachNode<ISpawnMarker>(_autoSpawn, marker =>
|
||||
{
|
||||
var node2D = marker.Spawn(_currentWaveNumber);
|
||||
if (node2D is CharacterTemplate characterTemplate)
|
||||
{
|
||||
//The maximum wave number should be the maximum wave number produced by living organisms.For now, the player's condition for the next step is to kill all enemies.
|
||||
//最大波数应该是生物生成的最大波数。就目前而言,玩家进入下一步的条件是杀死所有敌人。
|
||||
_maxWaveNumber = Math.Max(_maxWaveNumber, marker.GetMaxWaveNumber());
|
||||
_spawnedCharacterTemplateList.Add(characterTemplate);
|
||||
characterTemplate.TreeExited += () =>
|
||||
{
|
||||
_spawnedCharacterTemplateList.Remove(characterTemplate);
|
||||
if (_spawnedCharacterTemplateList.Count == 0)
|
||||
{
|
||||
//All the creatures they summoned are dead.
|
||||
//召唤的生物全死了。
|
||||
_currentWaveNumber++;
|
||||
AddTimer(SpawnEnemyWave);
|
||||
}
|
||||
};
|
||||
}
|
||||
return false;
|
||||
});
|
||||
if (_spawnedCharacterTemplateList.Count > 0)
|
||||
{
|
||||
GameSceneDepend.MiniMap?.Hide();
|
||||
AddTimer(PlaceBarriersInAllSlots);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>Add a timer node to handle some events</para>
|
||||
/// <para>添加定时器节点处理一些事件</para>
|
||||
/// </summary>
|
||||
/// <param name="timeoutAction"></param>
|
||||
private void AddTimer(Action timeoutAction)
|
||||
{
|
||||
if (_rootNode == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
var timer = new Timer();
|
||||
timer.Autostart = true;
|
||||
timer.OneShot = true;
|
||||
timer.WaitTime = 0.3f;
|
||||
timer.Timeout += () =>
|
||||
{
|
||||
timeoutAction.Invoke();
|
||||
timer.QueueFree();
|
||||
};
|
||||
NodeUtils.CallDeferredAddChild(_rootNode, timer);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>When a node enters the room</para>
|
||||
|
@ -181,14 +265,7 @@ public class Room
|
|||
_characterTemplateList.Add(player);
|
||||
_hasPlayer = true;
|
||||
PlayerRoomVisitCount++;
|
||||
if (PlayerRoomVisitCount == 1 && _autoSpawn != null)
|
||||
{
|
||||
NodeUtils.ForEachNode<ISpawnMarker>(_autoSpawn, marker =>
|
||||
{
|
||||
marker.Spawn();
|
||||
return false;
|
||||
});
|
||||
}
|
||||
SpawnEnemyWave();
|
||||
//The player enters the room, opening up their view.
|
||||
//玩家进入了房间,开放视野。
|
||||
if (_pointLight2D != null)
|
||||
|
|
Loading…
Reference in New Issue
Block a user