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

平台游戏角色边缘滑落问题:如何修复碰撞检测逻辑?

平台游戏角色边缘滑落问题修复

我开发的平台游戏中,角色靠近平台边缘时会缓慢滑落,希望实现角色稳定停留在平台顶部的效果。

相关代码

Player类(核心为onCollision方法)

class Player extends SpriteAnimationGroupComponent with HasGameRef<Gain>, KeyboardHandler, CollisionCallbacks {
  String character;
  Player({pos, this.character = "Ninja Frog"}) : super(position: pos);

  final double stepTime = 0.05;

  ...
  @override
  void onCollision(Set<Vector2> intersectionPoints, PositionComponent other) {
    if (other is Platform) {
      if (intersectionPoints.length == 2) {
        Vector2 mid = (intersectionPoints.elementAt(0) + intersectionPoints.elementAt(1)) / 2;
        Vector2 collisionNormal = absoluteCenter - mid;
        final seperationDist = (size.x / 2) - collisionNormal.length;
        collisionNormal.normalize();
        if (Vector2(0, -1).dot(collisionNormal) > 0.9) {
          _isOnGround = true;
        }
        position += collisionNormal.scaled(seperationDist);
      }
    }
    super.onCollision(intersectionPoints, other);
  }
}

Platform类(墙体、地面、天花板)

class Platform extends PositionComponent with CollisionCallbacks {
  bool canJumpThrough;
  Platform({required Vector2 position, required Vector2 size, this.canJumpThrough = false}) : super(position: position, size: size);

  @override
  FutureOr<void> onLoad() {
    add(RectangleHitbox(collisionType: CollisionType.passive));
    return super.onLoad();
  }
}

问题原因

当前代码存在两个核心问题:

  1. 地面判断阈值过严:只有碰撞法线几乎完全垂直向上(点积>0.9)时才标记_isOnGround为true,角色在平台边缘时,碰撞法线会带有水平分量,无法达到阈值,导致_isOnGround为false,角色受重力缓慢下落。
  2. 全方向分离逻辑不合理:碰撞分离时同时修改x、y轴位置,边缘碰撞的水平分离会把角色推离平台,加剧滑落现象。

修复方案

修改Player类的onCollision方法,调整地面判断逻辑并限制分离方向:

@override
void onCollision(Set<Vector2> intersectionPoints, PositionComponent other) {
  if (other is Platform) {
    if (intersectionPoints.length == 2) {
      Vector2 mid = (intersectionPoints.elementAt(0) + intersectionPoints.elementAt(1)) / 2;
      Vector2 collisionNormal = absoluteCenter - mid;
      collisionNormal.normalize();
      
      // 只要碰撞来自下方(法线y分量为正),就判定角色在地面上
      bool isOnPlatformTop = collisionNormal.y > 0;
      if (isOnPlatformTop) {
        _isOnGround = true;
        // 仅在y轴方向做分离,避免水平移动推离角色
        final verticalSeparation = (size.y / 2) - (absoluteCenter.y - mid.y);
        position.y += verticalSeparation;
      } else {
        // 非顶部碰撞(如撞墙),正常处理全方向分离
        final separationDist = (size.x / 2) - collisionNormal.length;
        position += collisionNormal.scaled(separationDist);
      }
    }
  }
  super.onCollision(intersectionPoints, other);
}

同时确保重力仅在角色不在地面时生效(检查Player的update方法):

@override
void update(double dt) {
  // 仅当不在地面时应用重力
  if (!_isOnGround) {
    // 假设gravity是你定义的重力常量
    position.y += gravity * dt;
  }
  // 其他更新逻辑
  super.update(dt);
}

额外优化

如果角色仍有轻微滑落,可以直接强制对齐平台顶部:

if (isOnPlatformTop) {
  _isOnGround = true;
  // 直接将角色底部对齐平台顶部
  position.y = other.position.y - size.y;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 17:03:22