XNA(Monogame):无需循环检测Car与任意ParkingLoot碰撞的方法
解决方法:用LINQ的Any()方法简化碰撞检测
嘿,这个场景太常见了!手动写循环确实麻烦,尤其是当集合元素数量不确定的时候。你可以用C#里LINQ的Any()方法来优雅解决这个问题,完全不用写for循环~
核心思路
Any()方法的作用就是检查集合中是否存在任意一个元素满足指定条件,而且它会做“短路评估”——找到第一个符合条件的元素就立刻停止遍历,效率和你手动写for循环加break是一样的,但代码简洁太多。
修改后的代码
首先确保你引用了System.Linq命名空间(大多数项目默认已经引用了,但如果没有的话要加上),然后直接用下面一行代码替换你原来的判断:
using System.Linq; // 必要的命名空间 // 直接赋值,无需手动写if/else或循环 intersects = parkingLoot.Any(loot => car1.hitbox.Intersects(loot.hitbox));
代码解释
parkingLoot.Any(...):遍历你的parkingLoot集合loot => car1.hitbox.Intersects(loot.hitbox):这是一个lambda表达式,定义了判断条件——当前遍历到的loot对象的hitbox是否和car1的hitbox相交- 整个表达式的结果就是布尔值,直接赋值给
intersects即可,完全替代了你原来的if/else逻辑
关于性能的小说明
不用担心1000个元素的性能问题:Any()内部其实也是循环,但它会在找到第一个相交的元素后立刻停止遍历,不会遍历整个集合。这和你手动写for循环并在找到匹配后break的效率完全一致,而且Rectangle.Intersects()本身是轻量的矩形交集判断,速度很快。
如果因为某些限制不能用LINQ(比如老版本.NET环境),那还是得手动写循环,但可以优化成找到匹配就break:
bool intersects = false; foreach (var loot in parkingLoot) { if (car1.hitbox.Intersects(loot.hitbox)) { intersects = true; break; // 找到后立刻退出循环,避免多余检查 } }
不过还是优先推荐LINQ的写法,代码更简洁易读~
内容的提问来源于stack exchange,提问作者Ufuk Bakan
相关产品推荐
相关产品推荐

