Bullets pooling

This commit is contained in:
Marco 2025-06-08 16:33:38 +02:00
commit fa3805ecfe
18 changed files with 280 additions and 69 deletions

View file

@ -0,0 +1,131 @@
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using Cirno.Scripts.Resources;
using Godot;
using Godot.Collections;
namespace Cirno.Scripts.Controllers;
public partial class PoolingManager : Node2D
{
public static PoolingManager Instance { get; private set; }
[Export] public Array<PooledBulletInfo> PoolOnStart { get; private set; }
[Export] public bool DebugView { get; private set; } = false;
private readonly System.Collections.Generic.Dictionary<BulletResource, System.Collections.Generic.List<Bullet>>
_activeBullets = new();
private readonly System.Collections.Generic.Dictionary<BulletResource, System.Collections.Generic.List<Bullet>>
_inactiveBullets = new();
public override void _Ready()
{
Instance = this;
}
public Bullet SpawnBullet(BulletResource bulletResource, bool active = true)
{
// Look for bullet among the inactive ones
// If present move it to active, set it as active and return it
// Otherwise spawn it and add it to active and return it
var activeBullets = GetActiveBulletsList(bulletResource);
var inactiveBullets = GetInactiveBulletsList(bulletResource);
var bullet = inactiveBullets.Count > 0 ? inactiveBullets.First() : InstantiateBullet(bulletResource);
if (active)
{
inactiveBullets.Remove(bullet);
activeBullets.Add(bullet);
bullet.Enable();
}
else
{
activeBullets.Add(bullet);
inactiveBullets.Remove(bullet);
bullet.Disable();
}
return bullet;
}
public IEnumerable<Bullet> GetAllActiveBullets()
{
return _activeBullets.Values.SelectMany(list => list);
}
public IEnumerable<Bullet> GetAllInActiveBullets()
{
return _activeBullets.Values.SelectMany(list => list);
}
public List<Bullet> GetActiveBulletsList(BulletResource resource)
{
return GetOrCreateList(_activeBullets, resource);
}
private List<Bullet> GetInactiveBulletsList(BulletResource resource)
{
return GetOrCreateList(_inactiveBullets, resource);
}
public void DisableBullet(Bullet bullet)
{
var activeBulletsList = GetActiveBulletsList(bullet.BulletInfo.OriginalBulletResource);
var inactiveBulletsList = GetInactiveBulletsList(bullet.BulletInfo.OriginalBulletResource);
bullet.Disable(!DebugView);
activeBulletsList.Remove(bullet);
inactiveBulletsList.Add(bullet);
}
public void DisableAllBullets()
{
var allActiveBullets = GetAllActiveBullets().ToImmutableList();
foreach (var bullet in allActiveBullets)
{
var inactiveBulletsList = GetInactiveBulletsList(bullet.BulletInfo.OriginalBulletResource);
bullet.Disable(!DebugView);
inactiveBulletsList.Add(bullet);
}
foreach (var activeBulletsList in _activeBullets)
{
activeBulletsList.Value.Clear();
}
}
private List<Bullet> GetOrCreateList(System.Collections.Generic.Dictionary<BulletResource, List<Bullet>> dict, BulletResource resource)
{
if (dict.TryGetValue(resource, out var list)) return list;
list = [];
dict[resource] = list;
return list;
}
private Bullet InstantiateBullet(BulletResource bulletData)
{
var bullet = this.CreateChild<Bullet>(bulletData.BulletScene);
return bullet;
}
}
public partial class PooledBulletInfo : Resource
{
public BulletResource Bullet { get; private set; }
public int Amount { get; private set; }
}

View file

@ -0,0 +1 @@
uid://k1pdoan4wie2