Skip to main content

Revolute Joint (Hinge)

game.ts
const renderLayers = {
foreground: 1 << 0,
};

const gravity = new Vector2(0, -600);

export const createRevoluteJointGame = async (): Promise<Game> => {
const { game, world, renderContext, time } = createGame('demo-game');

createCamera(world, {
isStatic: true,
cullingMask: renderLayers.foreground,
verticalWorldUnits: DEMO_VERTICAL_WORLD_UNITS,
});

const physicsWorld = new PhysicsWorld({ gravity });

await createHinges(world, renderContext, renderLayers.foreground);

// `createRevoluteJointEcsSystem` and `createPushEcsSystem` must run before
// `createPhysicsSyncEcsSystem`, which is what steps `physicsWorld`:
// newly-added joints need to be registered, and this tick's push impulses
// applied, before that step happens (see the Revolute Joints guide's
// registration-order caution).
world.addSystem(createRevoluteJointEcsSystem(physicsWorld));
world.addSystem(createPushEcsSystem(time));
world.addSystem(createCameraEcsSystem(time));
world.addSystem(createRenderEcsSystem(renderContext));
world.addSystem(createPhysicsSyncEcsSystem(physicsWorld, time));

return game;
};

This demo showcases RevoluteJoint in three different setups. On the left, a door is hinged to a wall mount, its swing limited to 90 degrees between closed and open; gravity swings it shut and a periodic push swings it back open. In the middle, a pendulum is hinged by an arm to a fixed pivot and, with no limit and no push at all, simply swings back and forth under gravity, rotation is completely free. On the right, a wheel is hinged directly to its hub and, having been given a single initial spin, keeps rotating indefinitely: unlike RevoluteJoint's translation lock, nothing resists rotation unless a limit is enabled. RevoluteJoint has no built-in motor, so the door's swing is driven by a small demo-only system that periodically applies an off-center impulse (see push.component.ts and push.system.ts).