Phaser 性能优化 #

性能概述 #

性能优化是游戏开发的重要环节,良好的性能可以提供流畅的游戏体验。

text
┌─────────────────────────────────────────────────────────────┐
│                    性能优化方向                              │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  渲染优化                                                   │
│  ├── 减少绘制调用                                          │
│  ├── 使用纹理图集                                          │
│  └── 合理使用图层                                          │
│                                                             │
│  内存优化                                                   │
│  ├── 对象池                                                │
│  ├── 资源管理                                              │
│  └── 避免内存泄漏                                          │
│                                                             │
│  逻辑优化                                                   │
│  ├── 减少计算量                                            │
│  ├── 使用空间分区                                          │
│  └── 优化碰撞检测                                          │
│                                                             │
└─────────────────────────────────────────────────────────────┘

性能监控 #

FPS 显示 #

javascript
create() {
  this.fpsText = this.add.text(10, 10, '', {
    fontSize: '16px',
    fill: '#00ff00'
  }).setScrollFactor(0).setDepth(1000);
}

update() {
  this.fpsText.setText('FPS: ' + Math.round(this.game.loop.actualFps));
}

性能调试 #

javascript
const config = {
  physics: {
    arcade: {
      debug: true
    }
  }
};

console.log('Game objects:', this.children.length);
console.log('Active bodies:', this.physics.world.bodies.getLength());
console.log('Memory:', performance.memory);

使用浏览器工具 #

javascript
console.time('operation');
console.timeEnd('operation');

console.profile('profileName');
console.profileEnd('profileName');

渲染优化 #

批量渲染 #

javascript
const config = {
  type: Phaser.WEBGL,
  batchSize: 4096
};

纹理图集 #

javascript
preload() {
  this.load.atlas('game', 'assets/game.png', 'assets/game.json');
}

create() {
  this.add.image(100, 100, 'game', 'player');
  this.add.image(200, 100, 'game', 'enemy');
  this.add.image(300, 100, 'game', 'item');
}

减少绘制调用 #

javascript
const container = this.add.container(400, 300);
container.add([sprite1, sprite2, sprite3]);

const graphics = this.add.graphics();
graphics.fillStyle(0xff0000);
graphics.fillRect(0, 0, 100, 100);
graphics.fillRect(100, 0, 100, 100);
graphics.fillRect(200, 0, 100, 100);

使用 TileSprite #

javascript
const background = this.add.tileSprite(400, 300, 800, 600, 'pattern');

update() {
  background.tilePositionX += 1;
}

剔除优化 #

javascript
layer.setCullPadding(2, 2);

layer.skipCull = false;

深度排序优化 #

javascript
this.children.sort('depth');

const config = {
  type: Phaser.WEBGL,
  preserveDrawingBuffer: false
};

内存优化 #

对象池 #

javascript
class Bullet extends Phaser.Physics.Arcade.Sprite {
  constructor(scene, x, y) {
    super(scene, x, y, 'bullet');
  }
  
  fire(x, y, velocityX, velocityY) {
    this.setPosition(x, y);
    this.setActive(true);
    this.setVisible(true);
    this.setVelocity(velocityX, velocityY);
  }
  
  deactivate() {
    this.setActive(false);
    this.setVisible(false);
    this.setVelocity(0, 0);
  }
}

create() {
  this.bullets = this.physics.add.group({
    classType: Bullet,
    maxSize: 50,
    runChildUpdate: true
  });
}

fireBullet() {
  const bullet = this.bullets.get();
  if (bullet) {
    bullet.fire(this.player.x, this.player.y, 0, -300);
  }
}

update() {
  this.bullets.children.iterate((bullet) => {
    if (bullet && bullet.active && bullet.y < 0) {
      bullet.deactivate();
    }
  });
}

资源管理 #

javascript
preload() {
  this.load.image('level1', 'assets/level1.png');
}

loadLevel2() {
  this.textures.remove('level1');
  this.load.image('level2', 'assets/level2.png');
  this.load.start();
}

shutdown() {
  this.textures.remove('levelTexture');
  this.cache.audio.remove('levelMusic');
}

避免内存泄漏 #

javascript
create() {
  this.timer = this.time.addEvent({
    delay: 1000,
    callback: this.updateTimer,
    callbackScope: this,
    loop: true
  });
  
  this.input.keyboard.on('keydown-SPACE', this.jump, this);
  
  this.events.on('customEvent', this.handleEvent, this);
}

shutdown() {
  this.timer.remove();
  
  this.input.keyboard.off('keydown-SPACE', this.jump, this);
  
  this.events.off('customEvent', this.handleEvent, this);
  
  this.children.removeAll(true);
}

纹理管理 #

javascript
const texture = this.textures.createCanvas('dynamic', 64, 64);
texture.destroy();

this.textures.remove('unusedTexture');

const texture = this.textures.get('player');
texture.setFilter(Phaser.Textures.FilterMode.NEAREST);

逻辑优化 #

减少计算量 #

javascript
update() {
  const playerX = this.player.x;
  const playerY = this.player.y;
  
  this.enemies.children.iterate((enemy) => {
    const dx = playerX - enemy.x;
    const dy = playerY - enemy.y;
    const distance = Math.sqrt(dx * dx + dy * dy);
    
    if (distance < 200) {
      enemy.setVelocity(dx / distance * 100, dy / distance * 100);
    }
  });
}

update() {
  const playerX = this.player.x;
  const playerY = this.player.y;
  const threshold = 200;
  const thresholdSq = threshold * threshold;
  
  this.enemies.children.iterate((enemy) => {
    const dx = playerX - enemy.x;
    const dy = playerY - enemy.y;
    const distanceSq = dx * dx + dy * dy;
    
    if (distanceSq < thresholdSq) {
      const distance = Math.sqrt(distanceSq);
      enemy.setVelocity(dx / distance * 100, dy / distance * 100);
    }
  });
}

空间分区 #

javascript
class SpatialHash {
  constructor(cellSize) {
    this.cellSize = cellSize;
    this.grid = new Map();
  }
  
  clear() {
    this.grid.clear();
  }
  
  getKey(x, y) {
    const cellX = Math.floor(x / this.cellSize);
    const cellY = Math.floor(y / this.cellSize);
    return `${cellX},${cellY}`;
  }
  
  insert(gameObject) {
    const key = this.getKey(gameObject.x, gameObject.y);
    
    if (!this.grid.has(key)) {
      this.grid.set(key, []);
    }
    
    this.grid.get(key).push(gameObject);
  }
  
  getNearby(x, y, radius) {
    const results = [];
    const cellRadius = Math.ceil(radius / this.cellSize);
    const centerCellX = Math.floor(x / this.cellSize);
    const centerCellY = Math.floor(y / this.cellSize);
    
    for (let dx = -cellRadius; dx <= cellRadius; dx++) {
      for (let dy = -cellRadius; dy <= cellRadius; dy++) {
        const key = `${centerCellX + dx},${centerCellY + dy}`;
        const cell = this.grid.get(key);
        
        if (cell) {
          results.push(...cell);
        }
      }
    }
    
    return results;
  }
}

create() {
  this.spatialHash = new SpatialHash(100);
}

update() {
  this.spatialHash.clear();
  
  this.enemies.children.iterate((enemy) => {
    this.spatialHash.insert(enemy);
  });
  
  const nearby = this.spatialHash.getNearby(this.player.x, this.player.y, 200);
}

碰撞优化 #

javascript
this.physics.world.setBounds(0, 0, 800, 600);

this.physics.world.OVERLAP_BIAS = 4;

this.physics.world.TILE_BIAS = 16;

this.physics.add.collider(this.player, this.platforms, null, (player, platform) => {
  return player.y < platform.y;
}, this);

更新优化 #

javascript
update() {
  if (!this.isActive) return;
  
  this.updatePlayer();
  this.updateEnemies();
  this.updateProjectiles();
}

updateEnemies() {
  if (this.enemies.children.size === 0) return;
  
  this.enemies.children.iterate((enemy) => {
    if (!enemy.active) return;
    
    enemy.update();
  });
}

资源优化 #

图片优化 #

javascript
const config = {
  type: Phaser.AUTO,
  render: {
    pixelArt: true,
    antialias: false,
    roundPixels: true
  }
};

preload() {
  this.load.image('player', 'assets/player.png');
}

create() {
  this.player = this.add.image(100, 100, 'player');
  this.player.setTexture('player');
}

音频优化 #

javascript
preload() {
  this.load.audio('bgm', [
    'assets/audio/bgm.mp3',
    'assets/audio/bgm.ogg'
  ]);
}

create() {
  this.bgm = this.sound.add('bgm', {
    volume: 0.5,
    loop: true
  });
}

延迟加载 #

javascript
preload() {
  this.load.image('essential', 'assets/essential.png');
}

create() {
  this.load.once('complete', () => {
    console.log('Additional assets loaded');
  });
  
  this.load.image('extra', 'assets/extra.png');
  this.load.start();
}

移动端优化 #

缩放优化 #

javascript
const config = {
  type: Phaser.AUTO,
  scale: {
    mode: Phaser.Scale.FIT,
    autoCenter: Phaser.Scale.CENTER_BOTH,
    width: 800,
    height: 600
  }
};

触摸优化 #

javascript
const config = {
  input: {
    activePointers: 3,
    touch: {
      capture: true
    }
  }
};

this.input.addDownCallback(() => {
  if (this.sound.locked) {
    this.sound.unlock();
  }
});

降低分辨率 #

javascript
const config = {
  type: Phaser.AUTO,
  width: 400,
  height: 300,
  zoom: 2
};

最佳实践 #

场景管理 #

javascript
class GameScene extends Phaser.Scene {
  shutdown() {
    this.events.off('customEvent');
    
    this.timer.remove();
    
    this.tweens.killAll();
    
    this.children.removeAll(true);
    
    this.physics.world.shutdown();
  }
}

配置优化 #

javascript
const config = {
  type: Phaser.WEBGL,
  width: 800,
  height: 600,
  backgroundColor: '#000000',
  render: {
    pixelArt: true,
    antialias: false,
    roundPixels: true,
    transparent: false,
    clearBeforeRender: true,
    preserveDrawingBuffer: false,
    premultipliedAlpha: true,
    failIfMajorPerformanceCaveat: false,
    powerPreference: 'high-performance'
  },
  physics: {
    default: 'arcade',
    arcade: {
      gravity: { y: 0 },
      debug: false
    }
  },
  audio: {
    disableWebAudio: false
  },
  fps: {
    target: 60,
    forceSetTimeOut: false,
    deltaHistory: 10
  }
};

下一步 #

现在你已经掌握了性能优化,接下来学习 高级主题,了解游戏开发的最佳实践!

最后更新:2026-03-29