| name | dev-phaser-physics-arcade |
| description | Arcade physics velocity, acceleration, collision, and bounds |
Phaser Arcade Physics
"Fast, simple 2D physics for platformers and arcade games."
Before/After: Manual Collision vs Phaser Arcade Physics
❌ Before: Manual AABB Collision
interface Box {
x: number;
y: number;
width: number;
height: number;
vx: number;
vy: number;
}
const player: Box = { x: 100, y: 300, width: 32, height: 48, vx: 0, vy: 0 };
const platforms: Box[] = [
{ x: 0, y: 500, width: 800, height: 68 }
];
function checkCollision(a: Box, b: Box): boolean {
return a.x < b.x + b.width &&
a.x + a.width > b.x &&
a.y < b.y + b.height &&
a.y + a.height > b.y;
}
function updatePhysics(dt: number) {
player.vy += 1000 * dt;
player.x += player.vx * dt;
player.y += player.vy * dt;
for (const platform of platforms) {
if (checkCollision(player, platform)) {
if (player.vy > 0 && player.y + player.height - player.vy * dt <= platform.y) {
player.y = platform.y - player.height;
player.vy = 0;
}
}
}
if (player.x < 0) player.x = 0;
if (player.x > 800 - player.width) player.x = 800 - player.width;
}
✅ After: Phaser Arcade Physics
export class GameScene extends Phaser.Scene {
private player!: Phaser.Physics.Arcade.Sprite;
create() {
this.player = this.physics.add.sprite(100, 450, 'player');
this.player.setBounce(0);
this.player.setCollideWorldBounds(true);
const platforms = this.physics.add.staticGroup();
platforms.create(400, 568, 'ground').setScale(2, 1).refreshBody();
this.physics.add.collider(., platforms);
}
() {
(...) {
..(-);
} (...) {
..();
} {
..();
}
(... && ..!..) {
..(-);
}
}
}
When to Use This Skill
Use when:
- Implementing platformer games
- Creating collision detection
- Working with velocity and gravity
- Building arcade-style gameplay
- Need simple, performant physics
Quick Start
physics: {
default: 'arcade',
arcade: {
gravity: { y: 1000 },
debug: false
}
}
const player = this.physics.add.sprite(400, 300, 'player');
player.setBounce(0.2);
player.setCollideWorldBounds(true);
Decision Framework
| Need | Use |
|---|
| Platformer | Arcade with gravity |
| Top-down | Arcade without gravity |
| Bouncing objects | setBounce(0.5) |
| Static platforms | this.physics.add.staticGroup() |
| Collision detection | this.physics.add.collider() |
Progressive Guide
Level 1: Basic Physics Body
export class GameScene extends Phaser.Scene {
private player!: Phaser.Physics.Arcade.Sprite;
create() {
this.player = this.physics.add.sprite(400, 300, "player");
this.player.setBounce(0.2);
this.player.setCollideWorldBounds(true);
this.player.setDrag(0.1, 0);
this.player.setFriction(0.1);
this.player.setMaxVelocity(400);
this..();
..(-);
..(, );
..();
}
}
Level 2: Collision Detection
create() {
const player = this.physics.add.sprite(400, 300, 'player');
const platforms = this.physics.add.staticGroup();
platforms.create(400, 568, 'ground').setScale(2, 1).refreshBody();
platforms.create(600, 400, 'platform');
this.physics.add.collider(player, platforms);
const coins = this.physics.add.group({
defaultKey: 'coin',
bounceX: 0.5,
bounceY: 0.5
});
this.physics.add.overlap(player, coins, this.collectCoin, , );
}
() {
coin.(, );
}
Level 3: Platformer Controls
export class GameScene extends Phaser.Scene {
private player!: Phaser.Physics.Arcade.Sprite;
private cursors!: Phaser.Types.Input.Keyboard.CursorKeys;
private jumpKey!: Phaser.Input.Keyboard.Key;
create() {
this.player = this.physics.add.sprite(100, 450, "player");
this.player.setBounce(0);
this.player.setCollideWorldBounds(true);
this.cursors = this.input.keyboard!.createCursorKeys();
this.jumpKey = this.input.keyboard!.();
platforms = ...();
platforms.(, , ).().();
...(., platforms);
}
() {
(...) {
..(-);
} (...) {
..();
} {
..();
}
(.. && ..!..) {
..(-);
}
}
}
Level 4: Advanced Collision Callbacks
create() {
this.physics.add.collider(
this.player,
this.enemies,
this.playerHitEnemy,
this.checkEnemyVulnerable,
this
);
}
checkEnemyVulnerable(
player: Phaser.Types.Physics.Arcade.GameObjectWithBody,
enemy: any
): boolean {
const enemySprite = enemy as Phaser.Physics.Arcade.Sprite;
return !enemySprite.getData('invincible');
}
playerHitEnemy(
player: Phaser.Types.Physics.Arcade.GameObjectWithBody,
enemy: any
) {
const enemySprite = enemy as ...;
(player.!.. > && player. < enemySprite. - ) {
enemySprite.();
player.(-);
} {
.();
}
}
Level 5: Custom Physics Components
class PlatformerController {
private speed = 160;
private jumpForce = -330;
private isGrounded = false;
constructor(
private sprite: Phaser.Physics.Arcade.Sprite,
private cursors: Phaser.Types.Input.Keyboard.CursorKeys,
private jumpKey: Phaser.Input.Keyboard.Key
) {
this.enableDoubleJump();
}
update() {
if (this.cursors.left.isDown) {
this.sprite.setVelocityX(-this.speed);
this.sprite.setFlipX(true);
} else if (this...) {
..(.);
..();
} {
..();
}
(.. && .) {
..(.);
. = ;
}
}
() {
. = ;
}
() {
..(, {
(!. && ..!.. > -) {
..(. * );
}
});
}
}
() {
controller = (
.,
.,
.
);
...(., platforms, {
controller.();
});
}
() {
controller.();
}
Anti-Patterns
❌ DON'T:
- Use Matter physics for simple platformers - Arcade is faster
- Set position directly on physics bodies - use velocity
- Forget to call
refreshBody() after scaling static objects
- Use overlap when collider is needed
- Disable physics bodies instead of removing from scene
- Mix pixel and meter units arbitrarily
✅ DO:
- Use Arcade for platformers, top-down games
- Apply forces/velocity for movement
- Refresh body after scale/position changes
- Use proper collision types (collider vs overlap)
- Remove bodies from physics world when destroyed
- Keep units consistent (pixels)
Code Patterns
One-Way Platforms
create() {
const platforms = this.physics.add.staticGroup();
const platform = platforms.create(400, 400, 'platform');
platform.checkCollision.down = false;
platform.checkCollision.up = true;
}
Body Size Adjustment
const player = this.physics.add.sprite(400, 300, "player");
player.body!.setSize(20, 40);
player.body!.setOffset(6, 8);
player.body!.checkCollision.up = false;
Moving Platform
export class MovingPlatform extends Phaser.Physics.Arcade.Image {
constructor(
scene: Phaser.Scene,
x: number,
y: number,
texture: string,
private startX: number,
private endX: number,
) {
super(scene, x, y, texture);
scene.add.existing(this);
scene.physics.add.existing(this, false);
this.setVelocityX(50);
this.scene.events.on("update", this.updatePlatform, this);
}
updatePlatform() {
if (this.x >= this.endX) {
this.setVelocityX(-);
} (. <= .) {
.();
}
}
}
Checklist
Physics Body Properties
| Property | Type | Description |
|---|
velocity | Vector2 | Current velocity |
acceleration | Vector2 | Applied acceleration |
drag | Vector2 | Deceleration over time |
gravity | Vector2 | Applied gravity force |
bounce | number | Bounciness (0-1) |
friction | number | Surface friction |
maxVelocity | Vector2 | Maximum speed cap |
allowGravity | boolean | Whether gravity affects body |
immovable | boolean | Body cannot be pushed |
Reference