You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#开发落石躲避游戏时如何实现矩形重叠重随机生成位置

2D落石躲避游戏巨石生成重叠判断修复方案

问题根源

你现有重叠判断逻辑存在两个致命错误:

  • 判断条件boulderRec[i].Contains(boulderRec[i])是将当前索引的巨石矩形与自身做包含校验,结果永远为true,会触发无限随机X坐标的死循环
  • 逻辑未遍历其余已存在的巨石矩形,完全没有实现「与其他巨石比对位置」的检测目标

另外补充:矩形碰撞检测不适合用Contains()方法——该方法仅当一个矩形完全包裹另一个矩形时才返回真,判断两个矩形是否有重叠区域应该用Intersects()方法。

实现思路

  • 仅在巨石触发重生逻辑(掉出屏幕底部、撞到玩家被重置到顶部)时执行重叠检测,不需要每帧为所有下落中的巨石做校验,减少不必要的性能消耗
  • 检测时遍历所有巨石矩形,跳过当前正在重置的巨石本身,只要和任意一个已存在的顶部待下落巨石有重叠,就重新随机X坐标
  • 增加最大重试次数兜底,避免巨石数量过多时顶部空间不足触发死循环
  • 随机X坐标时扣除巨石自身宽度,避免巨石生成时半截卡在屏幕外侧

修正后完整代码

private void moveBoulder(GameTime gameTime)
{
    // 单帧下落速度统一计算即可,不需要放到循环里重复赋值
    speed.Y = boulderDirY * (boulderSpeed * (float)(gameTime.ElapsedGameTime.TotalSeconds));
    const int maxSpawnRetry = 50; // 最大重生重试次数,防止死循环

    for (int i = 0; i <= boulderRec.Length - 1; i++)
    {
        bool needRespawnCheck = false;

        // 巨石掉出屏幕底部,重置到顶部
        if (boulderPos[i].Y > 1080)
        {
            boulderPos[i].Y = -200;
            needRespawnCheck = true;
        }

        // 巨石撞到玩家,扣分后重置到顶部
        if (boulderRec[i].Contains(testrec))
        {
            playerScore = playerScore + boulderHit;
            boulderPos[i].Y = -200;
            needRespawnCheck = true;
        }

        // 仅在需要重置位置时执行重叠检测
        if (needRespawnCheck)
        {
            int retryCount = 0;
            bool isOverlap;
            do
            {
                isOverlap = false;
                // 随机X坐标时减去巨石宽度,避免卡出屏幕,1920可替换为你实际存储的屏幕宽度变量
                boulderRec[i].X = rng.Next(0, 1920 - boulderRec[i].Width);
                boulderRec[i].Y = (int)boulderPos[i].Y;

                // 遍历所有其他巨石,判断是否重叠
                for (int j = 0; j < boulderRec.Length; j++)
                {
                    // 跳过自身,跳过已经进入下落流程的巨石,仅和顶部待生成的巨石比对位置
                    if (i == j || boulderPos[j].Y > -100) continue;
                    
                    if (boulderRec[i].Intersects(boulderRec[j]))
                    {
                        isOverlap = true;
                        break;
                    }
                }
                retryCount++;
                // 超过最大重试次数强制跳出,避免死循环卡帧
            } while (isOverlap && retryCount < maxSpawnRetry);
        }

        // 更新巨石下落位置
        boulderPos[i].Y = boulderPos[i].Y - speed.Y;
        boulderRec[i].Y = (int)boulderPos[i].Y;
    }
}

额外优化说明

  • 原代码的速度计算移到循环外即可,所有巨石共享单帧下落速度,不需要每遍历一个巨石就重新赋值一次
  • 重叠检测增加了Y坐标过滤,只和同样处于顶部待下落状态的巨石做位置比对,不会误判和已经下落的巨石重叠——同速度下落的巨石只要初始生成时不堆叠,后续下落过程永远不会重叠,不需要重复校验
  • 修正了随机X坐标的范围计算,适配巨石自身宽度,不会出现巨石半截卡在屏幕外的问题

内容的提问来源于stack exchange,提问作者12345678i9

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.01 20:06:39