Phaser Project — Complete 2D Platform Game
In this tutorial, you will learn about Phaser Project. We cover key concepts, practical examples, and best practices to help you master this topic.
This project walks through building a complete 2D platform game with Phaser, combining arcade physics, animations, particles, audio, camera system, and Responsive Design.
What You'll Learn
By the end of this project, you will architect a complete game with multiple scenes, implement player movement and jumping with arcade physics, create enemy AI with patrol behavior, use particle effects for collectibles, manage game state across scenes, and deploy a production-ready game.
Game Architecture
var GameState = {
score: 0,
lives: 3,
level: 1,
coins: 0
};
var BootScene = {
create: function() {
this.scene.start('Menu');
}
};
var MenuScene = {
create: function() {
this.add.text(400, 300, 'Platform Quest', { fontSize: '48px' }).setOrigin(0.5);
this.add.text(400, 380, 'Click to Start', { fontSize: '24px' }).setOrigin(0.5);
this.input.on('pointerdown', function() {
this.scene.start('Game');
}, this);
}
};
var GameScene = {
create: function() {
// Setup physics, player, platforms, enemies, collectibles
},
update: function() {
// Handle input, enemy AI, collision checks
}
};
var GameOverScene = {
create: function() {
// Show final score, restart option
}
};
Enemy AI
function updateEnemies() {
this.enemies.children.iterate(function(enemy) {
if (enemy.body.blocked.left) {
enemy.setVelocityX(50);
enemy.setFlipX(true);
} else if (enemy.body.blocked.right) {
enemy.setVelocityX(-50);
enemy.setFlipX(false);
}
});
}
Common Mistakes
1. No State Management
Track score, lives, and level in a global object or registry: this.registry.set('score', 0).
2. Scene Transitions Without Cleanup
Destroy timers and events when leaving a scene. Use scene.events.on('shutdown').
3. Hardcoded Values
Put level data (platform positions, enemy spawns) in JSON or arrays. Avoid magic numbers.
4. No Game Over Condition
Handle lives reaching 0. Transition to a GameOver scene with the final score.
5. Not Testing on Target Device
Test on the lowest-spec target device early. Optimize particle counts and physics bodies.
Practice Questions
Q1: How do you structure a multi-scene game? A: Use separate scene classes for Boot, Menu, Game, and GameOver.
Q2: How do you share data between scenes? A: Use this.registry.set/get or a global state object.
Q3: How do you create enemy patrol AI? A: Check body.blocked.left/right and reverse velocity.
Q4: How do you add collectibles? A: Use a physics group with overlap detection on the player.
Q5: How do you handle game over? A: Decrease lives on death. When lives = 0, transition to GameOver scene.
Challenge: Add a level editor that saves platform layouts to JSON. The game should load levels from JSON files. Include a level select screen.
FAQ
Try It Yourself
Build a mini platformer.
<!DOCTYPE html>
<html>
<head>
<title>Phaser Project</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>Platform Quest Mini</h2>
<script>
var config = {
type: Phaser.AUTO,
width: 600,
height: 400,
backgroundColor: '#87CEEB',
physics: { default: 'arcade', arcade: { gravity: { y: 600 }, debug: false } },
scene: {
create: function() {
var style = { fontSize: '14px', fill: '#333' };
// Background
this.add.rectangle(300, 200, 600, 400, 0x87CEEB);
// Platforms
this.platforms = this.physics.add.staticGroup();
this.platforms.create(300, 390, null).setDisplaySize(600, 20).refreshBody();
this.platforms.create(150, 300, null).setDisplaySize(100, 16).refreshBody();
this.platforms.create(450, 250, null).setDisplaySize(120, 16).refreshBody();
this.platforms.create(300, 180, null).setDisplaySize(80, 16).refreshBody();
// Player
this.player = this.add.rectangle(100, 350, 24, 32, 0xff6b35);
this.physics.add.existing(this.player);
this.player.body.setBounce(0.1);
this.player.body.setCollideWorldBounds(true);
this.physics.add.collider(this.player, this.platforms);
this.cursors = this.input.keyboard.createCursorKeys();
// Coins
this.coins = this.physics.add.staticGroup();
for (var i = 0; i < 5; i++) {
var coin = this.coins.create(100 + i * 110, 250, null);
coin.setDisplaySize(12, 12).refreshBody();
coin.setFillStyle(0xffd700);
}
this.physics.add.overlap(this.player, this.coins, function(p, coin) {
coin.destroy();
GameState.score += 10;
this.scoreText.setText('Score: ' + GameState.score);
}, null, this);
// Enemies
this.enemies = this.physics.add.group();
for (var i = 0; i < 2; i++) {
var enemy = this.enemies.create(300 + i * 200, 350, null);
enemy.setDisplaySize(20, 20);
enemy.setFillStyle(0xe74c3c);
enemy.body.setVelocityX(40 * (i === 0 ? 1 : -1));
enemy.body.setBounce(1, 0);
enemy.body.setCollideWorldBounds(true);
}
this.physics.add.collider(this.enemies, this.platforms);
this.physics.add.overlap(this.player, this.enemies, function() {
if (GameState.lives > 0) {
GameState.lives--;
this.livesText.setText('Lives: ' + GameState.lives);
this.player.setPosition(100, 350);
this.player.body.setVelocity(0);
}
if (GameState.lives <= 0) {
this.add.text(300, 200, 'GAME OVER', { fontSize: '48px', fill: '#e74c3c' }).setOrigin(0.5);
this.physics.pause();
}
}, null, this);
// UI
GameState = { score: 0, lives: 3 };
this.scoreText = this.add.text(16, 16, 'Score: 0', style);
this.livesText = this.add.text(500, 16, 'Lives: 3', style);
},
update: function() {
var speed = 150;
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);
}
// Enemy patrol
this.enemies.children.iterate(function(e) {
if (e.body.blocked.left) e.body.setVelocityX(50);
if (e.body.blocked.right) e.body.setVelocityX(-50);
});
}
}
};
var GameState = { score: 0, lives: 3 };
var game = new Phaser.Game(config);
</script>
</body>
</html>
What's Next
Review all learned libraries and choose your next project.
Libraries Overview — Recap of all frontend libraries.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro