Day 8: Designing Levels, Obstacle Patterns, and Environment Changes
Welcome to Day 8 of building your cross-platform mobile game with React Native and Phaser. Now that you have multiple scenes and core gameplay, itโs time to add level design mechanics: obstacle patterns, background changes, and per-level behaviors.
๐ง What Youโll Learn
- How to implement different obstacle patterns per level
- How to change the environment dynamically
- How to increase gameplay variety using level configuration
- How to manage background images and level metadata
๐๏ธ Step 1: Create Level Configuration
Add a simple level config inside GameScene
:
this.levels = [
{ speed: 100, pattern: 'straight', bg: 'bg1' },
{ speed: 150, pattern: 'zigzag', bg: 'bg2' },
{ speed: 200, pattern: 'double', bg: 'bg3' }
];
this.currentLevel = 0;
this.levelDuration = 15000; // 15s per level
๐ผ๏ธ Step 2: Preload Backgrounds
In preload()
:
this.load.image('bg1', 'https://labs.phaser.io/assets/skies/space3.png');
this.load.image('bg2', 'https://labs.phaser.io/assets/skies/nebula.jpg');
this.load.image('bg3', 'https://labs.phaser.io/assets/skies/space4.png');
๐ Step 3: Set the Level Background
In create()
:
this.bg = this.add.image(160, 240, 'bg1').setDepth(-1).setDisplaySize(320, 480);
Update background on level change:
this.time.addEvent({
delay: this.levelDuration,
callback: () => {
this.currentLevel++;
if (this.currentLevel >= this.levels.length) return;
const nextLevel = this.levels[this.currentLevel];
this.enemySpeed = nextLevel.speed;
this.bg.setTexture(nextLevel.bg);
this.pattern = nextLevel.pattern;
},
loop: true
});
๐พ Step 4: Spawn Enemies by Pattern
Modify the enemy spawner to check the pattern:
this.time.addEvent({
delay: 1000,
callback: () => {
const pattern = this.pattern || 'straight';
const x = Phaser.Math.Between(20, 300);
if (pattern === 'straight') {
const enemy = this.enemies.create(x, 0, 'enemy');
enemy.setVelocityY(this.enemySpeed);
}
if (pattern === 'zigzag') {
const enemy = this.enemies.create(x, 0, 'enemy');
const dir = Phaser.Math.Between(0, 1) === 0 ? -1 : 1;
enemy.setVelocity(this.enemySpeed * dir, this.enemySpeed);
}
if (pattern === 'double') {
const enemy1 = this.enemies.create(80, 0, 'enemy');
const enemy2 = this.enemies.create(240, 0, 'enemy');
enemy1.setVelocityY(this.enemySpeed);
enemy2.setVelocityY(this.enemySpeed);
}
},
loop: true
});
๐งช Step 5: Test Level Transitions
- Start the game.
- Watch the background change every 15 seconds.
- Observe different enemy patterns: zigzag, double, or fast spawns.
- Try surviving through all levels.
โ What Youโve Achieved
- Implemented progressive level design with speed and behavior changes
- Introduced dynamic environment backgrounds
- Enhanced gameplay variety using structured level data
- Laid the foundation for endless or story-based game modes
๐ Up Next
In Day 9, weโll add a scoring system with highscores, persistent storage using localStorage, and a leaderboard UI โ so players can track their best runs.
Your game is becoming an experience โ letโs make it memorable and replayable!