flame_flutter3d 0.8.2
flame_flutter3d: ^0.8.2 copied to clipboard
A bridge to the Flame 2D game engine: Flame draws its own layer, flutter3d draws its own, and the two stay reconciled — transforms, lifecycle, physics contacts, input and the actor system.
flame_flutter3d #
A bridge to the Flame 2D game engine. Flame draws its own layer and flutter3d draws its own. This package keeps the two in agreement on transforms, lifecycle, physics contacts, input and the actor system; neither engine drives the other's renderer.
final camera = CameraNode(name: 'eye');
Flutter3dFlameWidget(
game: MyFlameGame(),
camera: camera,
buildScene: (device) => Scene()..add(camera),
)
One clock, two layers #
Flutter3dFlameWidget composites a flutter3d SceneSurface beneath Flame's
own GameWidget in one Stack. Flame is on top because it needs raw input,
the same way the HUD layer of apps/flutter3d_demo_platformer does. Neither
engine's renderer is reimplemented. A BridgeClock component, added once to
the hosted FlameGame, calls back every frame after Flame's own components
have updated. A physics step, an actor system step and a camera sync all
advance from that callback, so a bridged game has one clock, the one Flame
already owns.
One plane, everywhere a point crosses #
BridgePlane is the single place where a Flame Vector2 and a flutter3d
Vector3 are the same point. BridgePlane.ground(height:) is for a top-down
game, where Flame's y becomes flutter3d's z; BridgePlane.backdrop(depth:)
is for a side-scroller, where Flame's y becomes flutter3d's own y. Every
bridged component takes one, so a game does not reinvent its axis convention
per component.
The bridges #
- Transform:
Object3dComponentkeeps a FlamePositionComponentand a flutter3dSceneNodeat the same place, on oneBridgePlane, in the direction aSyncDirectionnames (sceneToFlameorflameToScene). The direction is chosen once, at construction, and never inferred from which side changed more recently. - The actor system:
ActorComponentextendsObject3dComponentto carry the body position of aflutter3d_simActoracross the bridge.ActorSystemComponentholds the singleActorSystem.beginStep()/step()pair that everyActorComponentin a game shares, so the system is stepped once a frame however many actors are bridged. - Physics:
RigidBodyComponentextendsObject3dComponentto carry the position of aflutter3d_physicsRigidBodythe same way; it never steps the world itself.PhysicsStepComponentdoes, once a frame: the solver, then an optionalafterStepfor whatever rides on a body, then the contact dispatch.CollisionBridgere-fires flutter3d'sCollisionListenerevents as Flame's ownCollisionCallbacks, projecting a 3D contact point through the bridge'sBridgePlaneinto theSet<Vector2>that Flame's callback expects. - Input:
FlameInputBridgetranslates Flame's own keyboard and drag callbacks into calls on theBindings/InputStateofflutter3d_game.DesktopInput/PadInputalready write into those same objects, so a bridged game and a native one share one input model, one rebinding UI and one saved binding file. A game forwards itsKeyboardEventsthroughonGameKeyEvent, a component itsKeyboardHandlerthroughonKeyEvent. - Camera:
CameraSyncControllerkeeps a flutter3dCameraNode(typically orthographic) and Flame's ownViewfinderframed the same, reconciling position and zoom in whichever direction is authoritative.CameraSyncComponentruns it as a Flame component, for a game that orders it by priority.
The flame pages of apps/flutter3d_showcase show one mechanism per page,
each with a step-by-step guide.