在C# Windows Form火柴人平台游戏中实现实体碰撞检测
C# Windows Form平台游戏碰撞检测实现方案
核心思路
将所有需要阻挡角色的实体(包括底部边界GameBoundary、场景中的PictureBox障碍物)统一管理,每次角色移动/受重力影响时,先预判目标位置,检测是否会与障碍物碰撞,再调整角色位置避免穿透。
具体实现步骤
1. 统一管理障碍物
在Form类中添加列表存储所有碰撞实体,方便批量检测:
// 存储所有需要进行碰撞检测的障碍物 private List<Control> _obstacles = new List<Control>();
在Form构造函数里初始化列表,把底部边界和场景障碍物加入:
public Form1() { InitializeComponent(); // 添加底部边界 _obstacles.Add(GameBoundary); // 按需添加场景中的PictureBox障碍物,示例: _obstacles.Add(Obstacle1); _obstacles.Add(Obstacle2); }
2. 编写通用碰撞检测方法
实现一个方法,用来判断角色移动到目标位置时的碰撞情况,并返回修正后的合法位置:
// 检测目标位置与障碍物的碰撞,返回修正后的合法矩形 private Rectangle GetValidPosition(Rectangle targetRect) { foreach (var obstacle in _obstacles) { var obstacleRect = obstacle.Bounds; if (targetRect.IntersectsWith(obstacleRect)) { // 处理角色从上方落到障碍物的情况 if (Character.Bounds.Bottom <= obstacleRect.Top && targetRect.Bottom > obstacleRect.Top) { targetRect.Y = obstacleRect.Top - Character.Height; jump = false; // 重置跳跃状态,允许再次跳跃 } // 处理角色从下方顶到障碍物的情况 else if (Character.Bounds.Top >= obstacleRect.Bottom && targetRect.Top < obstacleRect.Bottom) { targetRect.Y = obstacleRect.Bottom; jump = false; force = 0; // 停止向上跳跃 } // 处理左侧碰撞 else if (Character.Bounds.Right <= obstacleRect.Left && targetRect.Right > obstacleRect.Left) { targetRect.X = obstacleRect.Left - Character.Width; } // 处理右侧碰撞 else if (Character.Bounds.Left >= obstacleRect.Right && targetRect.Left < obstacleRect.Right) { targetRect.X = obstacleRect.Right; } } } return targetRect; }
3. 修改Timer中的移动逻辑
不再直接修改角色位置,先计算目标位置,经碰撞检测修正后再赋值:
private void Timer(object sender, EventArgs e) { Rectangle targetRect = Character.Bounds; // 处理左右移动 if (left) { targetRect.X -= 15; Character.Image = Properties.Resources.LeftChar; } if (right) { targetRect.X += 15; Character.Image = Properties.Resources.RightChar; } // 处理跳跃 if (jump) { targetRect.Y -= force; force -= 1; if (force <= 0) { jump = false; // 跳跃力耗尽时停止跳跃 } } // 处理重力 else { targetRect.Y += 10; } // 碰撞检测并修正位置 targetRect = GetValidPosition(targetRect); // 应用修正后的位置 Character.Bounds = targetRect; }
4. 额外优化建议
- 将移动速度、重力值定义为常量,方便后续调整:
const int MoveSpeed = 15; const int Gravity = 10; - 优化图片切换逻辑,仅在方向变化时切换,减少资源开销
- 若场景障碍物较多,可只检测角色周围的障碍物,提升运行效率
内容的提问来源于stack exchange,提问作者Andrew Butler
相关产品推荐
相关产品推荐

