一、粒子系统动画开发
粒子动画通过大量微小元素的运动创造复杂视觉效果,如雨雪、火焰、爆炸等自然现象。
1. 基础粒子系统实现
import particle from '@ohos.graphics.particle';
import { BusinessError } from '@ohos.base';
@Component
struct ParticleAnimationExample {
@State particles: Array<ParticleData> = [];
private animationFrame: number = 0;
private readonly particleCount: number = 100;
aboutToAppear() {
this.initParticles();
this.startAnimation();
}
aboutToDisappear() {
this.stopAnimation();
}
// 初始化粒子数据
private initParticles(): void {
for (let i = 0; i < this.particleCount; i++) {
this.particles.push({
id: i,
x: Math.random() * 360,
y: Math.random() * 640,
size: Math.random() * 5 + 1,
color: this.getRandomColor(),
velocityX: (Math.random() - 0.5) * 2,
velocityY: Math.random() * 3 + 1,
rotation: Math.random() * 360,
life: 1.0,
decay: Math.random() * 0.01 + 0.005
});
}
}
// 获取随机颜色
private getRandomColor(): string {
const colors = ['#FF5252', '#FF4081', '#E040FB', '#7C4DFF', '#536DFE', '#448AFF', '#40C4FF', '#18FFFF'];
return colors[Math.floor(Math.random() * colors.length)];
}
// 启动动画循环
private startAnimation(): void {
const animate = () => {
this.updateParticles();
this.animationFrame = requestAnimationFrame(animate);
};
this.animationFrame = requestAnimationFrame(animate);
}
// 停止动画
private stopAnimation(): void {
if (this.animationFrame) {
cancelAnimationFrame(this.AnimationFrame);
}
}
// 更新粒子状态
private updateParticles(): void {
for (let i = 0; i < this.particles.length; i++) {
const particle = this.particles[i];
// 更新位置
particle.x += particle.velocityX;
particle.y += particle.velocityY;
// 更新生命周期
particle.life -= particle.decay;
// 重置死亡粒子
if (particle.life <= 0 || particle.y > 640) {
particle.x = Math.random() * 360;
particle.y = -10;
particle.life = 1.0;
particle.velocityX = (Math.random() - 0.5) * 2;
particle.velocityY = Math.random() * 3 + 1;
}
}
}
build() {
Canvas(this.getContext())
.width('100%')
.height('100%')
.onReady(() => {
this.drawParticles();
})
}
// 绘制粒子
private drawParticles(): void {
const context = this.getContext();
context.clearRect(0, 0, 360, 640);
this.particles.forEach(particle => {
if (particle.life > 0) {
context.globalAlpha = particle.life;
context.beginPath();
context.arc(particle.x, particle.y, particle.size, 0, Math.PI * 2);
context.fillStyle = particle.color;
context.fill();
}
});
context.globalAlpha = 1.0;
}
}
interface ParticleData {
id: number;
x: number;
y: number;
size: number;
color: string;
velocityX: number;
velocityY: number;
rotation: number;
life: number;
decay: number;
}
2. 高级粒子发射器
创建可配置的粒子发射器系统:
class ParticleEmitter {
private particles: ParticleData[] = [];
private isRunning: boolean = false;
private emissionRate: number = 10; // 每秒发射粒子数
private lastEmissionTime: number = 0;
// 发射器配置
config: EmitterConfig = {
position: { x: 180, y: 320 },
spread: 45, // 发射角度范围
minVelocity: 1,
maxVelocity: 5,
minSize: 1,
maxSize: 8,
minLife: 0.5,
maxLife: 2.0,
colors: ['#FF5722', '#FF9800', '#FFEB3B', '#4CAF50', '#2196F3'],
emissionType: 'continuous' // continuous 或 burst
};
// 发射粒子
emit(): void {
const now = Date.now();
const elapsed = now - this.lastEmissionTime;
const particlesToEmit = Math.floor((elapsed / 1000) * this.emissionRate);
for (let i = 0; i < particlesToEmit; i++) {
const angle = (Math.random() * this.config.spread - this.config.spread / 2) * Math.PI / 180;
const velocity = Math.random() * (this.config.maxVelocity - this.config.minVelocity) + this.config.minVelocity;
this.particles.push({
id: Date.now() + i,
x: this.config.position.x,
y: this.config.position.y,
size: Math.random() * (this.config.maxSize - this.config.minSize) + this.config.minSize,
color: this.config.colors[Math.floor(Math.random() * this.config.colors.length)],
velocityX: Math.cos(angle) * velocity,
velocityY: Math.sin(angle) * velocity,
rotation: Math.random() *

最低0.47元/天 解锁文章
11万+

被折叠的 条评论
为什么被折叠?



