Phaser Arcade Physics — Simple 2D Physics Engine
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
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