加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 无法从XNA中的列表中删除项目

发布时间:2020-12-15 23:43:09 所属栏目:百科 来源:网络整理
导读:我正在研究一个Flappy Bird克隆作为练习,因为我最近开始在XNA上编程,而且我遇到了这个我无法理解的错误. 我在Update()函数中包含了以下代码,其作用是在屏幕离开时删除管道,以免在创建更多内容时向左无限移动: //Pipe despawnerforeach (var pipe in pipes){
我正在研究一个Flappy Bird克隆作为练习,因为我最近开始在XNA上编程,而且我遇到了这个我无法理解的错误.

我在Update()函数中包含了以下代码,其作用是在屏幕离开时删除管道,以免在创建更多内容时向左无限移动:

//Pipe despawner
foreach (var pipe in pipes)
{
   if (pipe.position1.X <= -180)
   {
         pipes.Remove(pipe);
   }
}

游戏运行正常,直到第一个管道离开屏幕,调试器暂停并通过以下消息发出这部分代码的信号:

An unhandled exception of type 'System.InvalidOperationException' occurred in mscorlib.dll

Additional information: Colección modificada; puede que no se ejecute la operación de enumeración.

对不起,第二部分是西班牙语,这是我系统的语言,但希望你知道如何解决问题.

考虑到游戏的简单性,我认为我可以简单地不包括这部分代码,结果是无限产生的管道对性能造成的影响很小,但我不想在我开始学习时立即采用这种做法.游戏编程.

解决方法

问题是您在枚举集合时修改集合(通过删除管道).这将始终在.NET中引发异常(如果您在多线程环境中执行此操作,则需要注意,因为您可以获得一些由于它而无法重现的异常).

解决它的一个简单方法是在枚举时保留“kill”列表:

列表killList = new List();

foreach (var pipe in pipes)
{
   if (pipe.position1.X <= -180)
   {
      killList.Add(pipe)
   }
}

更简单:

IEnumerable<Pipe> killList = pipes.Where (p => p.position1.X < -100);

无论哪种方式,枚举这个新集合,并从主要元素中删除匹配元素(从而避免错误条件):

foreach (Pipe p in killList)
   pipes.Remove(p);

你完成了!再次,请注意线程.如果要在另一个线程中创建新管道,则可能很容易与此管道“发生碰撞”并导致异常.如果是这种情况,请确保在这些代码段周围放置锁.

注意,如果使用LINQ方法,实际上可以内联“killList”:

foreach (Pipe p in pipes.Where(p => p.Position1.X <= -100))
   pipes.Remove(p);

正如@ rot13建议的那样,你也可以运行RemoveAll,从“Where”语句中传递谓词,如:

pipes.RemoveAll(p => p.Position1.X <= -100);

这就像它得到的一样简单:)

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读