Phaser 粒子系统 #

粒子系统概述 #

粒子系统用于创建各种视觉效果,如火焰、烟雾、爆炸、魔法等。

text
┌─────────────────────────────────────────────────────────────┐
│                    粒子系统架构                              │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  ParticleEmitter                                            │
│  ├── 粒子属性                                              │
│  │   ├── 位置、速度、加速度                                │
│  │   ├── 大小、颜色、透明度                                │
│  │   └── 生命周期                                          │
│  ├── 发射配置                                              │
│  │   ├── 发射速率                                          │
│  │   ├── 发射区域                                          │
│  │   └── 发射方向                                          │
│  └── 粒子行为                                              │
│      ├── 重力影响                                          │
│      ├── 碰撞检测                                          │
│      └── 随时间变化                                        │
│                                                             │
└─────────────────────────────────────────────────────────────┘

创建粒子 #

基本粒子 #

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

create() {
  const emitter = this.add.particles(400, 300, 'particle', {
    speed: { min: -100, max: 100 },
    scale: { start: 1, end: 0 },
    lifespan: 2000
  });
}

粒子配置 #

javascript
const emitter = this.add.particles(400, 300, 'particle', {
  speed: { min: 100, max: 200 },
  angle: { min: 0, max: 360 },
  scale: { start: 1, end: 0 },
  alpha: { start: 1, end: 0 },
  tint: [0xff0000, 0x00ff00, 0x0000ff],
  lifespan: 2000,
  frequency: 100,
  quantity: 1,
  blendMode: 'ADD'
});

发射器属性 #

位置 #

javascript
const emitter = this.add.particles(400, 300, 'particle', {});

emitter.setPosition(200, 150);

emitter.x = 400;
emitter.y = 300;

emitter.setEmitterAngle(45);

emitter.setRadial(true);

发射区域 #

javascript
const emitter = this.add.particles(400, 300, 'particle', {
  emitZone: {
    type: 'random',
    source: new Phaser.Geom.Rectangle(-100, -100, 200, 200)
  }
});

const emitter = this.add.particles(400, 300, 'particle', {
  emitZone: {
    type: 'random',
    source: new Phaser.Geom.Circle(0, 0, 100)
  }
});

const emitter = this.add.particles(400, 300, 'particle', {
  emitZone: {
    type: 'edge',
    source: new Phaser.Geom.Ellipse(0, 0, 200, 100),
    quantity: 48
  }
});

const emitter = this.add.particles(400, 300, 'particle', {
  emitZone: {
    type: 'random',
    source: new Phaser.Geom.Line(-100, 0, 100, 0)
  }
});

死亡区域 #

javascript
const emitter = this.add.particles(400, 300, 'particle', {
  deathZone: {
    type: 'onEnter',
    source: new Phaser.Geom.Rectangle(0, 0, 800, 600)
  }
});

const emitter = this.add.particles(400, 300, 'particle', {
  deathZone: {
    type: 'onLeave',
    source: new Phaser.Geom.Circle(400, 300, 200)
  }
});

速度与方向 #

javascript
const emitter = this.add.particles(400, 300, 'particle', {
  speed: { min: 100, max: 200 }
});

const emitter = this.add.particles(400, 300, 'particle', {
  speed: 100
});

const emitter = this.add.particles(400, 300, 'particle', {
  speedX: { min: -100, max: 100 },
  speedY: { min: -100, max: 100 }
});

const emitter = this.add.particles(400, 300, 'particle', {
  angle: { min: 0, max: 360 }
});

const emitter = this.add.particles(400, 300, 'particle', {
  angle: { min: 80, max: 100 }
});

const emitter = this.add.particles(400, 300, 'particle', {
  angle: 90,
  speed: 100
});

缩放 #

javascript
const emitter = this.add.particles(400, 300, 'particle', {
  scale: { start: 1, end: 0 }
});

const emitter = this.add.particles(400, 300, 'particle', {
  scale: { start: 0.5, end: 2 }
});

const emitter = this.add.particles(400, 300, 'particle', {
  scale: { min: 0.5, max: 1.5 }
});

const emitter = this.add.particles(400, 300, 'particle', {
  scaleX: { start: 1, end: 0 },
  scaleY: { start: 1, end: 2 }
});

透明度 #

javascript
const emitter = this.add.particles(400, 300, 'particle', {
  alpha: { start: 1, end: 0 }
});

const emitter = this.add.particles(400, 300, 'particle', {
  alpha: { start: 0.5, end: 0 }
});

const emitter = this.add.particles(400, 300, 'particle', {
  alpha: { min: 0.3, max: 1 }
});

颜色 #

javascript
const emitter = this.add.particles(400, 300, 'particle', {
  tint: 0xff0000
});

const emitter = this.add.particles(400, 300, 'particle', {
  tint: [0xff0000, 0x00ff00, 0x0000ff]
});

const emitter = this.add.particles(400, 300, 'particle', {
  color: [0xff0000, 0xffff00, 0x00ff00]
});

const emitter = this.add.particles(400, 300, 'particle', {
  colorEase: 'Quad.easeOut'
});

生命周期 #

javascript
const emitter = this.add.particles(400, 300, 'particle', {
  lifespan: 2000
});

const emitter = this.add.particles(400, 300, 'particle', {
  lifespan: { min: 1000, max: 3000 }
});

发射频率 #

javascript
const emitter = this.add.particles(400, 300, 'particle', {
  frequency: 100
});

const emitter = this.add.particles(400, 300, 'particle', {
  frequency: -1
});

const emitter = this.add.particles(400, 300, 'particle', {
  frequency: 100,
  quantity: 5
});

混合模式 #

javascript
const emitter = this.add.particles(400, 300, 'particle', {
  blendMode: 'ADD'
});

const emitter = this.add.particles(400, 300, 'particle', {
  blendMode: 'MULTIPLY'
});

const emitter = this.add.particles(400, 300, 'particle', {
  blendMode: 'SCREEN'
});

粒子行为 #

重力 #

javascript
const emitter = this.add.particles(400, 300, 'particle', {
  gravityY: 200
});

const emitter = this.add.particles(400, 300, 'particle', {
  gravityX: 50,
  gravityY: 100
});

加速度 #

javascript
const emitter = this.add.particles(400, 300, 'particle', {
  accelerationY: 200
});

const emitter = this.add.particles(400, 300, 'particle', {
  accelerationX: { min: -100, max: 100 },
  accelerationY: 200
});

旋转 #

javascript
const emitter = this.add.particles(400, 300, 'particle', {
  rotate: { min: 0, max: 360 }
});

const emitter = this.add.particles(400, 300, 'particle', {
  rotate: { start: 0, end: 360 }
});

const emitter = this.add.particles(400, 300, 'particle', {
  angularVelocity: 45
});

随机属性 #

javascript
const emitter = this.add.particles(400, 300, 'particle', {
  speed: () => Phaser.Math.Between(100, 200),
  scale: () => Math.random(),
  tint: () => Phaser.Math.RND.pick([0xff0000, 0x00ff00, 0x0000ff])
});

发射器控制 #

启动与停止 #

javascript
const emitter = this.add.particles(400, 300, 'particle', {
  frequency: -1
});

emitter.start();

emitter.start(100);

emitter.stop();

emitter.stop(true);

emitter.pause();

emitter.resume();

emitter.active = false;
emitter.active = true;

爆发发射 #

javascript
const emitter = this.add.particles(400, 300, 'particle', {
  frequency: -1
});

emitter.explode(50);

emitter.explode(50, 400, 300);

emitter.explode(50, pointer.x, pointer.y);

流式发射 #

javascript
const emitter = this.add.particles(400, 300, 'particle', {
  frequency: -1
});

emitter.flow(100, 5);

emitter.flow(100, 5, 100);

emitter.flow(100, 5, -1);

清除粒子 #

javascript
emitter.killAll();

emitter.remove();

粒子跟随 #

跟随游戏对象 #

javascript
const emitter = this.add.particles(400, 300, 'particle', {
  follow: this.player
});

emitter.startFollow(this.player);

emitter.startFollow(this.player, 0, 0, 0.1);

emitter.stopFollow();

粒子碰撞 #

边界碰撞 #

javascript
const emitter = this.add.particles(400, 300, 'particle', {
  bounce: 0.5,
  bounds: new Phaser.Geom.Rectangle(0, 0, 800, 600)
});

emitter.setParticleBounds(new Phaser.Geom.Rectangle(0, 0, 800, 600));
emitter.setParticleBounce(0.8);

碰撞回调 #

javascript
const emitter = this.add.particles(400, 300, 'particle', {
  collideBottom: true,
  collideLeft: true,
  collideRight: true,
  collideTop: true
});

预设效果 #

火焰效果 #

javascript
createFire(x, y) {
  return this.add.particles(x, y, 'particle', {
    speed: { min: 50, max: 100 },
    angle: { min: -30, max: 30 },
    scale: { start: 1, end: 0 },
    alpha: { start: 1, end: 0 },
    tint: [0xffcc00, 0xff6600, 0xff0000],
    lifespan: 1000,
    frequency: 50,
    blendMode: 'ADD',
    gravityY: -100
  });
}

烟雾效果 #

javascript
createSmoke(x, y) {
  return this.add.particles(x, y, 'particle', {
    speed: { min: 20, max: 50 },
    angle: { min: -20, max: 20 },
    scale: { start: 0.5, end: 2 },
    alpha: { start: 0.5, end: 0 },
    tint: 0x888888,
    lifespan: 3000,
    frequency: 200,
    blendMode: 'MULTIPLY',
    gravityY: -30
  });
}

爆炸效果 #

javascript
createExplosion(x, y) {
  return this.add.particles(x, y, 'particle', {
    speed: { min: 200, max: 400 },
    angle: { min: 0, max: 360 },
    scale: { start: 1, end: 0 },
    alpha: { start: 1, end: 0 },
    tint: [0xffcc00, 0xff6600, 0xff0000],
    lifespan: 500,
    frequency: -1,
    quantity: 50,
    blendMode: 'ADD'
  }).explode(50);
}

魔法效果 #

javascript
createMagic(x, y) {
  return this.add.particles(x, y, 'particle', {
    speed: { min: 50, max: 100 },
    angle: { min: 0, max: 360 },
    scale: { start: 0.5, end: 0 },
    alpha: { start: 1, end: 0 },
    tint: [0x00ffff, 0x00ff00, 0xff00ff],
    lifespan: 1500,
    frequency: 100,
    blendMode: 'ADD',
    rotate: { min: 0, max: 360 }
  });
}

雪花效果 #

javascript
createSnow() {
  return this.add.particles(400, -50, 'snowflake', {
    x: { min: -400, max: 400 },
    speed: { min: 20, max: 50 },
    angle: { min: 80, max: 100 },
    scale: { min: 0.5, max: 1 },
    alpha: { start: 1, end: 0.5 },
    lifespan: 10000,
    frequency: 100,
    gravityY: 50,
    rotate: { min: -180, max: 180 }
  });
}

星星效果 #

javascript
createStars(x, y) {
  return this.add.particles(x, y, 'star', {
    speed: { min: 100, max: 200 },
    angle: { min: 0, max: 360 },
    scale: { start: 0.8, end: 0 },
    alpha: { start: 1, end: 0 },
    lifespan: 800,
    frequency: -1,
    quantity: 20,
    blendMode: 'ADD',
    rotate: { min: 0, max: 360 }
  }).explode(20);
}

粒子管理器 #

创建粒子管理器 #

javascript
const manager = this.add.particles('particle');

const emitter1 = manager.createEmitter({
  x: 100,
  y: 100,
  speed: { min: -100, max: 100 },
  scale: { start: 1, end: 0 },
  lifespan: 2000
});

const emitter2 = manager.createEmitter({
  x: 300,
  y: 100,
  speed: { min: -100, max: 100 },
  scale: { start: 1, end: 0 },
  lifespan: 2000
});

完整示例 #

粒子效果管理器 #

javascript
class ParticleManager {
  constructor(scene) {
    this.scene = scene;
    this.emitters = {};
  }
  
  preload() {
    this.scene.load.image('particle', 'assets/particle.png');
    this.scene.load.image('spark', 'assets/spark.png');
  }
  
  createFire(x, y) {
    const emitter = this.scene.add.particles(x, y, 'particle', {
      speed: { min: 50, max: 100 },
      angle: { min: -30, max: 30 },
      scale: { start: 1, end: 0 },
      alpha: { start: 1, end: 0 },
      tint: [0xffcc00, 0xff6600, 0xff0000],
      lifespan: 1000,
      frequency: 50,
      blendMode: 'ADD',
      gravityY: -100
    });
    
    return emitter;
  }
  
  createExplosion(x, y) {
    const emitter = this.scene.add.particles(x, y, 'spark', {
      speed: { min: 200, max: 400 },
      angle: { min: 0, max: 360 },
      scale: { start: 1, end: 0 },
      alpha: { start: 1, end: 0 },
      tint: [0xffcc00, 0xff6600, 0xff0000],
      lifespan: 500,
      frequency: -1,
      blendMode: 'ADD'
    });
    
    emitter.explode(50);
    
    this.scene.time.delayedCall(1000, () => {
      emitter.destroy();
    });
    
    return emitter;
  }
  
  createTrail(target) {
    const emitter = this.scene.add.particles(0, 0, 'particle', {
      follow: target,
      speed: 0,
      scale: { start: 0.5, end: 0 },
      alpha: { start: 0.5, end: 0 },
      tint: 0x00ffff,
      lifespan: 500,
      frequency: 20,
      blendMode: 'ADD'
    });
    
    return emitter;
  }
  
  createCollectEffect(x, y) {
    const emitter = this.scene.add.particles(x, y, 'spark', {
      speed: { min: 100, max: 200 },
      angle: { min: 0, max: 360 },
      scale: { start: 0.8, end: 0 },
      alpha: { start: 1, end: 0 },
      tint: 0xffff00,
      lifespan: 500,
      frequency: -1,
      blendMode: 'ADD'
    });
    
    emitter.explode(20);
    
    this.scene.time.delayedCall(600, () => {
      emitter.destroy();
    });
    
    return emitter;
  }
}

class GameScene extends Phaser.Scene {
  create() {
    this.particles = new ParticleManager(this);
    
    this.fire = this.particles.createFire(400, 500);
    
    this.input.on('pointerdown', (pointer) => {
      this.particles.createExplosion(pointer.x, pointer.y);
    });
    
    this.player = this.physics.add.sprite(100, 100, 'player');
    this.trail = this.particles.createTrail(this.player);
  }
}

下一步 #

现在你已经掌握了粒子系统,接下来学习 游戏组,了解如何高效管理游戏对象!

最后更新:2026-03-29