Voltar para o Blog
Quest Log

Condicionais no GDScript: if, elif, else e match

Tela do editor da Godot com codigo GDScript de decisao de estado de um inimigo

Aprenda condicionais no GDScript com exemplos de jogo: if, elif, else, operadores de comparacao e logicos, o match do Godot 4 e os erros de iniciante.

Ferramenta:Godot

Condicionais no GDScript: if, elif, else e match

Todo jogo vive tomando decisoes. O player levou dano, ainda esta vivo? A tecla de pulo foi apertada? O inimigo esta patrulhando, perseguindo ou atacando? Cada uma dessas perguntas termina em "faz isso ou faz aquilo", e e exatamente disso que trata este texto. Dominar as condicionais no GDScript e o que permite o seu jogo reagir ao que acontece na tela, em vez de rodar sempre igual. Aqui a gente vai do if mais simples ate o match do Godot 4, sempre com exemplos que rodam dentro de um jogo de verdade, e sempre com o codigo tipado como manda a casa.

Se voce ainda esta assentando os primeiros passos, vale ter a base de logica de programacao para jogos fresca, porque condicional sem nocao de fluxo vira decoreba. Aqui a gente parte do principio de que voce ja sabe criar uma variavel tipada e quer aprender a decidir com ela.

O if: a decisao mais basica de um jogo

Um if roda um bloco de codigo somente quando uma condicao for verdadeira. A estrutura le quase como portugues: se tal coisa, faca tal outra. Veja um caso classico, aplicar dano e checar se o player morreu:

var vida: int = 100

func receber_dano(dano: int) -> void:
    vida -= dano
    if vida <= 0:
        vida = 0
        morrer()

Traduzindo: subtrai o dano da vida; se a vida ficou menor ou igual a zero, zera a vida e chama a funcao de morte. Repare que o bloco do if so roda quando a condicao bate. Se a vida continuar positiva, o jogo simplesmente segue em frente. Nesse exemplo nao precisamos de mais nada, um if sozinho resolve.

O coracao de qualquer if sao os operadores de comparacao, que devolvem verdadeiro ou falso. Vale ter os seis na ponta da lingua:

vida == 0    # igual a
vida != 0    # diferente de
vida < 30    # menor que
vida > 30    # maior que
vida <= 0    # menor ou igual a
vida >= 100  # maior ou igual a

Guarde bem essa distincao, porque ela gera o bug numero um de iniciante: = atribui um valor a uma variavel, enquanto == compara dois valores. Escrever if vida = 0 esta errado, o certo dentro de uma condicao e if vida == 0. A Godot avisa nesse caso, mas o erro aparece tanto que vale gravar agora: dentro de if, quase sempre voce quer o ==.

if, elif e else: escolhendo entre varios caminhos

Um if sozinho decide entre fazer ou nao fazer. Quando existe uma acao clara para o caso contrario, entra o else, o "senao". E quando ha varios caminhos possiveis, o elif (contracao de "senao se") encadeia as perguntas. Pense num sistema que classifica o estado do player pela vida:

func estado_do_player() -> String:
    if vida > 70:
        return "saudavel"
    elif vida > 30:
        return "ferido"
    else:
        return "critico"

A Godot testa as condicoes de cima para baixo e para na primeira que for verdadeira. Se a vida for 80, devolve "saudavel" e nem olha o resto. Se for 50, pula o primeiro, cai no elif e devolve "ferido". Se for 10, os dois primeiros falham e sobra o else. Essa ordem importa: como cada galho so e testado se o anterior falhou, voce pode escrever elif vida > 30 sem repetir "e menor que 70", porque nesse ponto ja se sabe que a vida nao passou de 70.

O else e opcional. Se voce nao precisa de uma acao para o caso falso, deixe de fora. Mas quando existe uma escolha do tipo "ou isso ou aquilo", ter o else deixa a intencao explicita e evita que um caso escape sem tratamento.

Operadores logicos: combinando condicoes

Muitas decisoes de jogo dependem de mais de uma coisa ao mesmo tempo. Para isso existem os operadores logicos and, or e not. O and exige que as duas condicoes sejam verdadeiras, o or aceita qualquer uma, e o not inverte um valor booleano.

Um exemplo tipico: so deixar o player pular se ele estiver no chao e ainda tiver folego.

func tentar_pular(no_chao: bool, folego: int) -> void:
    if no_chao and folego > 0:
        pular()
    else:
        print("Nao da pra pular agora")

Com and, as duas partes precisam bater. Se o player estiver no ar, ou se o folego for zero, o pulo nao acontece. Ja o or serve para "basta uma". Imagine uma porta que abre com a chave certa ou com um comando de mestre ligado:

func pode_abrir(tem_chave: bool, modo_mestre: bool) -> bool:
    return tem_chave or modo_mestre

O not inverte. Ele e util para deixar a leitura natural, tipo travar a acao enquanto uma pausa estiver ativa:

func pode_agir(em_pausa: bool) -> bool:
    return not em_pausa

Uma dica de clareza: quando uma condicao comeca a virar um emaranhado de and e or, extraia ela para uma funcao com nome, do jeito que fizemos com pode_abrir e pode_agir. O if fica limpo de ler e a intencao aparece no nome. Se ainda tem duvida sobre declarar os tipos desses parametros e retornos, o artigo sobre variaveis e tipos no GDScript fecha essa base.

Truthiness e o estilo ternario

No GDScript, um if nao aceita so comparacoes explicitas, ele aceita valores que sao interpretados como verdadeiros ou falsos. Isso e o que se chama de truthiness. Um numero diferente de zero e verdadeiro, o zero e falso. Uma String vazia e falsa, uma com texto e verdadeira. E, importante para jogo, um objeto que existe e verdadeiro, enquanto null (nada) e falso.

var alvo: Node2D

func _physics_process(delta: float) -> void:
    if alvo:
        perseguir(alvo)

Escrever if alvo equivale a perguntar "existe um alvo?". Enquanto alvo for null, o bloco nao roda, e assim que ele apontar para um node de verdade, a perseguicao comeca. Isso evita o erro de tentar mexer num objeto que ainda nao existe.

Para decisoes curtas que so escolhem entre dois valores, o GDScript tem uma forma enxuta, o if de uma linha, que faz o papel do ternario de outras linguagens:

var velocidade: float = 400.0 if correndo else 200.0

Le-se da esquerda para a direita: a velocidade e 400 se correndo for verdadeiro, senao e 200. Para uma escolha simples assim, essa linha unica e mais clara que um if de quatro linhas so para atribuir um valor. Use com parcimonia: se a logica cresce, volte para o if normal, que respira melhor.

Se voce ja se pegou empilhando if dentro de if dentro de if e se perdendo no proprio codigo, saiba que isso e a dor mais comum de quem esta aprendendo sozinho. O problema quase nunca e falta de inteligencia, e falta de um caminho que mostre a ordem certa de aprender cada peca.

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

O match: o switch do Godot 4

Quando um unico valor decide varios caminhos, encadear muitos elif fica repetitivo. Para esse caso existe o match, o equivalente ao switch de outras linguagens. Ele compara um valor contra uma lista de casos e roda o bloco do primeiro que casar. O exemplo mais natural em jogo e a maquina de estados de um inimigo.

enum Estado { PATRULHA, PERSEGUINDO, ATACANDO, MORTO }

var estado: Estado = Estado.PATRULHA

func atualizar_ia() -> void:
    match estado:
        Estado.PATRULHA:
            patrulhar()
        Estado.PERSEGUINDO:
            perseguir_player()
        Estado.ATACANDO:
            atacar()
        Estado.MORTO:
            pass
        _:
            print("Estado desconhecido")

O match estado olha o valor de estado e desce comparando com cada caso. Se for PERSEGUINDO, roda so o bloco de perseguir e para ali, sem testar os outros. Repare no underline _ no final: ele e o caso curinga, o "qualquer outra coisa", que funciona como um else do match. E uma rede de seguranca para valores que voce nao previu.

O match brilha com outros valores tambem. Para reagir ao tipo de item que o player pegou:

func usar_item(tipo: String) -> void:
    match tipo:
        "pocao":
            curar(30)
        "bomba":
            explodir()
        "chave":
            guardar_chave()
        _:
            print("Item sem efeito: ", tipo)

E um recurso bacana do match do GDScript e agrupar varios casos numa linha so, separados por virgula. Pense em mapear teclas de movimento:

func reagir_tecla(tecla: String) -> void:
    match tecla:
        "a", "seta_esquerda":
            mover(-1)
        "d", "seta_direita":
            mover(1)
        _:
            pass

Aqui tanto "a" quanto "seta_esquerda" caem no mesmo bloco. Isso deixa o codigo enxuto quando varias entradas levam ao mesmo resultado. Como regra de bolso: use if quando a decisao envolve condicoes livres e combinadas (vida, distancia, folego, tudo junto), e use match quando um unico valor, como o estado ou o tipo, define o caminho. Os dois convivem no mesmo script sem problema.

Aninhando decisoes sem se perder

Condicionais podem morar dentro de condicionais, e isso e comum. Um inimigo que so ataca se o player estiver por perto e de frente combina distancia e alinhamento:

func decidir_acao(distancia: float, de_frente: bool) -> void:
    if distancia <= 120.0:
        if de_frente:
            atacar()
        else:
            virar_para_o_player()
    else:
        perseguir_player()

Funciona, mas quanto mais niveis de aninhamento, mais dificil fica de ler. Um truque util e o retorno antecipado: trate os casos de saida primeiro e evite empilhar. O mesmo comportamento com menos identacao fica assim:

func decidir_acao(distancia: float, de_frente: bool) -> void:
    if distancia > 120.0:
        perseguir_player()
        return
    if not de_frente:
        virar_para_o_player()
        return
    atacar()

Cada if resolve um caso e sai com return. Quem le desce a lista de situacoes sem precisar rastrear qual chave fecha qual bloco. Nao existe regra absoluta, mas quando o aninhamento passa de dois ou tres niveis, quase sempre da para achatar assim.

Erros de iniciante que valem evitar

Alem do = no lugar de ==, tem outros tropecos que aparecem toda semana em quem esta comecando. O primeiro e a identacao. No GDScript, o que define o que esta dentro do if e o recuo com Tab, nao chaves. Se voce alinhar errado, um comando pode acabar rodando sempre, fora da condicao, sem a Godot acusar erro. Mantenha a identacao consistente, sempre com Tab, e olhe com atencao o que esta alinhado com o que.

O segundo e esquecer os dois pontos no fim da linha do if, do elif, do else e de cada caso do match. Sem os dois pontos, o codigo nao roda. O terceiro e comparar float com == esperando precisao exata. Numeros decimais podem ter arredondamentos minusculos, entao em vez de if energia == 0.0 prefira if energia <= 0.0, que e mais seguro para valores que descem por subtracao.

Por fim, uma escolha de linguagem que aparece cedo: quem vem de outras linguagens as vezes estranha a sintaxe do GDScript e pensa em usar C#. Se for o seu caso, a comparacao entre C# e GDScript no Godot ajuda a decidir sem achismo. Para aprender condicionais e logica, porem, o GDScript e o caminho mais curto, com feedback rapido dentro do editor.

Por onde seguir

As condicionais no GDScript sao o mecanismo que faz o seu jogo reagir. O if, o elif e o else decidem com base em qualquer condicao, os operadores and, or e not combinam essas condicoes, o truthiness deixa checagens de existencia curtas, e o match organiza a escolha quando um unico valor define o caminho. Nenhuma dessas ideias e exclusiva da Godot, elas aparecem em qualquer motor e linguagem, so muda a escrita.

O jeito de fixar e o de sempre: abra a Godot e escreva. Faca um quadrado que muda de cor quando a vida passa de um limite. Coloque um inimigo com tres estados controlados por um match. Crie um inventario que reage ao tipo de item. Cada pequeno teste transforma a sintaxe em reflexo, e em pouco tempo voce vai olhar para uma mecanica e ja enxergar qual condicional ela pede. A decisao, no jogo e no aprendizado, vem da pratica.

Perguntas frequentes

Qual a diferenca entre if e match no GDScript?

O if avalia qualquer condicao verdadeira ou falsa, inclusive combinacoes com and e or. O match compara um unico valor contra varios casos possiveis, tipo o estado de um inimigo. Use if para condicoes livres e match quando um so valor decide varios caminhos.

Por que meu if nao funciona e a Godot reclama de erro?

O erro mais comum e trocar == por =. O sinal = atribui um valor, o == compara dois valores. Dentro de um if voce quase sempre quer comparar, entao use ==. A Godot avisa quando voce tenta atribuir onde deveria comparar.

Preciso sempre escrever o else?

Nao. O else e opcional. Se voce so quer rodar um bloco quando a condicao for verdadeira e nao fazer nada no caso contrario, um if sozinho basta. O else entra quando existe uma acao clara para o caso falso.