C#堆栈没有更新

时间:2013-05-18 06:24:21

标签: c# list xna stack

由于某种原因,我修改的代码似乎没有正常运行。调试时没有异常错误,但它与原始代码(列表)中的功能不同 - 也就是说它似乎没有更新。我已将其定位到我认为导致问题的代码区域:

我的原始代码(使用List)有效:

    private List<Gem> gems = new List<Gem>();
    private List<Enemy> enemies = new List<Enemy>();

    private void UpdateGems(GameTime gameTime)
    {
        for (int i = 0; i < gems.Count; ++i)
        {
            Gem gem = gems[i];

            gem.Update(gameTime);

            if (gem.BoundingCircle.Intersects(Player.BoundingRectangle))
            {
                gems.RemoveAt(i--);
                OnGemCollected(gem, Player);
            }
        }
    }

我的修改后的代码将List替换为Stack,但这些代码无法正常工作:

    private Stack<Gem> gems = new Stack<Gem>();
    private Stack<Enemy> enemies = new Stack<Enemy>();

    private void UpdateGems(GameTime gameTime)
    {
        for (int i = 0; i < gems.Count; ++i)
        {
            Gem gem = gems.Peek();


            gem.Update(gameTime);


            if (gem.BoundingCircle.Equals(Player.BoundingRectangle))
            {
                gems.Pop();

                OnGemCollected(gem, Player);
            }
        }
    }

有什么想法吗?

4 个答案:

答案 0 :(得分:1)

我不确切知道你需要什么,但是循环看起来有点奇怪:如果你在第一回合没有pop()堆栈中的任何东西,{{1总是会返回相同的元素。 堆栈数据结构未编入索引,它只允许弹出/查看最后推送的元素。列表中的代码当然不同,因为您实际上正在检查列表中的所有元素。

答案 1 :(得分:1)

根据定义,当你从堆栈中弹出一些东西时,你会删除最后添加的项目。因此,当您执行GemPeek以及Pop检查时,您已经颠倒了检查和删除集合中BoundingCircle.Equals()个对象的顺序。 {1}}版本您没有检查集合中的第一项,就像您在Stack<Gem>版本中一样。

可以在任一方向迭代List,只需以适当的方式调整索引器。 Stack是LIFO(后进先出),因此您只能访问最后添加的项目。

答案 2 :(得分:0)

我认为当调用peak方法时,它可能会在堆栈集合的顶部保留对该项的引用。所以当你打电话给pop方法时。它会工作不正常。

答案 3 :(得分:0)

我已复制您的示例并将其置于控制台应用程序中,如下所示

class Program
    {
        private static Stack<Gem> gems = new Stack<Gem>();
        private Stack<Enemy> enemies = new Stack<Enemy>();
        static void Main(string[] args)
        {
            gems.Push(new Gem
                {
                   BoundingCircle = new BoundingCircle
                       {
                           Name = "abc"
                       }
                });

            gems.Push(new Gem
            {
                BoundingCircle = new BoundingCircle
                {
                    Name = "def"
                }
            });

            UpdateGems(new GameTime());
        }

        private static void UpdateGems(GameTime gameTime)
        {
            for (int i = 0; i < gems.Count; ++i)
            {
                Gem gem = gems.Peek();


                gem.Update(gameTime);


                if (gem.BoundingCircle.Equals(Player.BoundingRectangle))
                {
                    gems.Pop();

                    OnGemCollected(gem, null);
                }
            }
        }

        private static void OnGemCollected(Gem gem, Player player)
        {

        }
    }

    public class Gem
    {
        public void Update(GameTime gameTime)
        {

        }

        public BoundingCircle BoundingCircle { get; set; }
    }

    public class Enemy
    {

    }

    public class GameTime
    {

    }

    public class BoundingCircle : Bounding
    {
        public override bool Equals(object obj)
        {
            var temp = (Bounding) obj;
            return Name.Equals(temp.Name, StringComparison.InvariantCulture);
        }
    }

    public class Player
    {
        static Player()
        {
            BoundingRectangle = new BoundingRectangle
                {
                    Name = "def"
                };
        }

        public static BoundingRectangle BoundingRectangle { get; set; }
    }

    public class BoundingRectangle : Bounding
    {

    }

    public abstract class Bounding
    {
        public string Name { get; set; }
    }

工作得很好。请注意,您的Equals函数必须被BoundingCircle类覆盖。