C# 使用LINQ从对象列表中隔离特定对象
C# 使用LINQ从对象列表中隔离特定对象,c#,visual-studio-2008,linq,c#-3.0,C#,Visual Studio 2008,Linq,C# 3.0,(来源:) 我正在尝试制作一个侵略者克隆体。屏幕上有30个外星人排列在5x6矩阵中。我需要给最底层的外星人一个射击的能力。 我正在使用LINQ根据Location.X将外星人分成5个组,然后对组进行降序排序。然后我需要选择其中一个组(这给了我5个组) 然后选择组中的第一个外国人并使用它;让我们一起开枪 我下面的代码很有效,但是任何一排的外星人都在愉快地开火——不仅仅是最底层的人。请看下面的代码,告诉我出了什么问题。 (r=随机类的一个实例,所有外星人都在一个名为入侵者的列表中) 编辑: 解决了。
(来源:) 我正在尝试制作一个侵略者克隆体。屏幕上有30个外星人排列在5x6矩阵中。我需要给最底层的外星人一个射击的能力。 我正在使用LINQ根据Location.X将外星人分成5个组,然后对组进行降序排序。然后我需要选择其中一个组(这给了我5个组) 然后选择组中的第一个外国人并使用它;让我们一起开枪 我下面的代码很有效,但是任何一排的外星人都在愉快地开火——不仅仅是最底层的人。请看下面的代码,告诉我出了什么问题。 (r=随机类的一个实例,所有外星人都在一个名为入侵者的列表中) 编辑: 解决了。在大卫B把我推向正确的方向后,现在它可以按要求工作了 下面是最终代码。 鉴于正在进行的大量分组/排序,可能确实需要一些改进。如果有人对此有建设性的意见,我会洗耳恭听(在这种情况下,我会洗耳恭听)。感谢所有帮助过我的人
List<Invader> firstinvader = invaders.GroupBy(inv => inv.Location.X)
.Select(g => g.OrderByDescending(inv => inv.Location.Y)).ElementAt(r.Next(5)).ToList();
firstinvader.Sort(comparerByLocation);
Invader item = firstinvader[firstinvader.Count -1];
if(invaderShots.Count < 2)
{
invaderShots.Add(new Shot(
new Point(item.Area.X + item.Area.Width / 2, item.Area.Y + item.Area.Height / 2),
displayrect, Shot.Direction.Down));
}
else
{
return;
}
List firstinvader=invaders.GroupBy(inv=>inv.Location.X)
.Select(g=>g.OrderByDescending(inv=>inv.Location.Y)).ElementAt(r.Next(5)).ToList();
第一个入侵者。排序(comparerByLocation);
入侵者物品=第一个入侵者[firstinvader.Count-1];
如果(入侵者快照计数<2)
{
入侵者快照。添加(新快照)(
新点(项目面积X+项目面积宽度/2,项目面积Y+项目面积高度/2),
displayrect,Shot.Direction.Down);
}
其他的
{
返回;
}
您正在对组进行排序,但没有对入侵者进行排序。有可能这样做:
var query = (from inv in invaders
group inv by inv.Location.X
into invgroup
orderby invgroup.Key descending
select invgroup.OrderBy(inv => inv.Location.Y)).ToList();
(根据Y是向上还是向下,您可能希望进行降序。)
虽然这可能有效,但我不确定一直做这些排序是否理想。。。您不能将入侵者存储在一个数据结构中,以帮助您更轻松地执行此操作吗?您正在按
位置.X
进行分组,我猜这是一列。然后按列号对这些组进行排序-请注意,这会对组进行排序,而不是对组中的项目进行排序。由于您随后选择了一个随机组,因此您对它们进行排序的事实是无关紧要的。一旦你选择了一个随机组(原始外星人的随机列),你就可以首先选择组的,
,但是由于外星人在组中没有排序,你就得到了一个任意的外星人
要解决这个问题,您需要确保组是按高度排序的(Location.Y
,我猜),这样当您选择随机选择的组的第一个
时,它是最底层的。改变
select invgroup).ToList();
到
(假设你的Y
轴朝着正确的方向移动,从而得到你想要的!)列出第一个入侵者=入侵者
.GroupBy(inv=>inv.Location.X)
.选择(g=>g
.OrderByDescending(inv=>inv.Location.Y)
.First())
.ToList();
入侵者射手=第一个入侵者[r.Next(firstinvestors.Count)];
对不起!尝试了你的代码,但也不管用。射击仍然是从许多不同的行发射,而不是根据需要从最底部的行发射。@dezkev:Location和Area在入侵者类中有什么区别?Location是在屏幕上绘制入侵者时的一个点(X,Y),Area是定义如下的属性:public Rectangle Area{get{return new Rectangle(Location,Image.Size);}}@jonas-Elfstrom:r是Random的一个实例,我需要从5列中抽取一个随机列。(否则游戏会变得可预测)@Midhat:如果没有完整的解决方案,你怎么能测试它呢?如果你是说代码可以编译,当然可以。我已经在上面说过它可以工作,只是不做“必需”的事情我的INAVDER是一组按表格布局排列的按钮。为了模拟射击,我更改了按钮的文本。HERE:@midhat:谢谢你的文件。下载并运行了它。它按照你说的做。但仍然不能解决我的问题。Y轴是垂直的。也许我需要在随机选择后对它们进行排序。我怎么做?我也试过了吗不工作。正在发生的是外星人(或入侵者)在第一列中,只有正在发射,但又是任意发射-不是最底层的。因此,与我现有的代码相比有很大的改进,但仍然需要一些调整。我会尽我最大的努力。进一步调整后,它现在可以工作了。最后的代码请参阅我的原始帖子中的编辑。必须是你的X和Y被切换了。
select invgroup).ToList();
select invgroup.OrderBy(inv => inv.Location.Y)).ToList();
List<Invader> firstInvaders = invaders
.GroupBy(inv => inv.Location.X)
.Select(g => g
.OrderByDescending(inv => inv.Location.Y)
.First())
.ToList();
Invader shooter = firstInvaders[r.Next(firstInvaders.Count)];