physics-arcade
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseArcade 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: , , , , , ,
Related skills: ../game-setup-and-config/SKILL.md, ../sprites-and-images/SKILL.md, ../tilemaps/SKILL.md, ../groups-and-containers/SKILL.md
src/physics/arcade/ArcadePhysics.jssrc/physics/arcade/World.jssrc/physics/arcade/Body.jssrc/physics/arcade/StaticBody.jssrc/physics/arcade/Factory.jssrc/physics/arcade/components/src/physics/arcade/events/本文介绍Phaser 4中Arcade Physics的配置与使用——包括在GameConfig中启用物理系统、创建带物理属性的精灵/图像/组、速度、加速度、重力、碰撞(collide/overlap)、世界边界、物体属性以及碰撞类别。
核心源码路径: , , , , , ,
相关指南: ../game-setup-and-config/SKILL.md, ../sprites-and-images/SKILL.md, ../tilemaps/SKILL.md, ../groups-and-containers/SKILL.md
src/physics/arcade/ArcadePhysics.jssrc/physics/arcade/World.jssrc/physics/arcade/Body.jssrc/physics/arcade/StaticBody.jssrc/physics/arcade/Factory.jssrc/physics/arcade/components/src/physics/arcade/events/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
)
this.physics.worldWorld(this.physics.world
)
this.physics.worldThe manages all bodies in the simulation. Accessed via in a Scene.
Phaser.Physics.Arcade.Worldthis.physics.world- gravity -- applied to all dynamic bodies each step. Set via config or
Vector2.this.physics.world.gravity.y = 300 - bounds -- defining the world boundary. Defaults to game canvas size.
Rectangle - bodies -- of all dynamic
Setinstances.Body - staticBodies -- of all
Setinstances.StaticBody - colliders -- of registered
ProcessQueueobjects (fromCollider/this.physics.add.collider).this.physics.add.overlap - fps -- Physics steps per second (default 60). Read-only; change via .
world.setFPS(120) - fixedStep -- (default) uses fixed timestep;
truesyncs to render fps.false - 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 -- (default) uses RTree spatial index for dynamic bodies. Disable for 5000+ bodies.
true - drawDebug -- Enables debug rendering when . Set via config
true.debug: true
Phaser.Physics.Arcade.Worldthis.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 -- (默认)为动态物体使用RTree空间索引。当物体数量超过5000时建议禁用。
true - drawDebug -- 设为true时启用调试渲染。可通过配置设置。
debug: true
Bodies (Body
)
BodyBodies(Body
)
BodyA dynamic body is created automatically when you use or . Access it via .
this.physics.add.sprite()this.physics.add.image()gameObject.bodyKey properties (all on ):
Body- velocity -- , pixels/sec
Vector2 - acceleration -- , pixels/sec^2
Vector2 - drag -- , deceleration (applied only when acceleration is zero)
Vector2 - gravity -- , per-body gravity added to world gravity
Vector2 - bounce -- , rebound factor relative to 1
Vector2 - friction -- , default
Vector2-- velocity imparted by immovable body to riding body(1, 0) - maxVelocity -- , default
Vector2| maxSpeed -- scalar cap, default(10000, 10000)(none)-1 - mass -- default , affects collision momentum exchange
1 - immovable -- ; if
false, never moved by collisionstrue - pushable -- ; if
true, reflects velocity to colliding bodyfalse - moves -- ; if
true, position/rotation not updated by physicsfalse - enable -- ;
trueremoves from simulationfalse - useDamping -- ; when
false, drag is a multiplier (0-1) instead of lineartrue - collideWorldBounds -- ; onWorldBounds/onCollide/onOverlap --
false, setfalseto emit eventstrue
Shape: isCircle (set via ), width/height, offset (), center (read-only midpoint).
setCircleVector2Collision state (read-only, reset each step): touching / blocked / wasTouching -- . embedded -- both overlapping with zero velocity.
{ none, up, down, left, right }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 -- ,减速值(仅当加速度为0时生效)
Vector2 - gravity -- ,物体自身重力,会叠加到世界重力上
Vector2 - bounce -- ,反弹系数,以1为基准
Vector2 - friction -- ,默认
Vector2-- 不可移动物体施加给上方物体的速度(1, 0) - maxVelocity -- ,默认
Vector2| maxSpeed -- 速度上限标量,默认(10000, 10000)(无限制)-1 - mass -- 默认1,影响碰撞时的动量交换
- immovable -- ;设为
false时,碰撞不会使其移动true - pushable -- ;设为
true时,会将碰撞物体的速度反弹回去false - moves -- ;设为
true时,物理系统不会更新其位置/旋转false - enable -- ;设为
true时会从模拟中移除false - useDamping -- ;设为
false时,drag是乘数(0-1)而非线性值true - collideWorldBounds -- ;onWorldBounds/onCollide/onOverlap --
false,设为false时会触发事件true
形状:isCircle(通过设置)、width/height、offset()、center(只读中点)。
setCircleVector2碰撞状态(只读,每步重置):touching / blocked / wasTouching -- 。embedded -- 两个物体重叠且速度为0。
{ none, up, down, left, right }旋转属性:angularVelocity(度/秒)、angularAcceleration、angularDrag、maxAngular(默认1000)、allowRotation(默认true)。
Static Bodies (StaticBody
)
StaticBodyStatic Bodies(StaticBody
)
StaticBodyA 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(), orthis.physics.add.staticImage().this.physics.add.staticGroup() - After changing the parent Game Object's position or scale, call or
body.reset()to sync.gameObject.refreshBody() - Has and
collisionCategorylike dynamic bodies.collisionMask - 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 Bodyjs
// 通过物理工厂(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); // 静态BodyVelocity 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 bouncejs
// 直接设置速度
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 memberPhysicsGroup config keys (applied as defaults to new members): , , , , , , , , , , , , , , , , , , .
collideWorldBoundsbounceX/YaccelerationX/YdragX/YgravityX/YfrictionX/YvelocityX/YangularVelocityangularAccelerationangularDragmaxVelocityX/YmaxSpeedmassimmovableallowDragallowGravityallowRotationuseDampingenablejs
// 动态物理组 -- 成员自动获得动态物体
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速度递增10PhysicsGroup配置项(作为新成员的默认值):, , , , , , , , , , , , , , , , , , .
collideWorldBoundsbounceX/YaccelerationX/YdragX/YgravityX/YfrictionX/YvelocityX/YangularVelocityangularAccelerationangularDragmaxVelocityX/YmaxSpeedmassimmovableallowDragallowGravityallowRotationuseDampingenableWorld 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 texturejs
// 尺寸与形状
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 and collisionMask . Everything still collides with everything because . PhysicsGroup defaults to mask (all bits). Call to set the mask to all bits after changing categories.
0x00011(1 & 1) !== 02147483647resetCollisionCategory()碰撞类别使用位掩码值过滤哪些物体可以相互碰撞,最多支持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]);默认值:所有物体的类别为,碰撞掩码为1。因为,所以所有物体仍会相互碰撞。PhysicsGroup默认掩码为(所有位)。修改类别后,调用可将掩码设置为所有位。
0x0001(1 & 1) !== 02147483647resetCollisionCategory()Configuration Reference
配置参考
ArcadeWorldConfigphysics.arcade| Property | Default | Description |
|---|---|---|
| | Physics steps per second |
| | Use fixed timestep vs render sync |
| | Simulation speed multiplier |
| | World gravity in px/sec |
| | World bounds origin |
| game size | World bounds dimensions |
| all | |
| | Overlap threshold for separation |
| | Tile overlap threshold |
| | Separate horizontally first |
| | Start simulation paused |
| | Enable debug rendering |
| | Debug display toggles |
| | Debug colors |
| | RTree items per node |
| | Use RTree for dynamic bodies |
| | If true, call |
Scene-level config overrides game-level config (merged).
ArcadeWorldConfigphysics.arcade| 属性 | 默认值 | 描述 |
|---|---|---|
| | 每秒物理步数 |
| | 使用固定时间步长还是与渲染同步 |
| | 模拟速度乘数 |
| | 世界重力,单位:像素/秒 |
| | 世界边界原点 |
| 游戏尺寸 | 世界边界尺寸 |
| 全为 | |
| | 分离时的重叠阈值 |
| | 瓦片重叠阈值 |
| | 优先水平分离 |
| | 启动时模拟是否暂停 |
| | 启用调试渲染 |
| | 调试显示开关 |
| | 调试颜色 |
| | RTree每个节点的条目数 |
| | 为动态物体使用RTree |
| | 设为true时,需手动调用 |
场景级配置会覆盖游戏级配置(合并生效)。
Events
事件
All events are emitted on :
this.physics.world| Event | String | Condition | Callback Args |
|---|---|---|---|
| | Two bodies collide and at least one has | |
| | Two bodies overlap and at least one has | |
| | Body hits world edge and has | |
| | Body collides with a tile | |
| | Body overlaps a tile | |
| | After each physics step | |
| | World paused | none |
| | World resumed | none |
Events require opt-in per body: set , , or to .
body.onCollidebody.onOverlapbody.onWorldBoundstrue所有事件均在上触发:
this.physics.world| 事件 | 字符串 | 触发条件 | 回调参数 |
|---|---|---|---|
| | 两个物体碰撞,且至少一个物体的 | |
| | 两个物体重叠,且至少一个物体的 | |
| | 物体碰撞世界边缘,且 | |
| | 物体与瓦片碰撞 | |
| | 物体与瓦片重叠 | |
| | 每步物理模拟后 | |
| | 世界暂停时 | 无 |
| | 世界恢复时 | 无 |
事件需要物体手动开启:将、或设为。
body.onCollidebody.onOverlapbody.onWorldBoundstrueAPI Quick Reference
API速查
Scene Plugin (this.physics
)
this.physics场景插件(this.physics
)
this.physics| Method | Description |
|---|---|
| Create sprite with dynamic body |
| Create image with dynamic body |
| Sprite with static body |
| Image with static body |
| Dynamic physics group |
| Static physics group |
| Add body to existing Game Object |
| Standalone dynamic Body (no GO) |
| Standalone static Body (no GO) |
| Persistent collider |
| Persistent overlap |
| One-shot collision check |
| One-shot overlap check |
| Next collision category bitmask |
| Pause/resume simulation |
| Accelerate toward point |
| Move toward point at speed |
| Angle (deg) to velocity |
| Rotation (rad) to velocity |
| Find nearest body |
| Find farthest body |
| Query bodies in rectangle |
| Query bodies in circle |
Also: , , , , , .
accelerateToObjectmoveToObjectcollideTilesoverlapTilesenableUpdatedisableUpdate| 方法 | 描述 |
|---|---|
| 创建带动态物体的精灵 |
| 创建带动态物体的图像 |
| 创建带静态物体的精灵 |
| 创建带静态物体的图像 |
| 创建动态物理组 |
| 创建静态物理组 |
| 为现有Game Object添加物理物体 |
| 创建独立动态Body(无Game Object) |
| 创建独立静态Body(无Game Object) |
| 创建持久化碰撞器 |
| 创建持久化重叠检测器 |
| 单次碰撞检测 |
| 单次重叠检测 |
| 获取下一个碰撞类别位掩码 |
| 暂停/恢复模拟 |
| 向指定点加速 |
| 以指定速度向指定点移动 |
| 将角度(度)转换为速度 |
| 将旋转(弧度)转换为速度 |
| 查找最近的物体 |
| 查找最远的物体 |
| 查询矩形区域内的物体 |
| 查询圆形区域内的物体 |
其他方法:, , , , , 。
accelerateToObjectmoveToObjectcollideTilesoverlapTilesenableUpdatedisableUpdateWorld (this.physics.world
)
this.physics.worldWorld(this.physics.world
)
this.physics.world| Method | Description |
|---|---|
| Set boundary + edge checks |
| Set which edges collide |
| Change physics step rate |
| Enable physics on object/group/array |
| Disable physics on object/group/array |
| Add/remove Body from simulation |
| Create Collider (same args as factory) |
| Remove Collider |
| Pause/resume simulation |
| Create debug rendering graphic |
| 方法 | 描述 |
|---|---|
| 设置边界及边缘碰撞检测 |
| 设置可碰撞的边缘 |
| 修改物理步频 |
| 为物体/组/数组启用物理系统 |
| 为物体/组/数组禁用物理系统 |
| 向模拟中添加/移除Body |
| 创建Collider(参数与工厂方法相同) |
| 移除Collider |
| 暂停/恢复模拟 |
| 创建调试渲染图形 |
Body Methods
Body方法
| Method | Description |
|---|---|
| Set velocity |
| Set acceleration |
| Velocity caps |
| Bounce and drag |
| Enable damping mode |
| Friction and per-body gravity |
| Mass and collision behavior |
| Resize/offset body |
| Switch to circular body |
| World bounds collision |
| Custom bounds rectangle |
| Toggle physics features |
| Enable/disable body |
| Category filtering |
| Reset to default (all) |
| Reset position or zero velocity |
| 方法 | 描述 |
|---|---|
| 设置速度 |
| 设置加速度 |
| 设置速度上限 |
| 设置反弹和阻力 |
| 启用阻尼模式 |
| 设置摩擦力和物体自身重力 |
| 设置质量和碰撞行为 |
| 调整物体尺寸/偏移 |
| 切换为圆形物体 |
| 设置世界边界碰撞 |
| 设置自定义边界矩形 |
| 切换物理特性 |
| 启用/禁用物体 |
| 设置类别过滤 |
| 重置为默认(与所有物体碰撞) |
| 重置位置或归零速度 |
Gotchas
注意事项
-
in production -- Debug rendering is expensive. Always disable for release builds.
debug: true -
Static body transform changes -- After changing position, scale, or origin of a static body's Game Object, you must callor
body.reset(). Static bodies do not auto-sync.gameObject.refreshBody() -
vs
collide--overlapperforms separation (pushes bodies apart).collideonly detects intersection without moving anything. Useoverlapfor triggers like pickups.overlap -
Persistent Collider vs one-shot --creates a Collider checked every frame automatically.
this.physics.add.collider()is a one-shot check that must be called each frame inthis.physics.collide(). Prefer persistent Colliders.update() -
Events require opt-in -- World events (,
'collide','overlap') only fire if the relevant body property ('worldbounds',onCollide,onOverlap) is set toonWorldBounds.true -
Collision categories default -- By default all bodies have categoryand mask
0x0001(PhysicsGroup defaults to mask1). Call2147483647to get new category values; max 32 categories total. After changing categories, usethis.physics.nextCategory()to set the mask to all bits.resetCollisionCategory() -
Group defaults only apply at creation -- PhysicsGroup(like
defaults,velocityX) are applied when a member is added/created. ChangingbounceYlater does not retroactively update existing members.defaults -
config -- Setting
customUpdatein the arcade config stops the world from auto-updating on the Scene UPDATE event. You must callcustomUpdate: truemanually.this.physics.world.update(time, delta) -
drag values -- When
useDampingisuseDamping, drag values should be small (e.g.,true) as they act as a multiplier. A value of0.05means the body keeps 5% of its velocity per second.0.05 -
Immovable vs pushable --means the body is never moved by collisions at all.
immovable = truemeans the body reflects velocity back to the colliding body but can still be separated.pushable = false -
Overlap with TilemapLayer -- When usingwith a TilemapLayer, every tile is checked regardless of collision settings on individual tiles.
overlapOnly -
RTree threshold -- The RTree spatial index (enabled by default) becomes expensive to rebuild with very large numbers of dynamic bodies. Consider settingfor 5000+ dynamic bodies.
useTree: false
-
生产环境中禁用-- 调试渲染性能开销大,发布版本务必禁用。
debug: true -
静态物体变换更新 -- 修改静态物体所属Game Object的位置、缩放或原点后,必须调用或
body.reset()。静态物体不会自动同步状态。gameObject.refreshBody() -
与
collide的区别 --overlap会执行分离(将物体推开)。collide仅检测相交,不会移动物体。拾取道具等触发场景建议使用overlap。overlap -
持久化碰撞器与单次检测 --创建的Collider会每帧自动检测。
this.physics.add.collider()是单次检测,需在this.physics.collide()中每帧调用。优先使用持久化碰撞器。update() -
事件需手动开启 -- 世界事件(、
'collide'、'overlap')仅在对应物体属性('worldbounds'、onCollide、onOverlap)设为onWorldBounds时触发。true -
碰撞类别默认值 -- 默认所有物体的类别为,掩码为1(PhysicsGroup默认掩码为
0x0001)。调用2147483647获取新类别值;最多支持32个类别。修改类别后,使用this.physics.nextCategory()将掩码设置为所有位。resetCollisionCategory() -
组默认值仅在创建时生效 -- PhysicsGroup的默认配置(如、
velocityX)仅在成员添加/创建时应用。后续修改默认配置不会更新现有成员。bounceY -
配置 -- 在arcade配置中设置
customUpdate会停止世界在Scene UPDATE事件中自动更新。需手动调用customUpdate: true。this.physics.world.update(time, delta) -
模式下的drag值 -- 当
useDamping设为useDamping时,drag值应设为较小值(如true),因为它作为乘数生效。值为0.05表示物体每秒保留5%的速度。0.05 -
Immovable与Pushable的区别 --表示物体完全不会因碰撞移动。
immovable = true表示物体会反弹碰撞物体的速度,但仍会被分离。pushable = false -
与TilemapLayer的重叠检测 -- 对TilemapLayer使用时,无论单个瓦片的碰撞设置如何,所有瓦片都会被检测。
overlapOnly -
RTree阈值 -- 默认启用的RTree空间索引在动态物体数量极多时重建开销会变大。当动态物体超过5000个时,建议设置。
useTree: false
Source File Map
源码文件映射
| File | Purpose |
|---|---|
| Scene plugin ( |
| Physics world -- bodies, gravity, bounds, colliders, step loop, setBounds, addCollider |
| Dynamic body -- velocity, acceleration, bounce, drag, gravity, mass, immovable, pushable |
| Static body -- immovable, no velocity, optimized RTree lookup |
| |
| Collider object -- persistent collision/overlap check with callbacks |
| Dynamic physics group with per-member defaults |
| Static physics group with auto-refresh |
| Body component mixins -- Acceleration, Angular, Bounce, Collision, Debug, Drag, Enable, Friction, Gravity, Immovable, Mass, Pushable, Size, Velocity |
| Collision category/mask methods -- setCollisionCategory, setCollidesWith, addCollidesWith, removeCollidesWith |
| Event constants -- COLLIDE, OVERLAP, WORLD_BOUNDS, TILE_COLLIDE, TILE_OVERLAP, WORLD_STEP, PAUSE, RESUME |
| TypeDef for arcade physics config options |
| 文件 | 用途 |
|---|---|
| 场景插件( |
| 物理世界 -- 物体管理、重力、边界、碰撞器、步循环、setBounds、addCollider等 |
| 动态物体 -- 速度、加速度、反弹、阻力、重力、质量、immovable、pushable等属性 |
| 静态物体 -- 不可移动、无速度、优化的RTree查找 |
| |
| Collider对象 -- 带回调的持久化碰撞/重叠检测 |
| 带成员默认配置的动态物理组 |
| 带自动刷新的静态物理组 |
| Body组件混入 -- Acceleration、Angular、Bounce、Collision、Debug、Drag、Enable、Friction、Gravity、Immovable、Mass、Pushable、Size、Velocity |
| 碰撞类别/掩码方法 -- setCollisionCategory、setCollidesWith、addCollidesWith、removeCollidesWith |
| 事件常量 -- COLLIDE、OVERLAP、WORLD_BOUNDS、TILE_COLLIDE、TILE_OVERLAP、WORLD_STEP、PAUSE、RESUME |
| Arcade物理配置选项的类型定义 |