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

如何在flame_forge2d中创建矩形?含示例修改与碰撞需求

在flame_forge2d中创建可渲染矩形刚体(替代Love2D的newRectangleShape)

Love2D的newRectangleShape是对Box2D原生API的封装,而flame_forge2d直接使用Box2D底层接口,因此你需要用PolygonShape的setAsBox方法创建矩形物理形状,同时必须手动实现渲染逻辑(这也是官方示例中Wall看不到的原因——它只定义了物理碰撞体,没有绘制图形)。

核心实现步骤

  • 创建物理形状:用Box2D的PolygonShape().setAsBox(),注意参数是半宽和半高(Box2D以刚体中心为原点)。
  • 定义刚体属性:根据需求设置刚体类型(静态/运动学/动态),运动学刚体对应BodyType.kinematic。
  • 添加渲染逻辑:在BodyComponent的render方法中,用Flame的Canvas API绘制矩形,同步刚体的位置和旋转角度。

可复用矩形组件示例

import 'package:flame/components.dart';
import 'package:flame/geometry.dart';
import 'package:flame_forge2d/flame_forge2d.dart';
import 'dart:math' as math;

class RenderableRectangle extends BodyComponent {
  final Vector2 position;
  final Vector2 size;
  final BodyType bodyType;
  final double initialAngle;
  final double angularSpeed;

  RenderableRectangle({
    required this.position,
    required this.size,
    this.bodyType = BodyType.static,
    this.initialAngle = 0,
    this.angularSpeed = 0,
  });

  @override
  Body createBody() {
    // 定义矩形物理形状:参数为半宽、半高
    final shape = PolygonShape()
      ..setAsBox(size.x / 2, size.y / 2);

    final fixtureDef = FixtureDef(shape)
      ..density = 1.0
      ..friction = 0.3;

    final bodyDef = BodyDef()
      ..position = position
      ..type = bodyType
      ..angle = initialAngle;

    return world.createBody(bodyDef)..createFixture(fixtureDef);
  }

  @override
  void render(Canvas canvas) {
    // 同步刚体位置与旋转,绘制矩形
    canvas.save();
    canvas.translate(body.position.x, body.position.y);
    canvas.rotate(body.angle);
    canvas.drawRect(
      Rect.fromCenter(
        center: Offset.zero,
        width: size.x,
        height: size.y,
      ),
      Paint()..color = bodyType == BodyType.kinematic ? Colors.orange : Colors.blue,
    );
    canvas.restore();
  }

  @override
  void update(double dt) {
    super.update(dt);
    // 让运动学刚体持续旋转
    if (body.type == BodyType.kinematic) {
      body.setAngularVelocity(angularSpeed);
    }
  }
}

修改官方示例添加矩形

在官方示例的MyGame类initialize方法中,添加底部静态地面和可旋转的运动学矩形:

@override
Future<void> initialize() async {
  await super.initialize();
  
  // 添加底部静态地面矩形
  add(RenderableRectangle(
    position: Vector2(size.x / 2, size.y - 20),
    size: Vector2(size.x, 40),
    bodyType: BodyType.static,
  ));

  // 添加可旋转的运动学矩形
  add(RenderableRectangle(
    position: Vector2(size.x / 2, size.y / 2),
    size: Vector2(100, 50),
    bodyType: BodyType.kinematic,
    initialAngle: math.pi / 4, // 初始45度旋转
    angularSpeed: 0.5, // 每秒旋转0.5弧度
  ));

  // 保留原有的下落圆形逻辑
  for (var i = 0; i < 20; i++) {
    add(Ball(position: Vector2.random() * size));
  }
}

关键注意事项

  • Box2D的setAsBox参数是半宽半高,与Love2D直接传宽高的逻辑不同,必须将尺寸除以2。
  • 运动学刚体不受重力影响,可通过setAngularVelocity/setLinearVelocity主动控制运动状态。
  • 必须实现render方法才能看到图形,官方示例中的Wall仅定义了碰撞体,没有渲染代码所以不可见。

内容的提问来源于stack exchange,提问作者shingo.nakanishi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 12:15:17