physics-arcade

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Arcade Physics

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
本文介绍Phaser 4中Arcade Physics的配置与使用——包括在GameConfig中启用物理系统、创建带物理属性的精灵/图像/组、速度、加速度、重力、碰撞(collide/overlap)、世界边界、物体属性以及碰撞类别。
核心源码路径:
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/
相关指南: ../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);
js
class GameScene extends Phaser.Scene {
    create() {
        // 带物理属性的精灵(动态物体,受重力影响)
        this.player = this.physics.add.sprite(100, 300, 'player');
        this.player.setCollideWorldBounds(true);
        this.player.setBounce(0.2);

        // 静态组(不可移动的平台)
        this.platforms = this.physics.add.staticGroup();
        this.platforms.create(400, 568, 'ground').setScale(2).refreshBody();

        // 注册持久化碰撞器(每帧自动检测)
        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);
        }
    }
}

// 在游戏配置中启用Arcade Physics
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
)

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
    .
Phaser.Physics.Arcade.World
管理模拟中的所有物体。可在Scene中通过
this.physics.world
访问。
  • gravity -- 每步应用于所有动态物体的
    Vector2
    。可通过配置或
    this.physics.world.gravity.y = 300
    设置。
  • bounds -- 定义世界边界的
    Rectangle
    。默认与游戏画布尺寸一致。
  • bodies -- 所有动态
    Body
    实例的
    Set
    集合。
  • staticBodies -- 所有
    StaticBody
    实例的
    Set
    集合。
  • colliders -- 已注册
    Collider
    对象的
    ProcessQueue
    (来自
    this.physics.add.collider
    /
    this.physics.add.overlap
    )。
  • fps -- 每秒物理步数(默认60)。只读;可通过
    world.setFPS(120)
    修改。
  • fixedStep --
    true
    (默认)使用固定时间步长;
    false
    与渲染帧率同步。
  • timeScale -- 缩放因子:1.0 = 正常速度,2.0 = 半速,0.5 = 双倍速度。
  • isPaused -- 设为true时,物体不更新,碰撞器不运行。可通过
    world.pause()
    /
    world.resume()
    切换状态。
  • useTree --
    true
    (默认)为动态物体使用RTree空间索引。当物体数量超过5000时建议禁用。
  • drawDebug -- 设为true时启用调试渲染。可通过配置
    debug: true
    设置。

Bodies (
Body
)

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).
当你使用
this.physics.add.sprite()
this.physics.add.image()
时,会自动创建动态物体。可通过
gameObject.body
访问。
关键属性(均属于
Body
):
  • velocity --
    Vector2
    ,单位:像素/秒
  • acceleration --
    Vector2
    ,单位:像素/秒²
  • drag --
    Vector2
    ,减速值(仅当加速度为0时生效)
  • gravity --
    Vector2
    ,物体自身重力,会叠加到世界重力上
  • bounce --
    Vector2
    ,反弹系数,以1为基准
  • friction --
    Vector2
    ,默认
    (1, 0)
    -- 不可移动物体施加给上方物体的速度
  • maxVelocity --
    Vector2
    ,默认
    (10000, 10000)
    | maxSpeed -- 速度上限标量,默认
    -1
    (无限制)
  • mass -- 默认1,影响碰撞时的动量交换
  • immovable --
    false
    ;设为
    true
    时,碰撞不会使其移动
  • pushable --
    true
    ;设为
    false
    时,会将碰撞物体的速度反弹回去
  • moves --
    true
    ;设为
    false
    时,物理系统不会更新其位置/旋转
  • enable --
    true
    ;设为
    false
    时会从模拟中移除
  • useDamping --
    false
    ;设为
    true
    时,drag是乘数(0-1)而非线性值
  • collideWorldBounds --
    false
    onWorldBounds/onCollide/onOverlap --
    false
    ,设为
    true
    时会触发事件
形状:isCircle(通过
setCircle
设置)、width/heightoffset
Vector2
)、center(只读中点)。
碰撞状态(只读,每步重置):touching / blocked / wasTouching --
{ none, up, down, left, right }
embedded -- 两个物体重叠且速度为0。
旋转属性:angularVelocity(度/秒)、angularAccelerationangularDragmaxAngular(默认1000)、allowRotation(默认true)。

Static Bodies (
StaticBody
)

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.
静态物体不会移动,不受重力或速度影响。它使用优化的RTree实现快速空间查找。
  • 通过
    this.physics.add.staticSprite()
    this.physics.add.staticImage()
    this.physics.add.staticGroup()
    创建。
  • 修改父Game Object的位置或缩放后,需调用
    body.reset()
    gameObject.refreshBody()
    同步状态。
  • 与动态物体一样拥有
    collisionCategory
    collisionMask
    属性。
  • 没有velocity、acceleration、drag或gravity属性。

Common Patterns

常见用法

Enabling Physics on Existing Game Objects

为现有Game Object启用物理系统

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);
js
// 为任意现有Game Object添加物理物体
this.physics.add.existing(mySprite);           // 动态物体
this.physics.add.existing(mySprite, true);     // 静态物体

// 或直接通过world启用
this.physics.world.enable(mySprite);           // 动态
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
js
// 通过物理工厂(this.physics.add)创建
const player = this.physics.add.sprite(100, 200, 'player');     // 动态物体
const coin = this.physics.add.image(300, 100, 'coin');          // 动态物体
const wall = this.physics.add.staticImage(400, 300, 'wall');    // 静态物体
const platform = this.physics.add.staticSprite(400, 500, 'plat'); // 静态物体

// 独立物体(无Game Object)
const sensor = this.physics.add.body(200, 200, 32, 32);        // 动态Body
const zone = this.physics.add.staticBody(100, 100, 64, 64);    // 静态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
js
// 直接设置速度
player.setVelocity(200, -300);          // x=200像素/秒,y=-300像素/秒(向上)
player.setVelocityX(200);
player.body.velocity.set(200, -300);    // 通过Vector2设置,效果相同

// 加速度 + 速度上限
player.setAcceleration(100, 0);
player.setMaxVelocity(300, 600);

// 物体自身重力(叠加到世界重力)
player.body.gravity.y = 200;
player.body.allowGravity = false;       // 不受世界重力影响

// 阻力(仅当加速度为0时生效)
player.setDrag(300);                    // 线性减速
player.body.useDamping = true;
player.setDrag(0.05);                   // 阻尼模式:每秒保留5%的速度

// 反弹
player.setBounce(0.5);                  // 两个轴都设置
player.setBounceY(1);                   // 垂直方向完全反弹

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, onHit, canCollide, this);
function canCollide (player, enemy) {
    return !player.getData('invincible');
}

// --- One-shot checks (in update) ---
// Called manually each frame; no Collider object created

this.physics.collide(player, platforms);
this.physics.overlap(player, coins, collectCoin, null, this);

// Self-collision within a single group
this.physics.add.collider(enemies, enemies);
两种方式:持久化Colliders(每帧自动检测)或单次检测(在
update()
中调用)。
js
// --- 持久化碰撞器(推荐)---
// 通过this.physics.add.collider / this.physics.add.overlap创建
// 每步物理模拟自动检测

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); // 禁用物理并隐藏
}

// 碰撞器管理
collider.active = false;   // 临时禁用
collider.destroy();        // 永久移除

// 带处理回调(需返回布尔值以允许碰撞)
this.physics.add.collider(player, enemies, onHit, canCollide, this);
function canCollide (player, enemy) {
    return !player.getData('invincible');
}

// --- 单次检测(在update中)---
// 每帧手动调用;不会创建Collider对象

this.physics.collide(player, platforms);
this.physics.overlap(player, coins, collectCoin, null, this);

// 组内物体自碰撞
this.physics.add.collider(enemies, enemies);

Groups

物理组

js
// Dynamic physics group -- members get dynamic bodies automatically
const bullets = this.physics.add.group({
    classType: Phaser.Physics.Arcade.Sprite,  // default: ArcadeSprite
    maxSize: 20,
    collideWorldBounds: true,
    bounceX: 1,
    bounceY: 1,
    velocityX: 200,
    velocityY: 0,
    allowGravity: false,
    immovable: false
});

// Static physics group -- members get static bodies
const platforms = this.physics.add.staticGroup();
platforms.create(400, 568, 'ground');
platforms.create(600, 400, 'ground');

// After modifying a static group member's transform, refresh:
platforms.create(400, 568, 'ground').setScale(2).refreshBody();

// Group velocity helpers
bullets.setVelocity(200, 0);       // all members
bullets.setVelocityX(200);
bullets.setVelocityY(0, 10);       // with step increment per member
PhysicsGroup config keys (applied as defaults to new members):
collideWorldBounds
,
bounceX/Y
,
accelerationX/Y
,
dragX/Y
,
gravityX/Y
,
frictionX/Y
,
velocityX/Y
,
angularVelocity
,
angularAcceleration
,
angularDrag
,
maxVelocityX/Y
,
maxSpeed
,
mass
,
immovable
,
allowDrag
,
allowGravity
,
allowRotation
,
useDamping
,
enable
.
js
// 动态物理组 -- 成员自动获得动态物体
const bullets = this.physics.add.group({
    classType: Phaser.Physics.Arcade.Sprite,  // 默认:ArcadeSprite
    maxSize: 20,
    collideWorldBounds: true,
    bounceX: 1,
    bounceY: 1,
    velocityX: 200,
    velocityY: 0,
    allowGravity: false,
    immovable: false
});

// 静态物理组 -- 成员自动获得静态物体
const platforms = this.physics.add.staticGroup();
platforms.create(400, 568, 'ground');
platforms.create(600, 400, 'ground');

// 修改静态组成员的变换后,需刷新:
platforms.create(400, 568, 'ground').setScale(2).refreshBody();

// 组速度辅助方法
bullets.setVelocity(200, 0);       // 所有成员
bullets.setVelocityX(200);
bullets.setVelocityY(0, 10);       // 每个成员的Y速度递增10
PhysicsGroup配置项(作为新成员的默认值):
collideWorldBounds
,
bounceX/Y
,
accelerationX/Y
,
dragX/Y
,
gravityX/Y
,
frictionX/Y
,
velocityX/Y
,
angularVelocity
,
angularAcceleration
,
angularDrag
,
maxVelocityX/Y
,
maxSpeed
,
mass
,
immovable
,
allowDrag
,
allowGravity
,
allowRotation
,
useDamping
,
enable
.

World Bounds

世界边界

js
// Set bounds size and which edges collide (left, right, up, down)
this.physics.world.setBounds(0, 0, 1600, 1200, true, true, false, true);
this.physics.world.setBoundsCollision(true, true, false, true); // edges only

// Per-body world bounds
player.setCollideWorldBounds(true);
player.body.setBoundsRectangle(new Phaser.Geom.Rectangle(100, 100, 600, 400));
player.body.worldBounce = new Phaser.Math.Vector2(0.5, 0.5);

// Detect world bounds hit via event (requires opt-in)
player.body.onWorldBounds = true;
this.physics.world.on('worldbounds', (body, up, down, left, right) => {
    console.log('Hit edge:', { up, down, left, right });
});
js
// 设置边界尺寸及可碰撞的边缘(左、右、上、下)
this.physics.world.setBounds(0, 0, 1600, 1200, true, true, false, true);
this.physics.world.setBoundsCollision(true, true, false, true); // 仅设置边缘碰撞

// 单个物体的世界边界
player.setCollideWorldBounds(true);
player.body.setBoundsRectangle(new Phaser.Geom.Rectangle(100, 100, 600, 400));
player.body.worldBounce = new Phaser.Math.Vector2(0.5, 0.5);

// 通过事件检测边界碰撞(需手动开启)
player.body.onWorldBounds = true;
this.physics.world.on('worldbounds', (body, up, down, left, right) => {
    console.log('碰撞边缘:', { up, down, left, right });
});

Body Properties

物体属性

js
// Size and shape
player.body.setSize(24, 32, true);     // width, height, re-center on GO
player.body.setOffset(4, 0);           // offset from GO position
player.body.setCircle(16);             // circular body, radius 16
player.body.setCircle(16, 4, 4);       // circular with offset

// Collision behavior
player.body.setImmovable(true);        // not moved by collisions
player.body.setPushable(false);        // reflects velocity to collider
player.body.slideFactor.set(0, 0);     // Sokoban-style: stops after push
player.body.setMass(2);               // affects momentum exchange

// Enable / disable
player.disableBody(true, true);        // disable body + hide Game Object
player.enableBody(true, x, y, true, true); // re-enable at position + show

// Per-direction collision check
player.body.checkCollision.up = false; // don't collide from above
player.body.syncBounds = true;         // auto-sync size to texture
js
// 尺寸与形状
player.body.setSize(24, 32, true);     // 宽度、高度、是否相对于Game Object居中
player.body.setOffset(4, 0);           // 相对于Game Object的偏移
player.body.setCircle(16);             // 圆形物体,半径16
player.body.setCircle(16, 4, 4);       // 带偏移的圆形物体

// 碰撞行为
player.body.setImmovable(true);        // 碰撞时不会被移动
player.body.setPushable(false);        // 将碰撞物体的速度反弹回去
player.body.slideFactor.set(0, 0);     // 推箱子风格:推动后停止
player.body.setMass(2);               // 影响动量交换

// 启用/禁用
player.disableBody(true, true);        // 禁用物体并隐藏Game Object
player.enableBody(true, x, y, true, true); // 在指定位置重新启用并显示

// 分方向碰撞检测
player.body.checkCollision.up = false; // 不与上方物体碰撞
player.body.syncBounds = true;         // 自动同步尺寸到纹理

Collision Categories

碰撞类别

Collision categories let you filter which bodies can collide with each other using bitmask values. Maximum 32 categories.
js
// Get unique category values from the physics plugin
const CAT_PLAYER = this.physics.nextCategory();   // 0x0002
const CAT_ENEMY  = this.physics.nextCategory();   // 0x0004
const CAT_BULLET = this.physics.nextCategory();   // 0x0008

// Assign categories to bodies or groups
player.setCollisionCategory(CAT_PLAYER);
enemy.setCollisionCategory(CAT_ENEMY);
bullet.setCollisionCategory(CAT_BULLET);

// Set what each body collides with
player.setCollidesWith([CAT_ENEMY]);              // player hits enemies only
enemy.setCollidesWith([CAT_PLAYER, CAT_BULLET]);  // enemies hit player + bullets
bullet.setCollidesWith([CAT_ENEMY]);              // bullets hit enemies only

// Add/remove individual categories from existing mask
player.addCollidesWith(CAT_BULLET);
player.removeCollidesWith(CAT_ENEMY);

// Check if a body will collide with a category
player.willCollideWith(CAT_ENEMY); // returns boolean

// Reset to default (collides with everything)
player.resetCollisionCategory();

// Works on Groups too
enemies.setCollisionCategory(CAT_ENEMY);
enemies.setCollidesWith([CAT_PLAYER, CAT_BULLET]);
Default: all bodies have category
0x0001
and collisionMask
1
. Everything still collides with everything because
(1 & 1) !== 0
. PhysicsGroup defaults to mask
2147483647
(all bits). Call
resetCollisionCategory()
to set the mask to all bits after changing categories.
碰撞类别使用位掩码值过滤哪些物体可以相互碰撞,最多支持32个类别。
js
// 从物理插件获取唯一的类别值
const CAT_PLAYER = this.physics.nextCategory();   // 0x0002
const CAT_ENEMY  = this.physics.nextCategory();   // 0x0004
const CAT_BULLET = this.physics.nextCategory();   // 0x0008

// 为物体或组分配类别
player.setCollisionCategory(CAT_PLAYER);
enemy.setCollisionCategory(CAT_ENEMY);
bullet.setCollisionCategory(CAT_BULLET);

// 设置每个物体可碰撞的类别
player.setCollidesWith([CAT_ENEMY]);              // 玩家仅与敌人碰撞
enemy.setCollidesWith([CAT_PLAYER, CAT_BULLET]);  // 敌人与玩家、子弹碰撞
bullet.setCollidesWith([CAT_ENEMY]);              // 子弹仅与敌人碰撞

// 在现有掩码中添加/移除单个类别
player.addCollidesWith(CAT_BULLET);
player.removeCollidesWith(CAT_ENEMY);

// 检查物体是否会与某个类别碰撞
player.willCollideWith(CAT_ENEMY); // 返回布尔值

// 重置为默认(与所有物体碰撞)
player.resetCollisionCategory();

// 组也适用
enemies.setCollisionCategory(CAT_ENEMY);
enemies.setCollidesWith([CAT_PLAYER, CAT_BULLET]);
默认值:所有物体的类别为
0x0001
,碰撞掩码为1。因为
(1 & 1) !== 0
,所以所有物体仍会相互碰撞。PhysicsGroup默认掩码为
2147483647
(所有位)。修改类别后,调用
resetCollisionCategory()
可将掩码设置为所有位。

Configuration Reference

配置参考

ArcadeWorldConfig
-- passed via
physics.arcade
in GameConfig or SceneConfig:
PropertyDefaultDescription
fps
60
Physics steps per second
fixedStep
true
Use fixed timestep vs render sync
timeScale
1
Simulation speed multiplier
gravity
{ x: 0, y: 0 }
World gravity in px/sec
x
,
y
0
World bounds origin
width
,
height
game sizeWorld bounds dimensions
checkCollision
all
true
{ up, down, left, right }
edge collision
overlapBias
4
Overlap threshold for separation
tileBias
16
Tile overlap threshold
forceX
false
Separate horizontally first
isPaused
false
Start simulation paused
debug
false
Enable debug rendering
debugShowBody
/
debugShowStaticBody
/
debugShowVelocity
true
Debug display toggles
debugBodyColor
/
debugStaticBodyColor
/
debugVelocityColor
0xff00ff
/
0x0000ff
/
0x00ff00
Debug colors
maxEntries
16
RTree items per node
useTree
true
Use RTree for dynamic bodies
customUpdate
false
If true, call
world.update()
yourself
Scene-level config overrides game-level config (merged).
ArcadeWorldConfig
-- 通过GameConfig或SceneConfig中的
physics.arcade
传入:
属性默认值描述
fps
60
每秒物理步数
fixedStep
true
使用固定时间步长还是与渲染同步
timeScale
1
模拟速度乘数
gravity
{ x: 0, y: 0 }
世界重力,单位:像素/秒
x
,
y
0
世界边界原点
width
,
height
游戏尺寸世界边界尺寸
checkCollision
全为
true
{ up, down, left, right }
边缘碰撞设置
overlapBias
4
分离时的重叠阈值
tileBias
16
瓦片重叠阈值
forceX
false
优先水平分离
isPaused
false
启动时模拟是否暂停
debug
false
启用调试渲染
debugShowBody
/
debugShowStaticBody
/
debugShowVelocity
true
调试显示开关
debugBodyColor
/
debugStaticBodyColor
/
debugVelocityColor
0xff00ff
/
0x0000ff
/
0x00ff00
调试颜色
maxEntries
16
RTree每个节点的条目数
useTree
true
为动态物体使用RTree
customUpdate
false
设为true时,需手动调用
world.update()
场景级配置会覆盖游戏级配置(合并生效)。

Events

事件

All events are emitted on
this.physics.world
:
EventStringConditionCallback Args
COLLIDE
'collide'
Two bodies collide and at least one has
onCollide = true
(gameObject1, gameObject2, body1, body2)
OVERLAP
'overlap'
Two bodies overlap and at least one has
onOverlap = true
(gameObject1, gameObject2, body1, body2)
WORLD_BOUNDS
'worldbounds'
Body hits world edge and has
onWorldBounds = true
(body, up, down, left, right)
TILE_COLLIDE
'tilecollide'
Body collides with a tile
(gameObject, tile, body)
TILE_OVERLAP
'tileoverlap'
Body overlaps a tile
(gameObject, tile, body)
WORLD_STEP
'worldstep'
After each physics step
(delta)
PAUSE
'pause'
World pausednone
RESUME
'resume'
World resumednone
Events require opt-in per body: set
body.onCollide
,
body.onOverlap
, or
body.onWorldBounds
to
true
.
所有事件均在
this.physics.world
上触发:
事件字符串触发条件回调参数
COLLIDE
'collide'
两个物体碰撞,且至少一个物体的
onCollide = true
(gameObject1, gameObject2, body1, body2)
OVERLAP
'overlap'
两个物体重叠,且至少一个物体的
onOverlap = true
(gameObject1, gameObject2, body1, body2)
WORLD_BOUNDS
'worldbounds'
物体碰撞世界边缘,且
onWorldBounds = true
(body, up, down, left, right)
TILE_COLLIDE
'tilecollide'
物体与瓦片碰撞
(gameObject, tile, body)
TILE_OVERLAP
'tileoverlap'
物体与瓦片重叠
(gameObject, tile, body)
WORLD_STEP
'worldstep'
每步物理模拟后
(delta)
PAUSE
'pause'
世界暂停时
RESUME
'resume'
世界恢复时
事件需要物体手动开启:将
body.onCollide
body.onOverlap
body.onWorldBounds
设为
true

API Quick Reference

API速查

Scene Plugin (
this.physics
)

场景插件(
this.physics

MethodDescription
this.physics.add.sprite(x, y, key, frame)
Create sprite with dynamic body
this.physics.add.image(x, y, key, frame)
Create image with dynamic body
this.physics.add.staticSprite(x, y, key, frame)
Sprite with static body
this.physics.add.staticImage(x, y, key, frame)
Image with static body
this.physics.add.group(config)
Dynamic physics group
this.physics.add.staticGroup(config)
Static physics group
this.physics.add.existing(go, isStatic?)
Add body to existing Game Object
this.physics.add.body(x, y, w?, h?)
Standalone dynamic Body (no GO)
this.physics.add.staticBody(x, y, w?, h?)
Standalone static Body (no GO)
this.physics.add.collider(a, b, cb?, proc?, ctx?)
Persistent collider
this.physics.add.overlap(a, b, cb?, proc?, ctx?)
Persistent overlap
this.physics.collide(a, b, cb?, proc?, ctx?)
One-shot collision check
this.physics.overlap(a, b, cb?, proc?, ctx?)
One-shot overlap check
this.physics.nextCategory()
Next collision category bitmask
this.physics.pause()
/
resume()
Pause/resume simulation
this.physics.accelerateTo(go, x, y, spd?, maxX?, maxY?)
Accelerate toward point
this.physics.moveTo(go, x, y, spd?, maxTime?)
Move toward point at speed
this.physics.velocityFromAngle(angle, speed?, vec2?)
Angle (deg) to velocity
this.physics.velocityFromRotation(rot, speed?, vec2?)
Rotation (rad) to velocity
this.physics.closest(source, targets?)
Find nearest body
this.physics.furthest(source, targets?)
Find farthest body
this.physics.overlapRect(x, y, w, h, dyn?, static?)
Query bodies in rectangle
this.physics.overlapCirc(x, y, r, dyn?, static?)
Query bodies in circle
Also:
accelerateToObject
,
moveToObject
,
collideTiles
,
overlapTiles
,
enableUpdate
,
disableUpdate
.
方法描述
this.physics.add.sprite(x, y, key, frame)
创建带动态物体的精灵
this.physics.add.image(x, y, key, frame)
创建带动态物体的图像
this.physics.add.staticSprite(x, y, key, frame)
创建带静态物体的精灵
this.physics.add.staticImage(x, y, key, frame)
创建带静态物体的图像
this.physics.add.group(config)
创建动态物理组
this.physics.add.staticGroup(config)
创建静态物理组
this.physics.add.existing(go, isStatic?)
为现有Game Object添加物理物体
this.physics.add.body(x, y, w?, h?)
创建独立动态Body(无Game Object)
this.physics.add.staticBody(x, y, w?, h?)
创建独立静态Body(无Game Object)
this.physics.add.collider(a, b, cb?, proc?, ctx?)
创建持久化碰撞器
this.physics.add.overlap(a, b, cb?, proc?, ctx?)
创建持久化重叠检测器
this.physics.collide(a, b, cb?, proc?, ctx?)
单次碰撞检测
this.physics.overlap(a, b, cb?, proc?, ctx?)
单次重叠检测
this.physics.nextCategory()
获取下一个碰撞类别位掩码
this.physics.pause()
/
resume()
暂停/恢复模拟
this.physics.accelerateTo(go, x, y, spd?, maxX?, maxY?)
向指定点加速
this.physics.moveTo(go, x, y, spd?, maxTime?)
以指定速度向指定点移动
this.physics.velocityFromAngle(angle, speed?, vec2?)
将角度(度)转换为速度
this.physics.velocityFromRotation(rot, speed?, vec2?)
将旋转(弧度)转换为速度
this.physics.closest(source, targets?)
查找最近的物体
this.physics.furthest(source, targets?)
查找最远的物体
this.physics.overlapRect(x, y, w, h, dyn?, static?)
查询矩形区域内的物体
this.physics.overlapCirc(x, y, r, dyn?, static?)
查询圆形区域内的物体
其他方法:
accelerateToObject
,
moveToObject
,
collideTiles
,
overlapTiles
,
enableUpdate
,
disableUpdate

World (
this.physics.world
)

World(
this.physics.world

MethodDescription
setBounds(x, y, w, h, left?, right?, up?, down?)
Set boundary + edge checks
setBoundsCollision(left?, right?, up?, down?)
Set which edges collide
setFPS(framerate)
Change physics step rate
enable(object, bodyType?)
Enable physics on object/group/array
disable(object)
Disable physics on object/group/array
add(body)
/
remove(body)
Add/remove Body from simulation
addCollider
/
addOverlap
Create Collider (same args as factory)
removeCollider(collider)
Remove Collider
pause()
/
resume()
Pause/resume simulation
createDebugGraphic()
Create debug rendering graphic
方法描述
setBounds(x, y, w, h, left?, right?, up?, down?)
设置边界及边缘碰撞检测
setBoundsCollision(left?, right?, up?, down?)
设置可碰撞的边缘
setFPS(framerate)
修改物理步频
enable(object, bodyType?)
为物体/组/数组启用物理系统
disable(object)
为物体/组/数组禁用物理系统
add(body)
/
remove(body)
向模拟中添加/移除Body
addCollider
/
addOverlap
创建Collider(参数与工厂方法相同)
removeCollider(collider)
移除Collider
pause()
/
resume()
暂停/恢复模拟
createDebugGraphic()
创建调试渲染图形

Body Methods

Body方法

MethodDescription
setVelocity(x, y)
/
setVelocityX
/
setVelocityY
Set velocity
setAcceleration(x, y)
/
setAccelerationX
/
Y
Set acceleration
setMaxVelocity(x, y)
/
setMaxSpeed(speed)
Velocity caps
setBounce(x, y)
/
setDrag(x, y)
Bounce and drag
setDamping(bool)
Enable damping mode
setFriction(x, y)
/
setGravity(x, y)
Friction and per-body gravity
setMass(val)
/
setImmovable(bool)
/
setPushable(bool)
Mass and collision behavior
setSize(w, h, center?)
/
setOffset(x, y)
Resize/offset body
setCircle(radius, offX?, offY?)
Switch to circular body
setCollideWorldBounds(val, bX?, bY?)
World bounds collision
setBoundsRectangle(rect)
Custom bounds rectangle
setAllowGravity
/
setAllowDrag
/
setAllowRotation
Toggle physics features
setEnable(val)
Enable/disable body
setCollisionCategory
/
setCollidesWith
/
addCollidesWith
/
removeCollidesWith
Category filtering
resetCollisionCategory()
Reset to default (all)
reset(x, y)
/
stop()
Reset position or zero velocity
方法描述
setVelocity(x, y)
/
setVelocityX
/
setVelocityY
设置速度
setAcceleration(x, y)
/
setAccelerationX
/
Y
设置加速度
setMaxVelocity(x, y)
/
setMaxSpeed(speed)
设置速度上限
setBounce(x, y)
/
setDrag(x, y)
设置反弹和阻力
setDamping(bool)
启用阻尼模式
setFriction(x, y)
/
setGravity(x, y)
设置摩擦力和物体自身重力
setMass(val)
/
setImmovable(bool)
/
setPushable(bool)
设置质量和碰撞行为
setSize(w, h, center?)
/
setOffset(x, y)
调整物体尺寸/偏移
setCircle(radius, offX?, offY?)
切换为圆形物体
setCollideWorldBounds(val, bX?, bY?)
设置世界边界碰撞
setBoundsRectangle(rect)
设置自定义边界矩形
setAllowGravity
/
setAllowDrag
/
setAllowRotation
切换物理特性
setEnable(val)
启用/禁用物体
setCollisionCategory
/
setCollidesWith
/
addCollidesWith
/
removeCollidesWith
设置类别过滤
resetCollisionCategory()
重置为默认(与所有物体碰撞)
reset(x, y)
/
stop()
重置位置或归零速度

Gotchas

注意事项

  1. debug: true
    in production
    -- Debug rendering is expensive. Always disable for release builds.
  2. Static body transform changes -- After changing position, scale, or origin of a static body's Game Object, you must call
    body.reset()
    or
    gameObject.refreshBody()
    . Static bodies do not auto-sync.
  3. collide
    vs
    overlap
    --
    collide
    performs separation (pushes bodies apart).
    overlap
    only detects intersection without moving anything. Use
    overlap
    for triggers like pickups.
  4. Persistent Collider vs one-shot --
    this.physics.add.collider()
    creates a Collider checked every frame automatically.
    this.physics.collide()
    is a one-shot check that must be called each frame in
    update()
    . Prefer persistent Colliders.
  5. Events require opt-in -- World events (
    'collide'
    ,
    'overlap'
    ,
    'worldbounds'
    ) only fire if the relevant body property (
    onCollide
    ,
    onOverlap
    ,
    onWorldBounds
    ) is set to
    true
    .
  6. Collision categories default -- By default all bodies have category
    0x0001
    and mask
    1
    (PhysicsGroup defaults to mask
    2147483647
    ). Call
    this.physics.nextCategory()
    to get new category values; max 32 categories total. After changing categories, use
    resetCollisionCategory()
    to set the mask to all bits.
  7. Group defaults only apply at creation -- PhysicsGroup
    defaults
    (like
    velocityX
    ,
    bounceY
    ) are applied when a member is added/created. Changing
    defaults
    later does not retroactively update existing members.
  8. customUpdate
    config
    -- Setting
    customUpdate: true
    in the arcade config stops the world from auto-updating on the Scene UPDATE event. You must call
    this.physics.world.update(time, delta)
    manually.
  9. useDamping
    drag values
    -- When
    useDamping
    is
    true
    , drag values should be small (e.g.,
    0.05
    ) as they act as a multiplier. A value of
    0.05
    means the body keeps 5% of its velocity per second.
  10. Immovable vs pushable --
    immovable = true
    means the body is never moved by collisions at all.
    pushable = false
    means the body reflects velocity back to the colliding body but can still be separated.
  11. Overlap with TilemapLayer -- When using
    overlapOnly
    with a TilemapLayer, every tile is checked regardless of collision settings on individual tiles.
  12. RTree threshold -- The RTree spatial index (enabled by default) becomes expensive to rebuild with very large numbers of dynamic bodies. Consider setting
    useTree: false
    for 5000+ dynamic bodies.
  1. 生产环境中禁用
    debug: true
    -- 调试渲染性能开销大,发布版本务必禁用。
  2. 静态物体变换更新 -- 修改静态物体所属Game Object的位置、缩放或原点后,必须调用
    body.reset()
    gameObject.refreshBody()
    。静态物体不会自动同步状态。
  3. collide
    overlap
    的区别
    --
    collide
    会执行分离(将物体推开)。
    overlap
    仅检测相交,不会移动物体。拾取道具等触发场景建议使用
    overlap
  4. 持久化碰撞器与单次检测 --
    this.physics.add.collider()
    创建的Collider会每帧自动检测。
    this.physics.collide()
    是单次检测,需在
    update()
    中每帧调用。优先使用持久化碰撞器。
  5. 事件需手动开启 -- 世界事件(
    'collide'
    'overlap'
    'worldbounds'
    )仅在对应物体属性(
    onCollide
    onOverlap
    onWorldBounds
    )设为
    true
    时触发。
  6. 碰撞类别默认值 -- 默认所有物体的类别为
    0x0001
    ,掩码为1(PhysicsGroup默认掩码为
    2147483647
    )。调用
    this.physics.nextCategory()
    获取新类别值;最多支持32个类别。修改类别后,使用
    resetCollisionCategory()
    将掩码设置为所有位。
  7. 组默认值仅在创建时生效 -- PhysicsGroup的默认配置(如
    velocityX
    bounceY
    )仅在成员添加/创建时应用。后续修改默认配置不会更新现有成员。
  8. customUpdate
    配置
    -- 在arcade配置中设置
    customUpdate: true
    会停止世界在Scene UPDATE事件中自动更新。需手动调用
    this.physics.world.update(time, delta)
  9. useDamping
    模式下的drag值
    -- 当
    useDamping
    设为
    true
    时,drag值应设为较小值(如
    0.05
    ),因为它作为乘数生效。值为0.05表示物体每秒保留5%的速度。
  10. Immovable与Pushable的区别 --
    immovable = true
    表示物体完全不会因碰撞移动。
    pushable = false
    表示物体会反弹碰撞物体的速度,但仍会被分离。
  11. 与TilemapLayer的重叠检测 -- 对TilemapLayer使用
    overlapOnly
    时,无论单个瓦片的碰撞设置如何,所有瓦片都会被检测。
  12. RTree阈值 -- 默认启用的RTree空间索引在动态物体数量极多时重建开销会变大。当动态物体超过5000个时,建议设置
    useTree: false

Source File Map

源码文件映射

FilePurpose
src/physics/arcade/ArcadePhysics.js
Scene plugin (
this.physics
) -- collide, overlap, moveTo, accelerateTo, nextCategory
src/physics/arcade/World.js
Physics world -- bodies, gravity, bounds, colliders, step loop, setBounds, addCollider
src/physics/arcade/Body.js
Dynamic body -- velocity, acceleration, bounce, drag, gravity, mass, immovable, pushable
src/physics/arcade/StaticBody.js
Static body -- immovable, no velocity, optimized RTree lookup
src/physics/arcade/Factory.js
this.physics.add
-- sprite, image, group, staticGroup, body, existing, collider, overlap
src/physics/arcade/Collider.js
Collider object -- persistent collision/overlap check with callbacks
src/physics/arcade/PhysicsGroup.js
Dynamic physics group with per-member defaults
src/physics/arcade/StaticPhysicsGroup.js
Static physics group with auto-refresh
src/physics/arcade/components/index.js
Body component mixins -- Acceleration, Angular, Bounce, Collision, Debug, Drag, Enable, Friction, Gravity, Immovable, Mass, Pushable, Size, Velocity
src/physics/arcade/components/Collision.js
Collision category/mask methods -- setCollisionCategory, setCollidesWith, addCollidesWith, removeCollidesWith
src/physics/arcade/events/
Event constants -- COLLIDE, OVERLAP, WORLD_BOUNDS, TILE_COLLIDE, TILE_OVERLAP, WORLD_STEP, PAUSE, RESUME
src/physics/arcade/typedefs/ArcadeWorldConfig.js
TypeDef for arcade physics config options
文件用途
src/physics/arcade/ArcadePhysics.js
场景插件(
this.physics
)-- collide、overlap、moveTo、accelerateTo、nextCategory等方法
src/physics/arcade/World.js
物理世界 -- 物体管理、重力、边界、碰撞器、步循环、setBounds、addCollider等
src/physics/arcade/Body.js
动态物体 -- 速度、加速度、反弹、阻力、重力、质量、immovable、pushable等属性
src/physics/arcade/StaticBody.js
静态物体 -- 不可移动、无速度、优化的RTree查找
src/physics/arcade/Factory.js
this.physics.add
-- sprite、image、group、staticGroup、body、existing、collider、overlap等创建方法
src/physics/arcade/Collider.js
Collider对象 -- 带回调的持久化碰撞/重叠检测
src/physics/arcade/PhysicsGroup.js
带成员默认配置的动态物理组
src/physics/arcade/StaticPhysicsGroup.js
带自动刷新的静态物理组
src/physics/arcade/components/index.js
Body组件混入 -- Acceleration、Angular、Bounce、Collision、Debug、Drag、Enable、Friction、Gravity、Immovable、Mass、Pushable、Size、Velocity
src/physics/arcade/components/Collision.js
碰撞类别/掩码方法 -- setCollisionCategory、setCollidesWith、addCollidesWith、removeCollidesWith
src/physics/arcade/events/
事件常量 -- COLLIDE、OVERLAP、WORLD_BOUNDS、TILE_COLLIDE、TILE_OVERLAP、WORLD_STEP、PAUSE、RESUME
src/physics/arcade/typedefs/ArcadeWorldConfig.js
Arcade物理配置选项的类型定义