Day 2: Creating a Game Loop and Handling User Input in Phaser
Welcome to Day 2 of building a cross-platform mobile game using React Native and Phaser. Yesterday, we set up Phaser inside a React Native WebView. Today, you’ll create a basic game loop, handle user interactions like touch/tap, and display a moving sprite.
🧠 What You’ll Learn
- Creating a game loop with Phaser’s
update()
function - Handling mobile touch and pointer input
- Moving a sprite on tap
- Structuring Phaser code for scalability
🔁 Step 1: Update the HTML Game Template
Replace assets/phaser/game.html
with the following code:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Phaser Game</title>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/phaser.js"></script>
<style>
body { margin: 0; overflow: hidden; }
canvas { display: block; }
</style>
</head>
<body>
<script>
let logo;
let targetX = 160;
let targetY = 240;
const config = {
type: Phaser.AUTO,
width: 320,
height: 480,
scene: {
preload,
create,
update,
}
};
function preload() {
this.load.image('logo', 'https://labs.phaser.io/assets/sprites/phaser3-logo.png');
}
function create() {
logo = this.add.image(targetX, targetY, 'logo').setInteractive();
this.input.on('pointerdown', function (pointer) {
targetX = pointer.x;
targetY = pointer.y;
});
}
function update() {
if (!logo) return;
const speed = 4;
const distX = targetX - logo.x;
const distY = targetY - logo.y;
if (Math.abs(distX) > 1 || Math.abs(distY) > 1) {
logo.x += distX * 0.1;
logo.y += distY * 0.1;
}
}
new Phaser.Game(config);
</script>
</body>
</html>
🎮 What This Code Does
- Scene Lifecycle: You now use all three Phaser lifecycle functions:
preload()
,create()
, andupdate()
. - Input Handling:
pointerdown
listens for taps/touches on the screen. - Smooth Movement: The
update()
function animates the logo smoothly toward the tapped position.
📱 Step 2: Run the App in React Native
No changes are needed in App.js
. Just run:
expo start
Scan with Expo Go or run on an emulator. Tap anywhere on the screen and the Phaser logo will animate smoothly to that point.
🧩 Bonus: Use Physics for Movement (Optional)
Want to try physics-based motion? Replace the movement logic in create()
and update()
with:
this.physics.add.existing(logo);
logo.body.setVelocity(0);
this.input.on('pointerdown', function (pointer) {
const angle = Phaser.Math.Angle.Between(logo.x, logo.y, pointer.x, pointer.y);
this.physics.moveTo(logo, pointer.x, pointer.y, 200);
}, this);
And add physics
to your config:
physics: { default: 'arcade' }
✅ What You’ve Achieved
- Created a game loop using
update()
- Handled user input (tap/touch)
- Moved a sprite smoothly across the screen
- Laid the foundation for player controls and interactive gameplay
📌 Up Next
In Day 3, we’ll build game objects like enemies and collectibles, and implement collision detection to trigger in-game events.
You’re now officially building your mobile game logic — one step closer to publishing!