Voltar para o Blog
Quest Log

Partículas no Godot 4: Efeitos com GPUParticles2D Passo a Passo

Cena de jogo 2D com jato de faíscas laranja e nuvem de fumaça cinza saindo de um ponto de impacto

Partículas no Godot 4 na prática: aprenda GPUParticles2D e CPUParticles2D para fazer fogo, fumaça, explosão, poeira e faíscas com código tipado.

O que são partículas no Godot e por que usar

Partículas no Godot são pequenos elementos que nascem, se movem, mudam de cor e morrem sozinhos, tudo controlado por um único node. Em vez de você animar cada faísca de uma explosão à mão, você configura regras (velocidade, gravidade, tempo de vida) e o motor gera dezenas ou milhares de cópias seguindo essas regras. É assim que se faz fogo, fumaça, poeira, faíscas de impacto, respingo de água e brilho mágico sem desenhar frame por frame.

No Godot 4 você tem dois nodes para isso no 2D: o GPUParticles2D e o CPUParticles2D. Eles fazem quase a mesma coisa visualmente, mas por caminhos diferentes. Este guia mostra quando usar cada um, como funciona o material que dá vida às partículas, a diferença entre disparo único e contínuo, como acionar tudo por código tipado e quatro receitas prontas que você copia e adapta: explosão, fumaça, poeira ao andar e faíscas de impacto.

GPUParticles2D vs CPUParticles2D: qual escolher

A diferença está em quem faz a conta.

O GPUParticles2D empurra o cálculo para a placa de vídeo. A GPU processa milhares de partículas em paralelo, então o custo para a CPU do jogo fica baixíssimo. É a escolha padrão para desktop e a maioria dos celulares modernos. A configuração vive num ParticleProcessMaterial.

O CPUParticles2D calcula tudo no processador. Ele aguenta menos partículas antes de pesar, mas tem duas vantagens reais: roda em hardware antigo ou dispositivos que não lidam bem com os shaders de partícula, e suporta colisão 2D de verdade contra o mundo do jogo. Quando esse cálculo pesado precisa mesmo rodar na CPU sem travar o quadro, a saída é empurrar o trabalho para outra thread, como mostra o guia de multithreading com WorkerThreadPool na Godot. Se você precisa que a poeira bata no chão físico da cena, o CPU resolve.

Regra prática: comece sempre com GPUParticles2D. Só troque para CPUParticles2D se testar num aparelho fraco e as partículas sumirem ou travarem, ou se precisar de colisão física real. O bom é que o Godot tem um atalho: com o GPUParticles2D selecionado, o menu do editor oferece "Convert to CPUParticles2D", que recria o efeito quase idêntico no outro node. Você monta uma vez e converte se precisar.

Uma dica de fluxo: se você ainda está juntando seu kit de trabalho, vale conhecer as ferramentas gratuitas para criar jogos antes de mergulhar fundo nos efeitos, porque o Godot combina bem com editores de imagem e som livres para gerar as texturas das partículas. E se criar efeitos te fisgar de verdade, saiba que existe uma profissão inteira nisso: o que faz um artista de VFX de jogos.

Anatomia do ParticleProcessMaterial

O GPUParticles2D sozinho não faz nada. Ele precisa de um ParticleProcessMaterial atribuído na propriedade Process Material do inspetor. Esse material é onde mora todo o comportamento. Vale entender os grupos principais:

Emission (emissão). Define de onde as partículas nascem. O padrão é um ponto, mas você pode escolher uma forma de emissão (Emission Shape) como esfera ou caixa para espalhar o nascimento numa área. Para fumaça larga, uma caixa achatada funciona bem.

Direction e Spread (direção e abertura). A direção base para onde as partículas vão e o ângulo de espalhamento em graus. Spread 0 lança tudo reto; spread 180 joga para todos os lados, ideal para explosão.

Gravity (gravidade). Um vetor que puxa as partículas. Para fumaça você inverte a gravidade padrão e coloca um valor negativo no Y para subir. Para faíscas caindo, gravidade positiva no Y.

Initial Velocity (velocidade inicial). A força com que cada partícula sai. Tem valor mínimo e máximo, então cada partícula ganha uma velocidade aleatória na faixa, o que evita aquele visual robótico de tudo igual.

Scale (escala). O tamanho das partículas, também com faixa mínima e máxima. Uma curva de escala (Scale Curve) permite crescer ou encolher ao longo da vida, ótimo para explosão que incha e some.

Color e Color Ramp (cor e gradiente). Você pode dar uma cor fixa ou, melhor, um Gradient na propriedade color_ramp. A partícula percorre esse gradiente durante o lifetime. Fogo que vai de amarelo para vermelho para transparente sai daqui. Colocar o alpha caindo para zero no fim do gradiente faz a partícula desaparecer suave em vez de piscar.

No próprio node (não no material) ficam três valores que você mexe o tempo todo: amount (quantas partículas existem), lifetime (quantos segundos cada uma vive) e emitting (se está emitindo agora ou não).

Próximo nível
Quer aprender isso na prática?

No CursoGame.Dev você sai dos tutoriais soltos e constrói jogos publicáveis, com trilha progressiva, quests práticas e feedback real.

Conhecer a plataforma
+500 alunos4.9/5Garantia 7 dias

one_shot vs contínuo: rajada ou fluxo

A propriedade one_shot do node decide o ritmo da emissão.

Com one_shot desligado (o padrão), a emissão é contínua. O node fica soltando partículas em loop enquanto emitting estiver ligado. É o comportamento certo para fogo de tocha, fumaça de chaminé, brilho de um item mágico, qualquer coisa que dura.

Com one_shot ligado, o node solta um lote de partículas de uma vez e para. É o comportamento de explosão, salto de poeira, respingo de sangue: um evento único disparado num instante. Depois de emitir o lote, o emitting volta sozinho para false.

Entender isso é o que separa um efeito que funciona de um que fica travado no loop. Explosão sempre com one_shot ligado.

Disparar partículas no Godot por código

Aqui entra o GDScript. Você raramente deixa o efeito emitindo desde o início; normalmente dispara no momento certo. Duas ferramentas resolvem quase tudo:

  • emitting = true / emitting = false liga e desliga a emissão contínua.
  • restart() reinicia a emissão do zero, o que é a forma correta de disparar um one_shot.

Referencie o node com @onready tipado para o código ficar seguro e legível:

extends Node2D

@onready var explosao: GPUParticles2D = $Explosao
@onready var fumaca: GPUParticles2D = $Fumaca

func _ready() -> void:
    # fumaca comeca ligada e continua, explosao fica em espera
    fumaca.emitting = true
    explosao.emitting = false

func disparar_explosao() -> void:
    # one_shot ligado no inspetor: restart() solta o lote uma vez
    explosao.restart()

O restart() é importante porque, num one_shot, apenas setar emitting = true pode não redisparar se o efeito já rodou. O restart() zera o estado interno e garante a nova rajada toda vez.

Receita 1: explosão com one_shot

Crie um GPUParticles2D, atribua um ParticleProcessMaterial e no inspetor:

  • one_shot: ligado
  • amount: 24
  • lifetime: 0.6
  • emitting: desligado (só dispara por código)
  • No material: Spread 180, Initial Velocity entre 120 e 260, Gravity Y por volta de 200, Scale Curve caindo para zero e um color_ramp de branco para laranja para transparente.

No código, dispare no ponto do impacto:

extends Node2D

@onready var explosao: GPUParticles2D = $Explosao

func explodir_em(posicao: Vector2) -> void:
    explosao.global_position = posicao
    explosao.restart()

Você move o node para onde o inimigo morreu e chama restart(). Como é one_shot, ele solta 24 partículas de uma vez, elas incham, caem com a gravidade e somem em 0.6 segundo. Para as faíscas de fato estourarem de luz na tela, em vez de ficarem opacas, combine a explosão com o efeito de glow e bloom da Godot: partículas brilhantes acima do limiar de brilho ganham aquele halo que vende o impacto.

Receita 2: fumaça contínua

Fumaça é o oposto: fluxo lento, para cima, sem parar. Num GPUParticles2D:

  • one_shot: desligado
  • amount: 16
  • lifetime: 2.5
  • No material: Gravity Y negativo (algo como -40) para subir, Initial Velocity baixa entre 10 e 30, Spread pequeno perto de 15, Scale crescendo com o tempo e color_ramp de cinza claro para transparente.

O lifetime longo e a velocidade baixa dão aquele movimento preguiçoso. Ligue e desligue a chaminé por código:

extends Node2D

@onready var fumaca: GPUParticles2D = $Fumaca

func acender_fogueira() -> void:
    fumaca.emitting = true

func apagar_fogueira() -> void:
    fumaca.emitting = false

O mesmo esqueleto vira fogo se você trocar o gradiente para amarelo e vermelho e inverter a escala. Fogo e fumaça costumam ser dois nodes empilhados na mesma posição.

Receita 3: poeira ao andar

Poeira é um efeito que reage ao estado do jogo. A ideia: emitir só quando o personagem se move no chão. Coloque um GPUParticles2D como filho do personagem, apontando para os pés, one_shot desligado, amount baixo, lifetime curto perto de 0.4, Spread pequeno e um pouco de gravidade positiva.

No script do personagem, ligue a emissão pela velocidade:

extends CharacterBody2D

@onready var poeira: GPUParticles2D = $Poeira

func _physics_process(_delta: float) -> void:
    var andando: bool = is_on_floor() and absf(velocity.x) > 10.0
    poeira.emitting = andando

Enquanto o personagem corre no chão, a poeira sai dos pés; quando ele para ou pula, para na hora. Esse padrão de ligar emitting por uma condição serve para trilha de nave, rastro de habilidade e muito mais. Se você curte esse tipo de efeito ambiental, vale ver como um sistema de clima com chuva no Godot usa a mesma lógica de partículas em escala de cena inteira.

Receita 4: faíscas de impacto

Faíscas são uma explosão pequena, rápida e brilhante, disparada quando algo bate em algo. É one_shot, amount entre 8 e 16, lifetime curto perto de 0.4, Spread médio perto de 60 (as faíscas saltam mais na direção do impacto que para todo lado), Initial Velocity alta, gravidade positiva e um color_ramp branco para amarelo para transparente.

Dispare no ponto e, se quiser, aponte a direção da batida:

extends Node2D

@onready var faiscas: GPUParticles2D = $Faiscas

func bater(ponto: Vector2, direcao: Vector2) -> void:
    faiscas.global_position = ponto
    faiscas.rotation = direcao.angle()
    faiscas.restart()

Girar o node com rotation faz o leque de faíscas apontar para onde o golpe veio, o que vende muito melhor a sensação de impacto do que faíscas saltando iguais para todo lado.

Dicas de performance

Partículas no Godot são baratas com GPUParticles2D, mas alguns hábitos evitam quedas de FPS. Se as partículas são só uma parte de um jogo que já está engasgando, vale um passo atrás e um diagnóstico geral com o guia de como otimizar o FPS e a performance na Godot:

  • Não exagere no amount. Antes de subir a quantidade, teste se um número menor com textura melhor já convence. Muitas vezes 20 partículas bem feitas batem 200.
  • Encurte o lifetime. Partícula que vive mais tempo significa mais partículas vivas ao mesmo tempo. Efeitos de impacto podem viver frações de segundo.
  • Reuse o mesmo material. Vários nodes de faísca iguais podem compartilhar um único ParticleProcessMaterial, o que economiza memória.
  • Cuidado com a textura. Uma imagem enorme de partícula multiplicada por centenas pesa. Texturas pequenas de partícula (32 ou 64 pixels) resolvem quase tudo.
  • Desligue o que não está à vista. Efeitos contínuos fora da tela ainda consomem. Deixe emitting = false quando o node sai do campo de visão.

Do efeito ao jogo completo

Dominar partículas transforma o feeling do seu jogo: cada golpe ganha faísca, cada morte ganha explosão, cada passo levanta poeira. E se o seu jogo é 3D, a lógica é a mesma com outro nó: veja como criar partículas 3D com o GPUParticles3D pra levar fumaça, fogo e faísca pro espaço tridimensional. Mas efeito bonito é só uma peça. Um projeto que sai do papel precisa de física, personagem, inimigos, som, telas e a cola que junta tudo, e aprender isso de forma solta pela internet costuma virar um monte de peças que nunca se encaixam.

Se você quer ir do "consigo fazer uma explosão" para o "terminei e publiquei meu jogo", faz diferença seguir uma trilha ordenada. O curso de criação de jogos para iniciantes da CursoGame.Dev pega você desde o básico do Godot e te leva até um jogo jogável, com as partículas no lugar certo e tudo o mais que um jogo de verdade precisa. Comece pelas receitas acima, quebre, conserte, e quando quiser a estrutura completa, o caminho está montado.

Perguntas frequentes

Qual a diferença entre GPUParticles2D e CPUParticles2D?

O GPUParticles2D calcula as partículas na placa de vídeo, aguenta milhares de partículas com custo baixo de CPU e é a escolha padrão. O CPUParticles2D calcula tudo no processador, funciona em hardware antigo ou celulares fracos que travam no shader e permite colisão 2D real com o mundo.

Como disparo uma explosão só uma vez por código no Godot 4?

Ative a propriedade one_shot no inspetor e, no script, chame particulas.restart() no momento do impacto. O restart() reinicia a emissão do zero, dispara o lote de partículas uma única vez e para sozinho.

Minhas partículas não aparecem, o que verificar?

Cheque se a propriedade emitting está ligada, se o node tem um ProcessMaterial atribuído e se o amount e o lifetime são maiores que zero. Sem ProcessMaterial o GPUParticles2D não sabe como mover nada e fica invisível.

Como faço poeira aparecer só quando o personagem anda?

Deixe emitting em false por padrão e ligue via código quando a velocidade horizontal do personagem passar de um limite, desligando quando ele para. Assim o efeito acompanha o movimento sem emitir parado.

Partículas no Godot pesam no desempenho?

GPUParticles2D é barato mesmo com muitas partículas, mas amount alto, texturas grandes e lifetime longo somam custo. Reduza a quantidade, encurte o lifetime e reuse o mesmo material entre nodes iguais para manter o jogo leve.

Preciso de shader ou material especial para colorir as partículas?

Não. O gradiente de cor fica dentro do ParticleProcessMaterial, na propriedade color_ramp. Você monta um Gradient no editor e as partículas mudam de cor ao longo da vida sem escrever shader nenhum.