Voltar para o Blog
Quest Log

Logica de Programacao para Jogos: o Basico

Mesa de estudo com notebook mostrando codigo de jogo e rascunhos de fluxograma ao lado

Aprenda logica de programacao para jogos do zero com exemplos tipados em GDScript. Variaveis, condicionais, loops, funcoes e o ciclo de frame.

Ferramenta:Godot

Logica de Programacao para Jogos: o Basico

Todo jogo, do Pong ao Elden Ring, roda em cima das mesmas ideias. Antes de qualquer motor ou arte, existe a logica de programacao para jogos: guardar valores, tomar decisoes, repetir tarefas e atualizar o mundo a cada instante. Se voce nunca programou, essa parte parece o muro mais alto. A boa noticia e que os fundamentos sao poucos e voce consegue enxergar cada um deles dentro de um jogo de verdade. Neste texto eu explico esses fundamentos com exemplos curtos em GDScript, a linguagem da Godot, sempre com os tipos declarados para o codigo ficar claro.

Nao vou te encher de teoria abstrata. Cada conceito aqui vem colado a uma cena de jogo: a barra de vida, o dano de um inimigo, a lista de itens do inventario, a horda que aparece na tela. Quando voce liga o conceito ao que acontece no jogo, ele para de ser decoreba e vira ferramenta.

Variaveis e tipos: onde o jogo guarda o estado

Uma variavel e um nome que guarda um valor. No jogo, ela guarda tudo que muda ou que precisa ser lembrado: a vida do player, a pontuacao, a posicao, se a porta esta aberta. Em GDScript voce cria uma variavel com var e, para deixar tudo explicito, declara o tipo dela.

var vida: int = 100
var nome: String = "Heroi"
var velocidade: float = 250.0
var vivo: bool = true

Repare nos tipos. int guarda numero inteiro (vida, municao, moedas). float guarda numero com casa decimal (velocidade, tempo, dano). String guarda texto (nome, dialogo). bool guarda verdadeiro ou falso, o famoso liga e desliga (o player esta vivo? o pulo esta disponivel?). Declarar o tipo nao e frescura: a Godot passa a te avisar quando voce tenta, por exemplo, somar texto com numero, e o codigo fica mais rapido. Para quem esta aprendendo, o tipo ainda funciona como um bilhete que diz o que cada variavel carrega.

Existe tambem o Vector2, um tipo que guarda dois numeros de uma vez, x e y. Ele aparece o tempo todo em jogo 2D porque posicao, velocidade e direcao vivem em duas dimensoes.

var posicao: Vector2 = Vector2(320.0, 180.0)
var direcao: Vector2 = Vector2(1.0, 0.0)

Se essa ideia de x e y ainda esta nebulosa, vale um mergulho depois em matematica para jogos e vetores, porque quase todo movimento no seu jogo vai passar por ali. Por enquanto, basta saber que um Vector2 e um par de numeros que a gente trata como um so.

Condicionais: como o jogo toma decisoes

Um jogo esta sempre perguntando coisas. O player levou dano, ainda esta vivo? A tecla de pulo foi apertada? O inimigo encostou no player? Toda pergunta que resulta em "faz isso ou faz aquilo" e uma condicional, o famoso if.

A estrutura e simples: se uma condicao for verdadeira, roda um bloco; senao, roda outro. Veja como aplicar dano e checar morte:

func receber_dano(dano: int) -> void:
    vida -= dano
    if vida <= 0:
        vida = 0
        morrer()
    else:
        print("Vida restante: ", vida)

Leia em voz alta e vira quase portugues: "vida menos dano; se a vida for menor ou igual a zero, zera a vida e morre; senao, mostra a vida restante". Os sinais de comparacao sao o coracao disso: == (igual), != (diferente), <, >, <=, >=. Cuidado com um erro classico de iniciante: = atribui um valor, == compara dois valores. Trocar um pelo outro e a fonte de metade dos bugs no comeco.

Voce tambem combina condicoes com and e or. 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:
        print("Pulou!")
    else:
        print("Nao da pra pular agora")

Quando existem varios caminhos, o elif (senao se) encadeia as perguntas. Pense num sistema que reage ao nivel de vida:

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

Cada if, elif e else desenha um galho da decisao. Ganhar fluencia em desenhar esses galhos e o que separa quem programa de quem copia.

Loops: quando o jogo precisa repetir

Muita coisa em jogo acontece em quantidade. Voce nao spawna um inimigo, spawna dez. Voce nao olha um item do inventario, percorre a lista inteira. Repetir uma tarefa varias vezes e trabalho de loop, e os dois principais sao for e while.

O for repete um numero conhecido de vezes ou percorre uma colecao. Para criar uma horda:

func spawnar_inimigos(quantidade: int) -> void:
    for i in range(quantidade):
        var inimigo: Node2D = cena_inimigo.instantiate()
        inimigo.position = Vector2(100.0 * i, 0.0)
        add_child(inimigo)

Aqui range(quantidade) gera a sequencia de numeros e o for roda o bloco uma vez para cada um. A cada volta, i muda (0, 1, 2...), e usamos esse i para espalhar os inimigos na horizontal. Percorrer o inventario segue a mesma ideia, so que iterando direto sobre a lista:

var inventario: Array[String] = ["espada", "pocao", "chave"]

func listar_itens() -> void:
    for item in inventario:
        print("Item: ", item)

Note o tipo Array[String]: uma lista que so aceita texto. Declarar o conteudo da lista evita que um numero solto entre ali por engano.

O while e diferente: ele repete enquanto uma condicao for verdadeira, sem saber de antemao quantas vezes. Serve para "continue fazendo isso ate mudar".

func gastar_municao(tiros: int) -> void:
    var restante: int = tiros
    while restante > 0:
        print("Bang! Municao: ", restante)
        restante -= 1

Cuidado dobrado com o while: se a condicao nunca virar falsa, o loop roda para sempre e o jogo trava. Sempre garanta que algo dentro do bloco caminhe para o fim (aqui, o restante -= 1).

Se voce ja travou tentando montar um desses loops, ou se ja se pegou colando codigo de um tutorial sem entender por que funciona, saiba que isso e absolutamente normal no comeco. O problema e parar por ai. A logica so gruda quando voce escreve, erra, conserta e ve o resultado rodar. E ai que um caminho guiado economiza meses de tentativa e erro solitario.

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

Funcoes tipadas: dando nome aos pedacos do jogo

Voce ja viu varias funcoes acima. Uma funcao e um bloco de codigo com nome, que voce chama quando precisar. Ela agrupa uma tarefa (receber dano, pular, spawnar) para voce nao repetir as mesmas linhas espalhadas pelo projeto. Em GDScript, uma funcao tipada declara o tipo de cada parametro e o tipo do que ela devolve.

func calcular_dano(base: int, multiplicador: float) -> int:
    var total: float = base * multiplicador
    return int(total)

Traduzindo a primeira linha: a funcao se chama calcular_dano, recebe um base inteiro e um multiplicador decimal, e devolve (->) um inteiro. O return entrega o resultado para quem chamou. Quando a funcao so faz uma acao e nao devolve nada, o tipo de retorno e void, como no receber_dano la de cima.

Funcoes que devolvem bool sao otimas para perguntas, e deixam os if limpos de ler:

func pode_atacar(cooldown: float) -> bool:
    return cooldown <= 0.0

func processar_ataque(cooldown: float) -> void:
    if pode_atacar(cooldown):
        print("Ataque liberado")

Perceba como o nome da funcao vira quase uma frase: "se pode atacar, ataque". Codigo bem fatiado em funcoes com bons nomes e mais facil de ler que qualquer comentario.

O ciclo de atualizacao: o jogo roda quadro a quadro

Aqui esta a ideia que amarra tudo e que costuma ser a virada de chave para iniciantes. Um jogo nao roda do inicio ao fim como uma receita e acabou. Ele desenha a tela dezenas de vezes por segundo, e cada uma dessas telas e um frame (quadro). A cada frame, o jogo pergunta: onde estao as coisas agora? o que mudou? o que desenho?

Na Godot, o codigo que precisa rodar todo frame vai dentro de _process ou _physics_process. E ali que a logica de movimento, colisao e regras acontece de forma continua.

extends CharacterBody2D

var velocidade: float = 250.0

func _physics_process(delta: float) -> void:
    var direcao: Vector2 = Input.get_vector("esquerda", "direita", "cima", "baixo")
    velocity = direcao * velocidade
    move_and_slide()

Esse bloco roda a cada quadro de fisica. Ele le a direcao do teclado, calcula a velocidade e move o personagem. O parametro delta e o tempo (em segundos) que passou desde o frame anterior; multiplicar valores por delta mantem o movimento igual em qualquer computador, seja rapido ou lento. Esses nodes como CharacterBody2D sao os blocos de montar da Godot, e vale entender como os nodes do Godot funcionam para ligar sua logica na cena certa.

Junte as pecas e o jogo inteiro aparece: variaveis guardam o estado (vida, posicao), condicionais decidem o que fazer com esse estado, loops processam grupos de coisas, funcoes organizam as acoes, e o ciclo de frame repete tudo isso muitas vezes por segundo para dar a ilusao de um mundo vivo. Nenhuma dessas ideias e exclusiva da Godot. Elas aparecem em qualquer motor e em qualquer linguagem de jogo.

Por falar em linguagem, uma duvida comum de quem comeca na Godot e se deve usar GDScript ou C#. Se voce estiver nesse dilema, vale ler a comparacao entre C# e GDScript no Godot antes de investir tempo em uma delas. Para aprender logica, porem, GDScript e o caminho mais curto: menos cerimonia, feedback rapido e integracao direta com o editor.

Por onde seguir

Os fundamentos que voce viu aqui, variaveis tipadas, condicionais, loops, funcoes e o ciclo de atualizacao, sao o alfabeto da logica de programacao para jogos. Dominar esse alfabeto nao significa decorar a sintaxe, e sim conseguir olhar para uma mecanica de jogo e enxergar quais dessas pecas ela usa. Um inimigo que persegue o player? Variavel de posicao, condicional para escolher a direcao, ciclo de frame para mover. Um sistema de loja? Lista de itens, loop para exibir, funcao para comprar, condicional para checar o dinheiro.

O proximo passo e simples de dizer e trabalhoso de fazer: abra a Godot e escreva codigo. Comece com um quadrado que anda com as setas. Depois faca ele perder vida ao encostar em algo. Depois spawne tres inimigos com um loop. Cada pequeno projeto exercita um fundamento diferente, e em poucas semanas essas pecas param de parecer conceito e viram reflexo. A logica nao entra pela leitura, entra pela mao.

Perguntas frequentes

Preciso saber matematica pra aprender logica de programacao para jogos?

Nao no comeco. O basico de logica usa soma, subtracao e comparacao, coisas que voce ja faz no dia a dia. Vetores e trigonometria entram depois, quando o jogo pede movimento em diagonal ou mira.

Por que os exemplos usam GDScript com tipos?

Declarar o tipo (var vida: int = 100) faz a Godot avisar seus erros antes de rodar e deixa o codigo mais rapido. Para quem esta aprendendo, o tipo tambem documenta o que cada variavel guarda.

Qual a diferenca entre um if e um loop?

O if decide se um bloco roda uma vez, com base numa condicao. O loop repete um bloco varias vezes, seja um numero fixo (for) ou enquanto algo for verdadeiro (while). Um controla escolha, o outro controla repeticao.