Skip to content

Phaser Arcade Physics — Simple 2D Physics Engine

DodaTech Updated 2026-06-28 3 min read

In this tutorial, you will learn about Phaser Arcade Physics. We cover key concepts, practical examples, and best practices to help you master this topic.

Phaser arcade physics provides lightweight 2D physics with gravity, velocity, acceleration, and collision detection for simple games.

What You'll Learn

By the end of this guide, you will create physics-enabled sprites, apply gravity and velocity, configure body shapes and sizes, detect collisions and overlaps, implement platformer movement, and build projectile systems.

Basic Physics Body

this.physics.add.existing(sprite);
sprite.body.setVelocity(100, 200);
sprite.body.setGravityY(300);

Platformer Setup

// Player
player = this.physics.add.sprite(100, 300, 'player');
player.body.setBounce(0.2);
player.body.setCollideWorldBounds(true);

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

// Collision
this.physics.add.collider(player, platforms);

// Input
cursors = this.input.keyboard.createCursorKeys();

Overlap Detection

this.physics.add.overlap(player, stars, collectStar, null, this);

function collectStar(player, star) {
    star.destroy();
    score += 10;
}

Body Customization

player.body.setSize(24, 32); // Hitbox smaller than sprite
player.body.setOffset(4, 16);
player.body.setBounce(0.3);
player.body.setDrag(50);
player.body.setMaxVelocity(200, 400);

Projectile

function fireBullet() {
    var bullet = bullets.get(player.x, player.y);
    if (bullet) {
        bullet.setActive(true).setVisible(true);
        bullet.body.setVelocityY(-300);
    }
}

Common Mistakes

1. staticGroup vs Group

Static group bodies do not move. Use physics.add.group() for moving objects.

2. Not Calling refreshBody

After scaling or changing a static body, call refreshBody() to update physics.

3. Gravity Affecting All Bodies

Gravity applies to all dynamic bodies by default. Use body.setAllowGravity(false) to disable.

4. Collision Not Detected

Both objects must have physics bodies. Static bodies need collider checks.

5. Body Size Not Matching Sprite

Default body matches sprite size. For uneven hitboxes, use setSize and setOffset.

Practice Questions

Q1: How do you make a sprite a physics body? A: Use this.physics.add.sprite() or this.physics.add.existing().

Q2: What is the difference between collider and overlap? A: collider pushes objects apart. overlap just detects intersection without separation.

Q3: How do you make a static body? A: Use physics.add.staticGroup() or body.setImmovable(true).

Q4: How do you set gravity per body? A: Set body.setGravityY(value) or the global gravity in config.

Q5: How do you check if a body is touching the ground? A: Use body.blocked.down or body.touching.down.

Challenge: Build a simple platformer with moving platforms. The player must jump between platforms. Falling off resets the position. Score points for each platform reached.

FAQ

What is the maximum velocity?

Set by body.setMaxVelocity(x, y). Default is 10,000.

Can I use arcade physics for top-down games?

Yes. Set gravity: { y: 0 } for top-down movement.

How do I stop a body?

Set velocity to 0: body.setVelocity(0, 0).

Can I rotate physics bodies?

Arcade bodies are axis-aligned. Use Matter physics for rotated bodies.

How do I make a one-way platform?

Set body.checkDown. Only collides when falling from above.

Try It Yourself

Build a simple platformer.

<!DOCTYPE html>
<html>
<head>
    <title>Phaser Arcade Physics</title>
    <script src="https://cdn.jsdelivr.net/npm/phaser@3/dist/phaser.min.js"></script>
</head>
<body style="font-family:sans-serif;padding:20px;">
<h2>Platformer Demo</h2>
<script>
var config = {
    type: Phaser.AUTO,
    width: 600,
    height: 400,
    backgroundColor: '#1a1a2e',
    physics: {
        default: 'arcade',
        arcade: {
            gravity: { y: 500 },
            debug: false
        }
    },
    scene: {
        create: function() {
            // Platforms
            this.platforms = this.physics.add.staticGroup();
            this.platforms.create(300, 380, null).setDisplaySize(600, 40).refreshBody();

            var platformPositions = [
                { x: 100, y: 300, w: 100 },
                { x: 400, y: 250, w: 100 },
                { x: 200, y: 180, w: 80 },
                { x: 500, y: 150, w: 100 }
            ];

            platformPositions.forEach(function(p) {
                var plat = this.platforms.create(p.x, p.y, null);
                plat.setDisplaySize(p.w, 16).refreshBody();
                plat.body.setImmovable(true);
            }, this);

            // Player
            this.player = this.add.rectangle(100, 300, 24, 32, 0x4ecdc4);
            this.physics.add.existing(this.player);
            this.player.body.setBounce(0.1);
            this.player.body.setCollideWorldBounds(true);
            this.player.body.setSize(24, 32);

            this.physics.add.collider(this.player, this.platforms);

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

            this.score = 0;
            this.scoreText = this.add.text(16, 16, 'Score: 0', {
                fill: '#ffffff', fontSize: '18px'
            });

            // Score zone
            this.scoreZone = this.add.zone(300, 50, 40, 40);
            this.physics.add.existing(this.scoreZone, true);
            this.physics.add.overlap(this.player, this.scoreZone, function() {
                this.score += 10;
                this.scoreText.setText('Score: ' + this.score);
                this.scoreZone.x = Math.random() * 500 + 50;
                this.scoreZone.y = Math.random() * 200 + 50;
                this.physics.world.step(this.scoreZone);
            }, null, this);
        },
        update: function() {
            var speed = 200;
            var jump = -350;

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

            if (this.cursors.up.isDown && this.player.body.blocked.down) {
                this.player.body.setVelocityY(jump);
            }
        }
    }
};

var game = new Phaser.Game(config);
</script>
</body>
</html>

What's Next

Use Matter.js physics.

Matter Physics — Matter.js advanced physics. Scaling — Responsive game scaling.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro