Stop Characters Sticking to Walls in Matter.js
When developing a 2D platformer in Matter.js, players often experience an unwanted effect where the character clings to vertical walls if a directional movement key is held mid-air. This sticking issue is caused by default physics friction and collision resolving between the player's body and vertical surfaces. This article covers why this occurs and details the most effective solutions, ranging from adjusting friction properties to building composite bodies with dedicated sensors.
Why Wall Sticking Occurs
By default, Matter.js rigid bodies are assigned non-zero values for
friction and frictionStatic. When a player
holds down a movement key against a vertical wall, horizontal force or
velocity continuously pushes the player against the wall. The physics
engine calculates normal contact force, and the resulting vertical
friction counteracts gravity, keeping the character suspended mid-air
until the directional key is released.
Solution 1: Zero Out Friction on the Player Body
The fastest way to eliminate wall sticking is to remove friction from the player body entirely.
const player = Bodies.rectangle(x, y, width, height, {
friction: 0,
frictionStatic: 0,
frictionAir: 0.01,
inertia: Infinity // Prevents character rotation
});Because horizontal wall contact no longer produces friction, gravity pulls the player down smoothly regardless of whether lateral keys are pressed.
Note: Setting body friction to zero means the player will also slide across the floor without slowing down naturally. To handle ground movement properly, you must manually control deceleration in your update loop:
// Manual horizontal deceleration on the ground
if (!isMovingLeft && !isMovingRight && isGrounded) {
Matter.Body.setVelocity(player, {
x: player.velocity.x * 0.8,
y: player.velocity.y
});
}Solution 2: Use a Compound Body with a Foot Sensor (Recommended)
A standard platformer architecture isolates wall interactions from floor interactions using a compound body. You create a frictionless main collider for the torso/walls and a separate sensor body at the base for ground detection.
const bodyWidth = 40;
const bodyHeight = 60;
// Main body that touches walls (frictionless)
const mainBody = Bodies.rectangle(x, y, bodyWidth, bodyHeight, {
chamfer: { radius: 10 },
friction: 0,
frictionStatic: 0
});
// Ground sensor positioned slightly below the main body
const footSensor = Bodies.rectangle(x, y + bodyHeight / 2, bodyWidth * 0.8, 5, {
isSensor: true,
isStatic: false
});
// Combine into one compound body
const player = Body.create({
parts: [mainBody, footSensor],
inertia: Infinity,
friction: 0,
frictionStatic: 0
});Using an isSensor body at the base lets you trigger
collision events to toggle an isGrounded boolean. This
enables grounded friction logic or direct velocity control while
ensuring the main body never catches on walls.
Solution 3: Add Chamfer to Colliders
Sharp rectangular corners easily snag on the seams of tiled tilemaps and wall edges. Adding a chamfer to the player's collision box creates rounded corners that slide naturally over geometry transitions:
const player = Bodies.rectangle(x, y, width, height, {
chamfer: { radius: 8 },
friction: 0
});Alternatively, you can approximate a capsule collider by stacking circles or combining a rectangle with rounded ends.
Solution 4: Zero Lateral Velocity on Wall Contact
If your game mechanics require walls to have friction for other objects, you can selectively disable horizontal input when touching a wall.
Use Matter.js collision events (collisionActive) to
check contact normals:
Matter.Events.on(engine, 'collisionActive', (event) => {
event.pairs.forEach((pair) => {
if (pair.bodyA === player || pair.bodyB === player) {
const collision = pair.collision;
// Check if the collision normal is predominantly horizontal
if (Math.abs(collision.normal.x) > 0.5) {
// Stop the player from exerting inward force into the wall
if ((movingRight && collision.normal.x < 0) || (movingLeft && collision.normal.x > 0)) {
Matter.Body.setVelocity(player, { x: 0, y: player.velocity.y });
}
}
}
});
});This prevents lateral acceleration against vertical walls while keeping your vertical velocity intact for smooth falling.