随机生成世界中不同尺寸游戏对象的放置碰撞检测方案咨询
判断游戏对象放置区域是否占用的核心方法
这个问题本质上是2D轴对齐矩形的碰撞检测(因为你只用x、z坐标,相当于忽略y轴的平面问题),核心思路是通过对比对象的包围盒边界来判断是否重叠。下面一步步拆解具体实现:
第一步:定义每个对象的包围盒边界
首先你需要给每个已放置的对象(比如那棵10x10的树)记录它的空间范围——也就是它在x-z平面上的矩形包围盒的四个边界值:min_x(最左x坐标)、max_x(最右x坐标)、min_z(最前/最下z坐标)、max_z(最后/最上z坐标)。
这里要注意对象的锚点规则(也就是你说的“位于(10,0,10)”是矩形的哪个点),常见的两种规则:
- 如果是中心锚点:比如那棵树的中心在(10,10),尺寸10x10,那么:
min_x = 10 - (10/2) = 5 max_x = 10 + (10/2) = 15 min_z = 10 - (10/2) = 5 max_z = 10 + (10/2) = 15 - 如果是左下角锚点:比如树的左下角在(10,10),尺寸10x10,那么:
min_x = 10 max_x = 10 + 10 = 20 min_z = 10 max_z = 10 + 10 = 20
不管用哪种规则,统一就行,否则边界计算会出错。
第二步:判断两个矩形是否重叠
对于要放置的新对象(比如5x5的石块),先按照同样的锚点规则算出它的包围盒边界。然后用分离轴定理的简化版判断它和已存在对象的包围盒是否重叠:
两个轴对齐矩形不重叠的情况只有四种:
- 新对象完全在已存在对象的左边:
新对象.max_x < 已存在对象.min_x - 新对象完全在已存在对象的右边:
新对象.min_x > 已存在对象.max_x - 新对象完全在已存在对象的前边/下边:
新对象.max_z < 已存在对象.min_z - 新对象完全在已存在对象的后边/上边:
新对象.min_z > 已存在对象.max_z
如果以上四个条件都不满足,说明两个矩形有重叠区域,也就是石块不能放在这个位置。
举个你例子里的实例
假设树是中心锚点,边界是min_x=5, max_x=15, min_z=5, max_z=15。现在要放一个中心在(12,12)的5x5石块:
- 石块的边界:
min_x=9.5, max_x=14.5, min_z=9.5, max_z=14.5 - 检查四个不重叠条件:
- 14.5 < 5?不成立
- 9.5 > 15?不成立
- 14.5 <5?不成立
4.9.5>15?不成立
所以四个条件都不满足,判定重叠,石块不能放置。
第三步:落地到游戏里的实现流程
- 存储已放置对象的边界:可以用一个数组/列表保存所有已放置对象的
min_x, max_x, min_z, max_z,或者保存位置、尺寸、锚点类型,需要时实时计算边界。 - 预计算新对象的边界:当玩家选择放置石块时,先根据石块的位置、尺寸、锚点算出它的包围盒。
- 遍历检测重叠:遍历所有已放置的对象,逐一对比边界。如果和任何一个对象重叠,就提示“位置被占用”;如果全部都不重叠,就允许放置。
进阶优化:提升检测效率
如果你的游戏世界很大,对象很多,遍历所有对象会很慢。可以用空间划分优化:
- 把x-z平面分成固定大小的网格(比如每个格子20x20)
- 每个对象放入它覆盖的格子里
- 放置新对象时,只需要检查它所在格子以及相邻格子里的对象,不用遍历全部对象,大幅减少检测次数
内容的提问来源于stack exchange,提问作者user9534568
相关产品推荐
相关产品推荐

