Flutter 中, Flame + flame_forge2d世界坐标和屏幕坐标对齐
一、核心概念(先对齐心智模型)
- Forge2D 的单位是米(m),你的刚体
Body/Fixture的位置与尺寸都是米。 - Flame 的渲染单位是逻辑像素(px),
SpriteComponent/PositionComponent的size/position默认用像素。 - 需要一个**像素/米比例(PPM, pixels-per-meter)**把两者连起来,例如
PPM = 10表示 1 米 = 10 像素。
只要你在“计算、事件输入、渲染尺寸”三个点都用同一套 PPM,就不会错位。
二、固定写法(推荐模板)
1)定义全局比例
const double PPM = 10.0; // 1m = 10px,可按需求调整
Vector2 worldToScreen(Vector2 w) => w * PPM;
Vector2 screenToWorld(Vector2 s) => s / PPM;
2)摄像机与坐标转换
-
用户触摸/输入要落到世界坐标:
bool onTapDown(TapDownInfo info) {final screenPos = info.eventPosition.global; // 屏幕像素final worldPos = camera.viewfinder.screenToWorld(screenPos);// worldPos 现在是米(配合你设定的 PPM/zoom)return true; } -
在代码里不要自己写一套 camera 变换同时又用
PPM,否则会“双重缩放”。
建议:用 Flame Camera 的screenToWorld/worldToScreen作为最终裁判。PPM 只用于「物理 ↔ 渲染尺寸」。
3)刚体与精灵对齐
- 刚体:用米(Forge2D)
- 精灵:用像素(Flame)
- 关键:渲染尺寸 = 物理尺寸(米) × PPM
class Player extends BodyComponent {final Vector2 sizeInMeters = Vector2(1.2, 0.8); // 物理尺寸:1.2m x 0.8mlate final SpriteComponent sprite;Future<void> onLoad() async {await super.onLoad