Claude
Skills
Sign in
Back

physics-arcade

Included with Lifetime
$97 forever

Use this skill when using Arcade Physics in Phaser 4. Covers enabling physics, velocity, acceleration, gravity, collisions, overlap, world bounds, physics groups, static bodies, and collision categories. Triggers on: physics, arcade, velocity, gravity, collide, overlap, bounce, physics body.

General

What this skill does


# Arcade Physics
> Setting up and using Arcade Physics in Phaser 4 -- enabling physics in GameConfig, creating physics-enabled sprites/images/groups, velocity, acceleration, gravity, collisions (collide/overlap), world bounds, body properties, and collision categories.

**Key source paths:** `src/physics/arcade/ArcadePhysics.js`, `src/physics/arcade/World.js`, `src/physics/arcade/Body.js`, `src/physics/arcade/StaticBody.js`, `src/physics/arcade/Factory.js`, `src/physics/arcade/components/`, `src/physics/arcade/events/`
**Related skills:** ../game-setup-and-config/SKILL.md, ../sprites-and-images/SKILL.md, ../tilemaps/SKILL.md, ../groups-and-containers/SKILL.md

## Quick Start

```js
class GameScene extends Phaser.Scene {
    create() {
        // Physics sprite (dynamic body, affected by gravity)
        this.player = this.physics.add.sprite(100, 300, 'player');
        this.player.setCollideWorldBounds(true);
        this.player.setBounce(0.2);

        // Static group (immovable platforms)
        this.platforms = this.physics.add.staticGroup();
        this.platforms.create(400, 568, 'ground').setScale(2).refreshBody();

        // Register a persistent collider (checked every frame automatically)
        this.physics.add.collider(this.player, this.platforms);

        this.cursors = this.input.keyboard.createCursorKeys();
    }

    update() {
        if (this.cursors.left.isDown) {
            this.player.setVelocityX(-160);
        } else if (this.cursors.right.isDown) {
            this.player.setVelocityX(160);
        } else {
            this.player.setVelocityX(0);
        }
    }
}

// Enable Arcade Physics in game config
const config = {
    type: Phaser.AUTO,
    width: 800,
    height: 600,
    physics: {
        default: 'arcade',
        arcade: {
            gravity: { y: 300 },
            debug: false
        }
    },
    scene: GameScene
};

const game = new Phaser.Game(config);
```

## Core Concepts

### World (`this.physics.world`)

The `Phaser.Physics.Arcade.World` manages all bodies in the simulation. Accessed via `this.physics.world` in a Scene.

- **gravity** -- `Vector2` applied to all dynamic bodies each step. Set via config or `this.physics.world.gravity.y = 300`.
- **bounds** -- `Rectangle` defining the world boundary. Defaults to game canvas size.
- **bodies** -- `Set` of all dynamic `Body` instances.
- **staticBodies** -- `Set` of all `StaticBody` instances.
- **colliders** -- `ProcessQueue` of registered `Collider` objects (from `this.physics.add.collider` / `this.physics.add.overlap`).
- **fps** -- Physics steps per second (default 60). Read-only; change via `world.setFPS(120)`.
- **fixedStep** -- `true` (default) uses fixed timestep; `false` syncs to render fps.
- **timeScale** -- Scaling factor: 1.0 = normal, 2.0 = half speed, 0.5 = double speed.
- **isPaused** -- When true, no bodies update and no colliders run. Toggle via `world.pause()` / `world.resume()`.
- **useTree** -- `true` (default) uses RTree spatial index for dynamic bodies. Disable for 5000+ bodies.
- **drawDebug** -- Enables debug rendering when `true`. Set via config `debug: true`.

### Bodies (`Body`)

A dynamic body is created automatically when you use `this.physics.add.sprite()` or `this.physics.add.image()`. Access it via `gameObject.body`.

Key properties (all on `Body`):
- **velocity** -- `Vector2`, pixels/sec
- **acceleration** -- `Vector2`, pixels/sec^2
- **drag** -- `Vector2`, deceleration (applied only when acceleration is zero)
- **gravity** -- `Vector2`, per-body gravity added to world gravity
- **bounce** -- `Vector2`, rebound factor relative to 1
- **friction** -- `Vector2`, default `(1, 0)` -- velocity imparted by immovable body to riding body
- **maxVelocity** -- `Vector2`, default `(10000, 10000)` | **maxSpeed** -- scalar cap, default `-1` (none)
- **mass** -- default `1`, affects collision momentum exchange
- **immovable** -- `false`; if `true`, never moved by collisions
- **pushable** -- `true`; if `false`, reflects velocity to colliding body
- **moves** -- `true`; if `false`, position/rotation not updated by physics
- **enable** -- `true`; `false` removes from simulation
- **useDamping** -- `false`; when `true`, drag is a multiplier (0-1) instead of linear
- **collideWorldBounds** -- `false`; **onWorldBounds/onCollide/onOverlap** -- `false`, set `true` to emit events

Shape: **isCircle** (set via `setCircle`), **width/height**, **offset** (`Vector2`), **center** (read-only midpoint).

Collision state (read-only, reset each step): **touching** / **blocked** / **wasTouching** -- `{ none, up, down, left, right }`. **embedded** -- both overlapping with zero velocity.

Angular: **angularVelocity** (deg/sec), **angularAcceleration**, **angularDrag**, **maxAngular** (default 1000), **allowRotation** (default true).

### Static Bodies (`StaticBody`)

A static body never moves and is not affected by gravity or velocity. It uses an optimized RTree for fast spatial lookups.

- Created via `this.physics.add.staticSprite()`, `this.physics.add.staticImage()`, or `this.physics.add.staticGroup()`.
- After changing the parent Game Object's position or scale, call `body.reset()` or `gameObject.refreshBody()` to sync.
- Has `collisionCategory` and `collisionMask` like dynamic bodies.
- Does not have velocity, acceleration, drag, or gravity properties.

## Common Patterns

### Enabling Physics on Existing Game Objects

```js
// Add a physics body to any existing Game Object
this.physics.add.existing(mySprite);           // dynamic body
this.physics.add.existing(mySprite, true);     // static body

// Or enable via the world directly
this.physics.world.enable(mySprite);           // dynamic
this.physics.world.enable(mySprite, Phaser.Physics.Arcade.STATIC_BODY);
```

### Creating Physics Sprites and Images

```js
// Via the physics factory (this.physics.add)
const player = this.physics.add.sprite(100, 200, 'player');     // dynamic body
const coin = this.physics.add.image(300, 100, 'coin');          // dynamic body
const wall = this.physics.add.staticImage(400, 300, 'wall');    // static body
const platform = this.physics.add.staticSprite(400, 500, 'plat'); // static body

// Standalone bodies (no Game Object)
const sensor = this.physics.add.body(200, 200, 32, 32);        // dynamic Body
const zone = this.physics.add.staticBody(100, 100, 64, 64);    // static Body
```

### Velocity and Gravity

```js
// Direct velocity
player.setVelocity(200, -300);          // x=200 px/s, y=-300 px/s (upward)
player.setVelocityX(200);
player.body.velocity.set(200, -300);    // equivalent via Vector2

// Acceleration + max velocity
player.setAcceleration(100, 0);
player.setMaxVelocity(300, 600);

// Per-body gravity (added to world gravity)
player.body.gravity.y = 200;
player.body.allowGravity = false;       // exempt from world gravity

// Drag (applied only when acceleration is zero)
player.setDrag(300);                    // linear deceleration
player.body.useDamping = true;
player.setDrag(0.05);                   // damping mode: keeps 5% velocity/sec

// Bounce
player.setBounce(0.5);                  // both axes
player.setBounceY(1);                   // full vertical bounce
```

### Collide and Overlap

Two approaches: **persistent Colliders** (checked every frame automatically) or **one-shot checks** (called in `update()`).

```js
// --- Persistent Colliders (preferred) ---
// Created via this.physics.add.collider / this.physics.add.overlap
// Automatically checked every physics step

const collider = this.physics.add.collider(player, platforms);
const overlap = this.physics.add.overlap(player, coins, collectCoin, null, this);

function collectCoin (player, coin) {
    coin.disableBody(true, true); // disable physics and hide
}

// Collider management
collider.active = false;   // temporarily disable
collider.destroy();        // remove permanently

// With processCallback (must return boolean to allow collision)
this.physics.add.collider(player, enemies, o
Files: 1
Size: 22.7 KB
Complexity: 28/100
Category: General

Related in General