检查列表中的下一个最高/最低值并选择该项目



更新:我应该更清楚。我正在尝试按升序排序列表,然后获得第一个具有比当前选择武器更大价值的武器。

我的NextWeapon()函数在这一点上没有做任何事情(它只是在那里显示我已经尝试过的事情),但在过去,我只是迭代到列表中的下一个项目,然而项目可能不在那里。

枚举F3DFXType是我的角色可能拿起的武器,但如果它们实际上不在库存中,那么循环这些武器就没有意义了。因此,我尝试创建一个int类型的列表,并循环遍历它。当角色拿起新武器时,它将作为整型添加到列表中,然后当我切换到该整型时,我会在F3DFXType enum中检查相同的整型。

例如,在拾取中,我会检查碰撞事件,然后使用:weaponList.Add (5);我想它会把5加到我的存货中。F3DFXType的第5项是"Seeker"。当我尝试循环我的库存时,它实际上不会添加第5个F3DFXType,它只会在F3DFXType中添加下一个项目。(例如:我已经有了Vulcan,这将简单地添加SoloGun,这是枚举中的第二项)


我正在尝试遍历列表中的项。

我遇到的问题是,如果我迭代到列表中的下一个项目,该项目可能实际上不在那里。那么我如何推进到列表中确实存在的下一个项目呢?

我不一定要用下面的代码寻找答案,我只是想给出一些背景,这样你就可以看到我目前的方法。

// Possible weapon types
public enum F3DFXType
{
    Vulcan = 1,
    SoloGun,
    Sniper,
    ShotGun,
    Seeker,
    RailGun,
    PlasmaGun,
    PlasmaBeam,
    PlasmaBeamHeavy,
    LightningGun,
    FlameRed,
    LaserImpulse
}

 // List of weapons currently avaialable
public List<int> weaponList;
public int currentIndex = 1;

void NextWeapon()
    {
        // Keep within bounds of list
        if (currentIndex < weaponList.Count)
        {
            currentIndex++;
            // Check if a higher value exists
            var higherVal = weaponList.Any(item => item < currentIndex);
            // create a new list to store current weapons in inventory
            var newWeapList = new List<int>();
            foreach (var weap in weaponList)
            {
                newWeapList.Add(weap);
            }
            weaponList = newWeapList;
            // If a higher value exists....
            if (higherVal)
            {
                //  currentIndex = SOMEHIGHERVALUE
            }
        }        
    }

    void PrevWeapon()
    {
        if (currentIndex > 1)
        {
            currentIndex--;
        }
    }

  // Fire turret weapon
    public void Fire()
    {
        switch (currentIndex)
        {
            case 1:
                // Fire vulcan at specified rate until canceled
                timerID = F3DTime.time.AddTimer(0.05f, Vulcan);
                Vulcan();
                break;
            case 2:
                timerID = F3DTime.time.AddTimer(0.2f, SoloGun);
                SoloGun();
                break;
            case 3:
                timerID = F3DTime.time.AddTimer(0.3f, Sniper);
                Sniper();
                break;
            case 4:
                ShotGun();
                break;
            case 5:
                timerID = F3DTime.time.AddTimer(0.2f, Seeker);
                Seeker();
                break
           default:
                break;
        }
    }

如果我正确理解了这个问题,我认为你可以简单地通过按升序排序列表来做到这一点,然后获得第一个比当前选择的武器具有更大价值的武器。

例如:

void Next()
{
    var nextWeapon = weaponList
        .OrderBy(w => w)                         // Sort the weapon list
        .FirstOrDefault(w => w > currentIndex);  // Get the next highest weapon
    // If nextWeapon is 0, there was no higher weapon found
    currentIndex = nextWeapon > 0 ? nextWeapon : currentIndex;
}
编辑:

你也可以反过来得到之前的武器:

void PrevWeapon()
{
    if (currentIndex > 1)
    {
        var previousWeapon = weaponList
            .OrderByDescending(w => w)               // Sort the weapon list
            .FirstOrDefault(w => w < currentIndex);  // Get the next lowest weapon
        // If previousWeapon is 0, there is no next lowest weapon
        currentIndex = previousWeapon > 0 ? previousWeapon : currentIndex;
    }
}

我找到了一个解决方案。不知道为什么我花了这么长时间才明白。不管怎样,我已经把它修好了。

一开始我的库存中有2支枪。我现在只能在这两者之间切换。(项目0 &

当我与拾取物碰撞时,我可以将另一项物品添加到此库存(数组中的第11项)。

现在当我点击Previous或Advance时,它知道要留在数组的范围内,如果没有找到更高的武器,那么默认回到我们当前使用的武器。

// Weapon types
public enum F3DFXType
{
    Vulcan          = 0,
    SoloGun         = 1,
    Sniper          = 2,
    ShotGun         = 3,
    Seeker          = 4,
    RailGun         = 5,
    PlasmaGun       = 6,
    PlasmaBeam      = 7,
    PlasmaBeamHeavy = 8,
    LightningGun    = 9,
    FlameRed        = 10,
    LaserImpulse    = 11,
    MAX_WEAPONS     = 12
}

    public bool[] aWeaponsHave = new bool[(int)F3DFXType.MAX_WEAPONS];
    int iWeaponsCurrent;

public Constructor() 
{
       .....
     // Start at first weapon (VULCAN)
        iWeaponsCurrent = 0;
        aWeaponsHave[0] = true;
        // DEBUG: Add weapon to inventory
        aWeaponsHave[1] = true;
         .....
}

 private void GoNextWeapon()
    {
        // If there isn't a higher value found, then default back to the original one
        var originalVal = iWeaponsCurrent;
        do
        {
            iWeaponsCurrent++;
            // Went to the end of array & didn't find a new weapon. Set it to the original one. 
            if (iWeaponsCurrent == 12)
            {
                iWeaponsCurrent = originalVal;
                return;
            }
        } while (aWeaponsHave[iWeaponsCurrent] == false);
    }

    void GoPrevWeapon()
{
    do
    {
        iWeaponsCurrent--;
        // Prevent from spilling over
        if (iWeaponsCurrent < 0)
        {
            // Went to end of array. Set weapon to lowest value and get out of here
            iWeaponsCurrent = 0;
            return;
        }
    } while (!aWeaponsHave[iWeaponsCurrent]);
}

// Fire turret weapon
    public void Fire()
    {
        switch (iWeaponsCurrent)
        {
            //case F3DFXType.Vulcan:
            case 0:
                // Fire vulcan at specified rate until canceled
                timerID = F3DTime.time.AddTimer(0.05f, Vulcan);
                // Invoke manually before the timer ticked to avoid initial delay
                Vulcan();
                break;
            //case F3DFXType.SoloGun:
            case 1:
                timerID = F3DTime.time.AddTimer(0.2f, SoloGun);
                Debug.Log("Solo");
                SoloGun();
                break;
            //case F3DFXType.Sniper:
            case 2:
                timerID = F3DTime.time.AddTimer(0.3f, Sniper);
                Debug.Log("Sniper");
                Sniper();
                break;
            //case F3DFXType.ShotGun:
            case 3:
                timerID = F3DTime.time.AddTimer(0.3f, ShotGun);
                ShotGun();
                break;
            //case F3DFXType.Seeker:
            case 4:
                timerID = F3DTime.time.AddTimer(0.2f, Seeker);
                Seeker();
                break;
            //case F3DFXType.RailGun:
            case 5:
                timerID = F3DTime.time.AddTimer(0.2f, RailGun);
                Debug.Log("railgun");
                RailGun();
                break;
            //case F3DFXType.PlasmaGun:
            case 6:
                timerID = F3DTime.time.AddTimer(0.2f, PlasmaGun);
                PlasmaGun();
                break;
            //case F3DFXType.PlasmaBeam:
            case 7:
                // Beams has no timer requirement
                PlasmaBeam();
                break;
            //case F3DFXType.PlasmaBeamHeavy:
            case 8:
                // Beams has no timer requirement
                PlasmaBeamHeavy();
                break;
            //case F3DFXType.LightningGun:
            case 9:
                // Beams has no timer requirement
                LightningGun();
                break;
            //case F3DFXType.FlameRed:
            case 10:
                // Flames has no timer requirement
                FlameRed();
                break;
            //case F3DFXType.LaserImpulse:
            case 11:
                timerID = F3DTime.time.AddTimer(0.15f, LaserImpulse);
                LaserImpulse();
                break;
            default:
                break;
        }
    }

最新更新