2021-01-17【tips】在循环中动态添加移除元素2
2021-01-17 本文已影响0人
持刀的要迟到了
之前写的方法,主要是为了在固定帧中,动态添加移除子弹。
后面由于出了bug,因此做了修改。
考虑的方面有如下几点:
1.由于是频繁操作,因此使用数组,并且减少循环遍历
2.添加元素,往数组的记录【最新】的位置后面依次添加
这样,当循环执行更新元素的时候,动态添加在后面的元素也能在本帧执行到。
3.移除元素,不能立即修改数组的元素。使用标记位,在本帧所有元素更新结束后才能移除。
4.由于标记位的缘故,不需要每帧都移除,可以定时间隔x帧清理一次
5.移除方式是把数组中某个元素移除,把后面的元素往前移填满数组。优化的方式,只需要遍历一次即可。
虽然是简单的for循环,但是还是出了各种bug;被逼无奈列举出了所有情况。
简单的东西,认真做也会有莫名的成就感;
贴部分代码
private int m_ActiveFrameBulletCount;
public Bullet[] m_FrameBulletList;
private int m_FrameToDeleteCount;
private int[] m_FrameToDeleteList;
private int m_MaxFrameBulletCount = 200;
int cleanTurn = 0;
int cleanFrequency = 10; //更新x轮子弹后销毁一次;要保证不能囤积数量超过数组最大数量
private void FrameUpdate()
{
//Debug.LogError("【BulletManager】更新子弹:" + Client.Ins.NetFrameIndex);
cleanTurn++;
if (cleanTurn == cleanFrequency)
{
cleanTurn = 0;
m_FrameToDeleteCount = 0;
}
var count = m_ActiveFrameBulletCount;
for (int i = 0; i < count; ++i)
{
var bullet = m_FrameBulletList[i];
if (bullet.Enabled)
{
//Debug.LogError("【BulletManager】更新子弹:" + bullet.preid + "_" + bullet.addid + "_" + Client.Ins.NetFrameIndex);
bullet.Update();
}
if (cleanTurn == 0 && bullet.toDelete)
{
m_FrameToDeleteList[m_FrameToDeleteCount] = i;
m_FrameToDeleteCount++;
}
}
if (cleanTurn == 0)
{
CleanFrameBullets();
}
}
private void CleanFrameBullets()
{
for (int i = 0; i < m_FrameToDeleteCount; i++)
{
int toDeleteIndex = m_FrameToDeleteList[i]; //获得在子弹表中要删除的index
int moveLastIndex = -1; //获得需要往前移 i+1 位的最后一项index
if (i != (m_FrameToDeleteCount - 1))
{
//当前删除项不是要删除的最后一项
//获取下一个要删除的项index,得到它前一个index
moveLastIndex = m_FrameToDeleteList[i + 1] - 1;
//目标:把两个要删除项之间的项,都前移 i+1 个格子
//如果两个项之间没有项,即:toDeleteIndex + 1 > moveLastIndex,那跳过本次移动
//否则遍历前移 i+1 位
int j = toDeleteIndex + 1;
if (j > moveLastIndex)
{
continue;
}
else
{
for (; j <= moveLastIndex; j++)
{
m_FrameBulletList[j - i - 1] = m_FrameBulletList[j];
}
}
}
else
{
//当前删除项就是要删除的最后一项
//获取最后一发子弹的index
moveLastIndex = m_ActiveFrameBulletCount - 1;
//目标:把后面所有的项,都前移 i+1 个格子
//如果小丑就是我自己,即:toDeleteIndex == moveLastIndex,那么跳过本次移动
//否则遍历前移 i+1 位
if (toDeleteIndex == moveLastIndex)
{
continue;
}
else
{
for (int j = toDeleteIndex + 1; j <= moveLastIndex; j++)
{
m_FrameBulletList[j - i - 1] = m_FrameBulletList[j];
}
}
}
}
}