# Sistema de partículas

Os sistemas de partículas permitem criar efeitos visuais dinâmicos emitindo e animando grandes quantidades de pequenos sprites. Use-os para criar fogo, fumo, chuva, neve, faíscas, auras mágicas, explosões e muitos outros efeitos que seriam impraticáveis de conseguir com meshes estáticos.

## Adicionar um sistema de partículas

Para adicionar um sistema de partículas à tua scene, cria uma entity e anexa-lhe o `ParticleSystem` component.

```ts
import { engine, Transform, ParticleSystem } from '@dcl/sdk/ecs'
import { Vector3 } from '@dcl/sdk/math'

const emitter = engine.addEntity()

Transform.create(emitter, {
	position: Vector3.create(8, 1, 8),
})

ParticleSystem.create(emitter, {})
```

Sem propriedades definidas, o component usa todos os valores por defeito: um emissor pontual que lança 10 partículas por segundo para cima, com uma vida útil da partícula de 5 segundos.

## Formas do emissor

A forma do emissor determina onde as partículas aparecem. Quatro formas estão disponíveis através dos `ParticleSystem.Shape` helpers.

### Point

As partículas aparecem a partir de um único ponto (a posição da entity). Este é o valor por defeito quando nenhuma forma é especificada.

```ts
ParticleSystem.create(emitter, {
	shape: ParticleSystem.Shape.Point(),
})
```

### Sphere

As partículas aparecem a partir da superfície ou do interior de uma esfera.

```ts
ParticleSystem.create(emitter, {
	shape: ParticleSystem.Shape.Sphere({ radius: 2 }),
})
```

### Cone

As partículas aparecem a partir da base de um cone e deslocam-se para fora na direção do cone. `angle` é o semiângulo em graus; `radius` é o raio da base em metros. Para orientar a direção do cone, define a rotação do `Transform`.

```ts
ParticleSystem.create(emitter, {
	da entity.
})
```

### Box

As partículas aparecem a partir de qualquer ponto dentro de um volume em caixa.

```ts
ParticleSystem.create(emitter, {
	shape: ParticleSystem.Shape.Box({ size: Vector3.create(3, 1, 3) }),
})
```

## Propriedades de emissão

Controla quantas partículas são criadas e quanto tempo vivem.

| Propriedade    | Padrão | Descrição                                               |
| -------------- | ------ | ------------------------------------------------------- |
| `rate`         | `10`   | Partículas emitidas por segundo (contínuo).             |
| `maxParticles` | `1000` | Limite máximo de partículas vivas simultaneamente.      |
| `lifetime`     | `5`    | Tempo de vida de cada partícula em segundos.            |
| `active`       | `true` | Se o sistema está a emitir ativamente novas partículas. |

```ts
ParticleSystem.create(emitter, {
	rate: 50,
	maxParticles: 500,
	lifetime: 3,
})
```

## Movimento

### Gravidade

O `gravity` property é um multiplicador aplicado à gravidade da scene (-9.81 m/s²). Define-o como `0` para fazer as partículas flutuar no lugar, um valor negativo para as empurrar para cima, ou um valor positivo para as acelerar para baixo.

```ts
ParticleSystem.create(emitter, {
	gravity: -0.5, // as partículas flutuam lentamente para cima
})
```

### Velocidade inicial

`initialVelocitySpeed` é um `FloatRange` que define um mínimo e um máximo para o intervalo de velocidade aleatória com que cada partícula é lançada (em m/s). Ambos os valores têm o valor por defeito de `1`.

```ts
import { Vector2 } from '@dcl/sdk/math'

ParticleSystem.create(emitter, {
	initialVelocitySpeed: { start: 2, end: 8 },
})
```

### Força adicional

Uma força constante vetorial aplicada a todas as partículas em cada frame, além da gravidade. Útil para efeitos de vento ou magnéticos.

```ts
ParticleSystem.create(emitter, {
	additionalForce: Vector3.create(0.5, 0, 0), // impulso lateral constante
})
```

### Limitação de velocidade

Usa `limitVelocity` para limitar a velocidade máxima das partículas e, opcionalmente, amortecer o excesso de velocidade em cada frame.

```ts
ParticleSystem.create(emitter, {
	limitVelocity: {
		speed: 5, // velocidade máxima permitida em m/s
		dampen: 0.8, // fração do excesso de velocidade removida por frame
	},
})
```

## Propriedades visuais

### Cor

`initialColor` define a cor da partícula ao nascer; `colorOverTime` define a cor no final da sua vida útil. Ambos aceitam um `ColorRange` com um valor `from` e `to` — a cor real no nascimento/morte é escolhida aleatoriamente dentro desse intervalo.

```ts
import { Color4 } from '@dcl/sdk/math'

ParticleSystem.create(emitter, {
	initialColor: {
		start: Color4.create(1, 0.5, 0, 1), // laranja
		end: Color4.create(1, 1, 0, 1), // amarelo
	},
	colorOverTime: {
		start: Color4.create(0.5, 0, 0, 0.5), // vermelho escuro, meio transparente
		end: Color4.create(0, 0, 0, 0), // totalmente transparente (desvanecer)
	},
})
```

Nota que o 4.º valor num `Color4` é o *alpha*. Se definires a cor final para uma com alpha 0, as partículas vão desvanecer gradualmente e tornar-se invisíveis, o que é muitas vezes um bom efeito.

### Tamanho

`initialSize` e `sizeOverTime` são `FloatRange` values que controlam a escala da partícula no nascimento e na morte, respetivamente. Um valor de `1` é igual ao tamanho original da textura.

```ts
ParticleSystem.create(emitter, {
	initialSize: { start: 0.1, end: 0.3 },
	sizeOverTime: { start: 0.5, end: 1.0 }, // crescer ao longo da vida
})
```

{% hint style="warning" %}
**📔 Nota**: A `scale` do `Transform` da entity não afeta a escala das partículas.
{% endhint %}

### Texture

Por defeito, as partículas são renderizadas como quadrados brancos. Fornece uma texture para usar uma imagem personalizada.

```ts
ParticleSystem.create(emitter, {
	texture: { src: 'assets/scene/Images/spark.png' },
})
```

### Modo de blending

Controla como a cor da partícula é combinada com a scene atrás dela.

| Valor                                  | Descrição                                                                   |
| -------------------------------------- | --------------------------------------------------------------------------- |
| `ParticleSystemBlendMode.PSB_ALPHA`    | Transparência padrão (por defeito).                                         |
| `ParticleSystemBlendMode.PSB_ADD`      | Blending aditivo — as partículas iluminam a scene. Bom para fogo e brilhos. |
| `ParticleSystemBlendMode.PSB_MULTIPLY` | Multiplica a cor da partícula com a scene atrás dela.                       |

```ts
import { ParticleSystemBlendMode } from '@dcl/sdk/ecs'

ParticleSystem.create(emitter, {
	texture: { src: 'assets/scene/textures/ember.png' },
	blendMode: ParticleSystemBlendMode.PSB_ADD,
})
```

### Billboard

Quando `billboard` é `true` (o valor por defeito), cada partícula enfrenta sempre a camera, independentemente da orientação do emissor. Define-o como `false` para partículas que devem rodar no espaço 3D.

```ts
ParticleSystem.create(emitter, {
	billboard: false,
})
```

## Rotação

### Rotação inicial e rotação ao longo do tempo

`initialRotation` é a orientação de uma partícula quando aparece. `rotationOverTime` é uma velocidade angular por eixo aplicada a cada segundo. Ambos aceitam um `Quaternion`.

```ts
import { Quaternion } from '@dcl/sdk/math'

ParticleSystem.create(emitter, {
	initialRotation: Quaternion.fromEulerDegrees(0, 0, 45),
	rotationOverTime: Quaternion.fromEulerDegrees(0, 0, 90), // rodar 90°/s no eixo Z
})
```

{% hint style="warning" %}
**📔 Nota**: Se `billboard` for definido como `true`, então as partículas só vão rodar num eixo, mantendo sempre a orientação voltada para a camera.
{% endhint %}

### Face travel direction

Quando `faceTravelDirection` é `true`, cada partícula roda automaticamente para apontar na direção do seu movimento, como um asteroide ou uma folha a cair pelo ar.

```ts
ParticleSystem.create(emitter, {
	faceTravelDirection: true,
	billboard: false,
})
```

{% hint style="warning" %}
**📔 Nota**: Se `faceTravelDirection` for true, o valor de `billboard` é ignorado.
{% endhint %}

## Animação de sprite sheet

Podes animar partículas tratando uma texture como uma grelha de frames de animação. Especifica o número de colunas e linhas na sheet e a velocidade de reprodução.

```ts
ParticleSystem.create(emitter, {
	texture: { src: 'assets/scene/textures/flame-sheet.png' },
	spriteSheet: {
		tilesX: 4, // 4 colunas
		tilesY: 3, // 3 linhas  (12 frames no total)
		framesPerSecond: 12,
	},
})
```

## Controlo de reprodução

O sistema de partículas pode estar num dos três estados controlados por `playbackState`.

| Valor                                    | Descrição                                                     |
| ---------------------------------------- | ------------------------------------------------------------- |
| `ParticleSystemPlaybackState.PS_PLAYING` | A emitir ativamente (por defeito).                            |
| `ParticleSystemPlaybackState.PS_PAUSED`  | Congela todas as partículas atuais no lugar e para a emissão. |
| `ParticleSystemPlaybackState.PS_STOPPED` | Pára a emissão e remove todas as partículas existentes.       |

```ts
import { ParticleSystemPlaybackState } from '@dcl/sdk/ecs'

// Pausar quando o player se afasta
ParticleSystem.getMutable(emitter).playbackState =
	ParticleSystemPlaybackState.PS_PAUSED

// Retomar
ParticleSystem.getMutable(emitter).playbackState =
	ParticleSystemPlaybackState.PS_PLAYING
```

### Loop e prewarm

Por defeito, o sistema repete-se indefinidamente. Define `loop` to `false` para um efeito único que para automaticamente depois de todas as partículas morrerem.

Define `prewarm` to `true` (requer `loop: true`) para simular o sistema como se estivesse a funcionar desde o início, para que as partículas já preencham a scene quando o player a vê pela primeira vez.

```ts
ParticleSystem.create(emitter, {
	loop: false, // reproduzir uma vez e depois parar
	prewarm: false,
})
```

## Emissão em burst

Os bursts permitem emitir uma grande quantidade de partículas em momentos específicos em vez de a uma taxa constante. São úteis para explosões, fogo de artifício ou outros eventos únicos.

Um único sistema de partículas pode passar por um ciclo com vários bursts, até com intervalos ou probabilidades variáveis, para parecer mais natural.

```ts
ParticleSystem.create(emitter, {
	rate: 0, // desativar emissão contínua
	bursts: {
		values: [
			{
				time: 0, // tempo em segundos após o início da reprodução
				count: 200, // partículas a emitir por burst
				cycles: 1, // quantas vezes repetir (0 = infinito)
				interval: 0.2, // segundos entre ciclos repetidos
				probability: 1, // probabilidade de 0–1 de o burst disparar em cada ciclo
			},
		],
	},
})
```

Para um efeito de fogo de artifício em loop com bursts desencontrados:

```ts
ParticleSystem.create(emitter, {
	loop: true,
	rate: 0,
	lifetime: 2,
	bursts: {
		values: [
			{ time: 0.0, count: 80, cycles: 0, interval: 3 },
			{ time: 0.7, count: 100, cycles: 0, interval: 3 },
			{ time: 1.4, count: 60, cycles: 0, interval: 3 },
		],
	},
})
```

## Espaço de simulação

Controla se as partículas se movem em relação ao emissor (`PSS_LOCAL`, por defeito) ou permanecem fixas em coordenadas do mundo depois de aparecerem (`PSS_WORLD`).

Usa `PSS_WORLD` para um emissor em movimento que deve deixar um rasto atrás de si (por exemplo, um asteroide ou um foguete).

```ts
import { ParticleSystemSimulationSpace } from '@dcl/sdk/ecs'

ParticleSystem.create(emitter, {
	simulationSpace: ParticleSystemSimulationSpace.PSS_WORLD,
})
```

## Desempenho

O engine impõe um orçamento de partículas por scene e irá reduzir automaticamente as taxas de emissão em todos os sistemas de partículas ativos na scene se a contagem total de partículas exceder o limite. Planeia as tuas scenes em conformidade:

* Prefere menos sistemas com impacto visual forte em vez de muitos sistemas com pouco impacto.
* Usa `maxParticles` para limitar sistemas individuais.
* Usa `active` ou `playbackState` para desativar sistemas que estão fora do ecrã ou fora do alcance.
* Valores `lifetime` curtos mantêm a contagem de partículas vivas inferior ao que uma emissão elevada `rate` por si só sugere.

O engine limita o número máximo de partículas renderizadas em qualquer momento a 1000. Se estiveres a emitir mais partículas do que isso, podes não estar a vê-las todas.

Tem também em mente que as partículas só podem ser vistas por um player enquanto este estiver dentro da tua scene. Players que estiverem a olhar para a scene do exterior não verão partículas até entrarem nela.

## Particle Lab

Entra no mundo [ParticleLab.dcl.eth](decentraland://?realm=particlelab.dcl.eth\&dclenv=org) para experimentar diferentes sistemas de partículas. Quando te aproximares de um sistema de partículas, a UI irá mostrar todos os campos disponíveis; podes ajustá-los em tempo real sem precisares de recarregar a scene. Quando estiveres satisfeito, clica no **Copy** button para copiar o código desse sistema de partículas para a tua área de transferência.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.decentraland.org/creator/content-creator-pt/scenes-sdk7/essenciais-de-conteudo-3d/particle-system.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
