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