Skip to content
Phaser Virtual Joystick

Phaser Virtual Joystick

Add intuitive mobile controls to your Phaser 3 games with a beautiful virtual joystick

A highly customizable and strongly typed virtual joystick component for Phaser.js games, inspired by the smooth and intuitive controls from Brawl Stars. Perfect for mobile games and touch-based interactions.

Brawl Stars Inspired

Smooth joystick following and intuitive touch controls just like Brawl Stars.

Fully Customizable

Colors, sizes, transparency, and visual styling - customize every aspect.

Touch Optimized

Designed specifically for mobile and touch devices with smart bounds detection.

High Performance

Lightweight and optimized for games with smooth 60fps performance.

Strongly Typed

Full TypeScript support with comprehensive type definitions.

Event Driven

Listen to move, press, and release events with rich data.

  • Brawl Stars-inspired behavior - Smooth joystick following and intuitive touch controls
  • Fully customizable - Colors, sizes, transparency, and visual styling
  • Touch-optimized - Designed specifically for mobile and touch devices
  • Smart bounds detection - Configurable activation areas
  • High performance - Lightweight and optimized for games
  • Strongly typed - Full TypeScript support with comprehensive type definitions
  • Visual feedback - Dead zone, base area, and stick with customizable styling
  • Event-driven - Listen to move, press, and release events
  • Button conflict prevention - Automatically avoids interference with UI buttons
import { VirtualJoystick } from 'phaser-virtual-joystick';
export class GameScene extends Phaser.Scene {
private joystick!: VirtualJoystick;
private player!: Phaser.Physics.Arcade.Sprite;
create() {
// Create the virtual joystick
this.joystick = new VirtualJoystick({
scene: this
});
// ⚠️ IMPORTANT: Don't forget to add the joystick to the scene!
this.add.existing(this.joystick);
// Create a player sprite
this.player = this.physics.add.sprite(400, 300, 'player');
// Listen to joystick events
this.joystick.on('move', (data) => {
// data.x and data.y are normalized between -1 and 1
this.player.setVelocity(
data.x * 200, // Move speed
data.y * 200
);
});
this.joystick.on('release', () => {
this.player.setVelocity(0, 0);
});
}
update() {
// Update joystick (required for smooth following behavior)
this.joystick?.update();
}
}

🚨 DON’T FORGET TO ADD THE JOYSTICK TO THE SCENE!

Always remember to call this.add.existing(joystick) or scene.add.existing(joystick) after creating the joystick. The joystick won’t work without being added to the scene!

// ✅ Correct
const joystick = new VirtualJoystick({ scene: this });
this.add.existing(joystick); // This is essential!
// ❌ Wrong - joystick won't work
const joystick = new VirtualJoystick({ scene: this });
// Missing: this.add.existing(joystick);
  • Action Games - Precise character movement and aiming
  • Platformers - Smooth left/right movement and jumping
  • Racing Games - Steering and acceleration control
  • Shooters - Movement and aiming mechanics
  • Any Mobile Game - That needs directional input
Terminal window
npm install phaser-virtual-joystick
# or
yarn add phaser-virtual-joystick
# or
pnpm add phaser-virtual-joystick
  • Activation Area: Left half of the screen (with 20% top padding)
  • Visual Style: Blue-themed with subtle transparency
  • Dead Zone: 16px radius - no input registered in this area
  • Base Area: 64px radius - maximum joystick movement range
  • Stick: 40px radius - follows your finger with smooth following behavior
  • Touch Only: Only works on touch devices by default

Mobile gaming requires intuitive controls that feel natural to touch users. While Phaser provides excellent input handling, creating a polished virtual joystick from scratch can be time-consuming and challenging.

Phaser Virtual Joystick solves this by providing:

  • Out-of-the-box mobile controls - No need to build joystick logic from scratch
  • Brawl Stars-quality feel - Smooth, responsive controls that players expect
  • TypeScript integration - Full type safety and IntelliSense support
  • Event-driven architecture - Clean separation of input handling and game logic
  • Automatic touch detection - Only shows when needed, invisible on desktop

Ready to add professional mobile controls to your Phaser game? Let’s get started!