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

基于Flame+Forge2D的打砖块游戏:小球碰撞Paddle角度调整问题

打砖块游戏Flame+Forge2D小球碰撞Paddle方向调整问题

我正在学习Flame+Forge2D开发经典打砖块游戏,目前卡在小球碰撞Paddle后的方向调整上。需求如下:
假设Paddle宽度为6,小球碰撞不同位置时:

  • 碰撞位置在(0,1)区间 → 小球向左运动
  • 碰撞位置在(2,3)区间 → 小球垂直向上运动
  • 碰撞位置在(4,5)区间 → 小球向右运动
    核心要求:忽略小球来向,严格按上述规则调整角度,同时保持速度大小不变

现有代码

Ball组件的碰撞处理代码

@override
void beginContact(Object other, Contact contact) {
  super.beginContact(other, contact);

  if (other is Paddle) {
    final ballManifold = WorldManifold();
    contact.getWorldManifold(ballManifold);

    final intersection = ballManifold.points[0] / 20;
    var localIntersection = body.localPoint(intersection);

    final double fraction = localIntersection.x / other.size.width / 2;

    final Vector2 direction = body.linearVelocity;
    if (fraction < 0.33) {
      body.linearVelocity += Vector2(-direction.x, direction.y);
      print('left');
    } else if (fraction < 0.67) {
      body.linearVelocity = Vector2(0.0, -10.0);
      print('cenbter');
    } else {
      body.linearVelocity += Vector2(direction.x, direction.y);
      print('right');
    }
  } else if (other is PowerUp) {
    // body.applyLinearImpulse(Vector2(15, 15));
    other.hasCollidedWithBall(body);
    gameRef.paddle.increaseSize();
  }
}

Ball组件的Body创建代码

@override
Body createBody() {
  final bodyDef = BodyDef()
    ..type = BodyType.dynamic
    ..userData = this
    ..position = position;

  final ball = world.createBody(bodyDef);
  final fixtureDef = FixtureDef(CircleShape()..radius = radius)
    ..restitution = 1
    ..friction = 0
    ..density = 1;
  ball.createFixture(fixtureDef);

  return ball;
}

Paddle组件的Body创建代码

@override
Body createBody() {
  final bodyDef = BodyDef()
    ..type = BodyType.dynamic
    ..position = position
    ..fixedRotation = true
    ..angularDamping = 1
    ..linearDamping = 10;

  final paddleBody = world.createBody(bodyDef);

  final shape = PolygonShape()
    ..setAsBox(size.width / 2, size.height / 2, Vector2.zero(), 0);

  paddleBody.createFixture(
    FixtureDef(shape)
      ..density = 100
      ..userData = this
      ..friction = 0
      ..restitution = 1,
  );

  return paddleBody;
}

重要信息

  • Ball和Paddle均为BodyComponent;
  • 方向调整代码位于Ball组件内部;
  • 游戏设置:gravity = Vector2.zero(),zoom = 20;
  • Paddle宽度会随游戏进程动态增减;

可使用非Dart语言解答,Forge2D是Box2D的Dart实现,只需明确算法逻辑即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 02:13:11