PixiJS Project — Interactive 2D Game
In this tutorial, you will learn about PixiJS Project. We cover key concepts, practical examples, and best practices to help you master this topic.
This project walks through building a complete 2D game with PixiJS, combining sprites, animated characters, particle effects, collision detection, and Responsive Design.
What You'll Learn
By the end of this project, you will architect a game loop with PixiJS, implement player movement and shooting, create enemy spawning with difficulty curves, use particle effects for explosions, manage game state (menu, play, game over), and optimize for mobile.
Game Architecture
var Game = {
state: 'menu',
score: 0,
player: null,
enemies: [],
bullets: [],
particles: [],
init: function() {
this.app = new PIXI.Application({ width: 800, height: 600 });
document.body.appendChild(this.app.view);
this.setupStages();
this.setupInput();
this.gameLoop();
},
setupInput: function() {
window.addEventListener('keydown', function(e) {
Game.keys[e.code] = true;
});
window.addEventListener('keyup', function(e) {
Game.keys[e.code] = false;
});
},
gameLoop: function() {
this.app.ticker.add(function(delta) {
Game.update(delta);
});
}
};
Collision Detection
function checkCollisions() {
for (var i = Game.enemies.length - 1; i >= 0; i--) {
for (var j = Game.bullets.length - 1; j >= 0; j--) {
if (rectsOverlap(Game.enemies[i], Game.bullets[j])) {
Game.destroyEnemy(i);
Game.destroyBullet(j);
Game.score += 10;
Game.spawnExplosion(Game.enemies[i].x, Game.enemies[i].y);
break;
}
}
}
}
function rectsOverlap(a, b) {
var ab = a.getBounds();
var bb = b.getBounds();
return ab.x < bb.x + bb.width &&
ab.x + ab.width > bb.x &&
ab.y < bb.y + bb.height &&
ab.y + ab.height > bb.y;
}
Common Mistakes
1. No Delta Time
Movement must be multiplied by delta for consistent speed across frame rates.
2. Memory Leaks from Bullets
Bullets that leave the screen must be destroyed. Use object pooling.
3. Collision Check Order
Check the least expensive collision first. Use spatial hashing for many objects.
4. Touch Not Working
Mobile needs touch controls. Add onscreen buttons or tap-to-shoot.
5. No Start Screen
Jumping straight into gameplay confuses users. Add a simple menu screen.
Practice Questions
Q1: How do you structure a PixiJS game? A: Use a game state machine with separate update and render methods.
Q2: How do you handle keyboard input? A: Listen to keydown/keyup events and track active keys in a map.
Q3: How do you detect sprite collisions? A: Use getBounds().x, .y, .width, .height for AABB collision checks.
Q4: How do you add delta time? A: The ticker callback receives delta. Multiply movement speeds by delta.
Q5: How do you create a particle explosion? A: Spawn 10-30 sprites at the explosion point with random velocities, fade alpha, and destroy after lifespan.
Challenge: Add power-ups that spawn every 10 seconds. Power-ups give triple shot for 5 seconds. Show a timer and visual indicator for the active power-up.
FAQ
Try It Yourself
Build a simple space shooter.
<!DOCTYPE html>
<html>
<head>
<title>PixiJS Space Shooter</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/pixi.js/7.3/pixi.min.js"></script>
</head>
<body style="font-family:sans-serif;padding:20px;">
<h2>Space Shooter</h2>
<p>Arrow keys to move, Space to shoot</p>
<canvas id="game" style="border:1px solid #333;border-radius:8px;"></canvas>
<div id="score" style="margin-top:8px;font-size:18px;font-weight:bold;">Score: 0</div>
<script>
var app = new PIXI.Application({ width: 600, height: 450, background: 0x0a0a1a, view: document.getElementById('game') });
// Player
var player = new PIXI.Graphics();
player.beginFill(0x4ecdc4);
player.moveTo(30, 0);
player.lineTo(-20, -15);
player.lineTo(-20, 15);
player.closePath();
player.endFill();
player.x = 300;
player.y = 400;
app.stage.addChild(player);
// Input
var keys = {};
window.addEventListener('keydown', function(e) { keys[e.code] = true; });
window.addEventListener('keyup', function(e) { keys[e.code] = false; });
// Bullets
var bullets = [];
var bulletTexture = (function() {
var g = new PIXI.Graphics();
g.beginFill(0xff6b35);
g.drawRect(0, 0, 4, 12);
g.endFill();
return app.renderer.generateTexture(g);
})();
function shoot() {
var bullet = new PIXI.Sprite(bulletTexture);
bullet.x = player.x - 2;
bullet.y = player.y - 20;
app.stage.addChild(bullet);
bullets.push(bullet);
}
// Enemies
var enemies = [];
var enemyTexture = (function() {
var g = new PIXI.Graphics();
g.beginFill(0xff6b35);
g.drawCircle(0, 0, 12);
g.endFill();
return app.renderer.generateTexture(g);
})();
function spawnEnemy() {
var enemy = new PIXI.Sprite(enemyTexture);
enemy.x = Math.random() * 550 + 25;
enemy.y = -30;
app.stage.addChild(enemy);
enemies.push(enemy);
}
setInterval(spawnEnemy, 1000);
// Score
var score = 0;
var scoreEl = document.getElementById('score');
function checkCollisions() {
for (var i = enemies.length - 1; i >= 0; i--) {
for (var j = bullets.length - 1; j >= 0; j--) {
var eb = enemies[i].getBounds();
var bb = bullets[j].getBounds();
if (eb.x < bb.x + bb.width && eb.x + eb.width > bb.x &&
eb.y < bb.y + bb.height && eb.y + eb.height > bb.y) {
app.stage.removeChild(enemies[i]);
app.stage.removeChild(bullets[j]);
enemies.splice(i, 1);
bullets.splice(j, 1);
score += 10;
scoreEl.textContent = 'Score: ' + score;
break;
}
}
}
}
var canShoot = true;
app.ticker.add(function(delta) {
// Movement
if (keys['ArrowLeft']) player.x -= 5 * delta;
if (keys['ArrowRight']) player.x += 5 * delta;
player.x = Math.max(30, Math.min(570, player.x));
if (keys['Space'] && canShoot) {
shoot();
canShoot = false;
setTimeout(function() { canShoot = true; }, 200);
}
// Update bullets
for (var i = bullets.length - 1; i >= 0; i--) {
bullets[i].y -= 7 * delta;
if (bullets[i].y < -20) {
app.stage.removeChild(bullets[i]);
bullets.splice(i, 1);
}
}
// Update enemies
for (var i = enemies.length - 1; i >= 0; i--) {
enemies[i].y += 2 * delta;
if (enemies[i].y > 500) {
app.stage.removeChild(enemies[i]);
enemies.splice(i, 1);
}
}
checkCollisions();
});
</script>
</body>
</html>
What's Next
Explore Phaser for Game Development.
Getting Started — Game development with Phaser.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro