logo
Unlock

Install with the CLI:

bjs download Flipper

Flipper

A keyboard-driven kinematic pinball bat that swings up while its trigger key is held and falls back when released.

What it does

The flipper entity owns a MeshPrimitive and a kinematic Physics body whose pose is driven from the mesh each frame. While the trigger key is held, the bat's Y rotation ramps toward flipAngle at flipSpeed; on release it returns to restAngle at returnSpeed, and Havok turns that animated motion into the contact impulse that pings the ball. Opting into taperedGeometry rebuilds the mesh as a trapezoidal prism hinged at the pivot end (so it swings around the outer hinge like a real flipper) and inflates the physics collider to resist tunneling. It listens for flipper.rebuildColliders to refit collider extents live and emits flipper.colliderRebuilt afterward so debug panels can refresh.

Use it in a scene

A scene is just data — a list of entities, each with its components. At startup the SceneLoader turns this JSON into a live world; edit the file and reload to rebuild it.

Fastest path

bjs download scene Flipper

Pulls this exact scene into your project and runs it — no copy-paste. Add --all to grab the components and assets it needs too.

Or build it from scratch with the bjs CLI:

  1. 1Scaffold a project
    npm create @babylonjsmarket/arcade@latest my-game

    World, renderer, and dev server — ready to run.

  2. 2Install dependencies
    cd my-game && npm install
  3. 3Add Flipper
    bjs download Flipper

    Copies its source into src/ so the scene resolves.

    First time? Run bjs login once.

  4. 4Paste the scene into src/scenes/arcade-room.ts and run
    npm run dev

    SceneLoader builds the world from the JSON; reload to rebuild.

JSON
{
  "Flipper_Left": {
    "tags": ["flipper", "flipper-left"],
    "components": {
      "MeshPrimitive": {
        "primitive": "box",
        "width": 2.4,
        "height": 0.4,
        "depth": 0.6,
        "position": [-3, 0.3, 0],
        "material": { "diffuseColor": [0.85, 0.85, 0.95] }
      },
      "Physics": { "shapeType": "box", "motionType": "kinematic", "mass": 1, "restitution": 0.4, "friction": 0.1, "autoCreate": false },
      "Flipper": {
        "restAngle": -0.555,
        "flipAngle": 0.5,
        "flipSpeed": 24,
        "returnSpeed": 12,
        "triggerKey": "ShiftLeft",
        "taperedGeometry": true,
        "length": 2.4,
        "direction": "left",
        "colliderInflate": { "y": 0.1, "z": 0.5 }
      }
    }
  }
}

Props

  • restAngle (number, default -0.45) — Y-rotation (radians) when the key is not held.
  • flipAngle (number, default 0.45) — target Y-rotation (radians) while the key is held.
  • flipSpeed (number, default 22) — angular speed (rad/sec) swinging toward flipAngle.
  • returnSpeed (number, default 12) — angular speed (rad/sec) returning to restAngle.
  • triggerKey (string, default 'KeyZ') — KeyboardEvent.code that fires the flipper.
  • taperedGeometry (boolean, default false) — rebuild the box as a trapezoidal prism hinged at the pivot end; requires Physics: { autoCreate: false }.
  • length (number, default 2.4) — bat length, pivot to tip.
  • direction ('left' | 'right', default 'left') — which way the bat extends from the pivot (left = +X, right = -X).
  • colliderInflate ({ x?, y?, z? }, default {0,0,0}) — world-units added to each side of the collider's bounding box (anti-tunneling); the rendered mesh stays slim.

Events

  • emits flipper.colliderRebuilt — after a flipper's collider is rebuilt; payload { entityId }.
  • listens flipper.rebuildColliders — rebuilds every flipper's collider in place using the current colliderInflate values.

Dependencies

MeshPrimitive — the bat mesh whose pose the system drives. Physics — the kinematic body Havok uses to compute the ball impulse.

Notes

  • With taperedGeometry: true you must declare Physics: { autoCreate: false }; the system creates the body itself after rebuilding the mesh so the collider fits the new bounding box. Without that flag, PhysicsSystem beats it to the body and fits a box to the original geometry.
  • colliderInflate adds N units to each side (so z: 0.4 makes the collider 0.8 thicker on Z) — useful when a fast-swung tip tunnels past the ball between Havok substeps.
  • One-shot geometry/body creation is idempotent per flipper, tracked off the serializable Component.

More like this

MeshPrimitive
Physics
Bumper
CarDrive
FlightIntent
Jump
KeyboardInput
KeyboardMover
MouseHole
MouseInput
PinballBuilder
PinballBuilderInput
PinballCamera
PinballLayout
PinballTable
PlayerFlightInput
PlayerInput
PlayerInputBridge
Plunger
PokerInput
Spinner
TwinStickShooter

Was this page helpful?

We read every note — tell us what's working and what isn't.

↑↓ NavigateEnter SelectEsc CloseCtrl+K Open Search