Jogos em C#: Unity e MonoGame

Jogos em C#: Unity e MonoGame

Como o C# se aplica ao desenvolvimento de jogos: a Unity, que o usa como linguagem de script, e o MonoGame, mais próximo do código. A aula explica o laço de jogo, conceito central de qualquer motor, e é honesta sobre as disciplinas além da programação que fazer jogos exige.
Linguagem C#

• • 12 min de leitura

Fechamos as extensões com o uso mais lúdico e, para muitos, mais empolgante da linguagem: o desenvolvimento de jogos. Talvez surpreenda quem chegou ao C# pensando em aplicações sérias, mas a linguagem é uma das mais importantes da indústria de jogos — principalmente porque a Unity, uma das ferramentas de criação de jogos mais usadas do planeta, adotou o C# como sua linguagem de programação. De jogos independentes a grandes produções comerciais, muito do que você joga tem C# por baixo. Esta aula não vai transformá-lo num desenvolvedor de jogos — isso é uma jornada própria, de meses ou mais —, mas vai mostrar como o C# se aplica a esse mundo, apresentar os conceitos fundamentais que todo jogo compartilha, e conectar tudo aos fundamentos que você já domina. É um convite a uma porta que agora está aberta para você.

Por que C# em jogos: a Unity

A razão central da presença do C# em jogos tem nome: Unity. Uma engine (ou "motor") de jogos é um conjunto de ferramentas que cuida das partes difíceis e comuns a todo jogo — desenhar gráficos na tela, simular física, tocar sons, detectar colisões entre objetos, gerenciar cenas — para que você se concentre na lógica do seu jogo. A Unity é uma das engines mais populares do mundo, especialmente para jogos independentes e para celular, e ela usa o C# como a linguagem em que você escreve o comportamento do jogo. Isso significa que todo o seu conhecimento de C# — objetos, herança, coleções, lógica de decisão e repetição — transfere-se diretamente para a criação de jogos. Você não aprende uma linguagem nova para fazer jogos na Unity; você aplica a que já sabe a um domínio novo e criativo.

O conceito central de todo jogo: o laço de jogo

Existe uma ideia que está no coração de todo jogo, do mais simples ao mais complexo: o laço de jogo (em inglês, game loop). Um programa comum, como os que fizemos no curso, roda de cima a baixo e termina. Um jogo é diferente: ele roda um laço contínuo que se repete muitas vezes por segundo (tipicamente 30 ou 60 vezes — o que chamamos de "quadros por segundo"). A cada volta desse laço — a cada quadro —, o jogo faz três coisas: processa a entrada (o que o jogador apertou), atualiza o estado (move os personagens, calcula a física, verifica colisões), e desenha a tela (mostra o quadro atual). Entrada, atualização, desenho — repetido dezenas de vezes por segundo, criando a ilusão de movimento e interatividade contínua.

        ┌──────────────────────────────┐
        │         LAÇO DE JOGO         │
        │  (60 vezes por segundo)      │
        │                              │
   ┌───▶│  1. Processar a entrada      │
   │    │  2. Atualizar o estado       │
   │    │  3. Desenhar a tela          │
   │    └──────────────┬───────────────┘
   └───────────────────┘  (repete)

Esse laço é a alma de qualquer jogo, e entendê-lo é entender como jogos funcionam por dentro. É, no fundo, um laço de repetição — como o while que você aprendeu — que nunca para enquanto o jogo está aberto, executando essas três etapas a cada volta. Nas engines, você raramente escreve o laço à mão — a engine o roda por você e chama o seu código nos momentos certos —, o que nos leva à forma como a Unity organiza isso.

Como a Unity organiza o código

A Unity usa um modelo baseado em componentes: um objeto do jogo (um personagem, um inimigo, uma moeda) é montado a partir de peças que lhe dão características e comportamentos. Você escreve os comportamentos como scripts em C#, e a Unity os executa dentro do laço de jogo. Um script da Unity é uma classe C# que herda de uma classe da engine (a herança que você aprendeu!), e a engine chama métodos especiais dela automaticamente. Os dois mais importantes: Start, chamado uma vez quando o objeto surge, e Update, chamado a cada quadro — ou seja, dentro do laço de jogo:

using UnityEngine;

// Um script da Unity: herda de MonoBehaviour (herança, da fase de objetos).
public class MovimentoJogador : MonoBehaviour
{
    public float velocidade = 5f;   // ajustável na interface da Unity

    // Start: roda uma vez, quando o objeto entra na cena.
    void Start()
    {
        Debug.Log("Jogador pronto!");   // o "Console.WriteLine" da Unity
    }

    // Update: roda A CADA QUADRO (dentro do laço de jogo).
    void Update()
    {
        // Lê a entrada do teclado e move o objeto.
        float horizontal = Input.GetAxis("Horizontal");
        transform.Translate(horizontal * velocidade * Time.deltaTime, 0, 0);
    }
}

Reconheça o que já sabe: é uma classe que herda de outra (a herança da fase de objetos), com um campo e métodos. A novidade é o contrato com a engine: você não chama o Update — a Unity o chama, uma vez por quadro, dentro do laço de jogo que ela gerencia. Dentro dele, você lê a entrada (Input) e move o objeto (transform.Translate). O Time.deltaTime (o tempo desde o último quadro) garante que o movimento seja suave independentemente da taxa de quadros — um detalhe idiomático de jogos. É o seu C# preenchendo os pontos do laço de jogo que a engine expõe. (A Unity também tem uma parte visual, um editor onde você monta cenas arrastando objetos — mas o comportamento é C#, e é aí que seu conhecimento entra.)

MonoGame: a abordagem mais próxima do código

Nem todo jogo em C# usa a Unity. O MonoGame é uma alternativa mais "crua": em vez de uma engine completa com editor visual, ele é um conjunto de ferramentas que lhe dá o essencial (desenhar, tocar som, ler a entrada) e deixa você escrever o laço de jogo e a estrutura. É mais trabalho, mas dá controle total — e jogos aclamados foram feitos com ele. No MonoGame, o laço de jogo aparece explicitamente, com métodos que você preenche:

// Esqueleto de um jogo em MonoGame: o laço de jogo é explícito.
public class MeuJogo : Game
{
    // Update: a etapa de LÓGICA do laço, chamada a cada quadro.
    protected override void Update(GameTime gameTime)
    {
        // Ler a entrada e atualizar o estado do jogo aqui.
        base.Update(gameTime);
    }

    // Draw: a etapa de DESENHO do laço, chamada a cada quadro.
    protected override void Draw(GameTime gameTime)
    {
        // Desenhar tudo na tela aqui.
        base.Draw(gameTime);
    }
}

Aqui o laço de jogo está à vista: Update (a lógica) e Draw (o desenho), sobrescritos (o override da fase de polimorfismo!) de uma classe-base Game, chamados a cada quadro. A Unity esconde mais e oferece mais ferramentas prontas; o MonoGame expõe mais e dá mais controle. A escolha entre eles é a mesma que atravessa toda a engenharia: mais abstração e produtividade (Unity) versus mais controle e simplicidade conceitual (MonoGame). Para começar e para a maioria dos casos, a Unity é o caminho mais suave; o MonoGame brilha para quem quer entender e controlar cada peça.

Uma nota honesta sobre a jornada dos jogos

Sendo justo com você: fazer jogos é uma disciplina vasta, com desafios próprios que vão muito além da linguagem — o design do jogo (o que o torna divertido), arte, som, física, matemática de vetores e ângulos. Esta aula abre a porta e mostra que o seu C# é a chave que a destranca, mas atravessá-la é uma jornada de aprendizado à parte, com sua própria curva. A boa notícia é que você chega a ela com uma vantagem enorme: a linguagem, que para muitos é o primeiro obstáculo, você já domina. O laço de jogo, os componentes, a herança de uma classe da engine — nada disso é misterioso para quem entende classes, herança e laços. Se jogos são seu interesse, o próximo passo é escolher uma engine (recomendo a Unity para começar), seguir um tutorial de um jogo simples (um jogo da velha, um pequeno jogo de plataforma), e construir. Você tem a base; agora é praticar no novo domínio.

O território dos jogos ficou situado. A Unity usa C# como linguagem de script e é a porta de entrada mais comum, organizando o código em componentes ligados a objetos de cena; o MonoGame oferece a abordagem mais próxima do código, com controle direto e menos estrutura pronta.

O conceito que atravessa qualquer motor é o laço de jogo: a cada quadro, processar entrada, atualizar o estado e desenhar. Compreendê-lo é entender por que jogos são estruturados como são. A nota honesta também fica registrada — fazer jogos acrescenta disciplinas próprias, como arte, som e design, e a programação é apenas uma das frentes dessa jornada.

Fontes e leituras recomendadas

Exercícios

Exercício 1

Explique, com suas palavras, o que é o laço de jogo e as três etapas que ele repete a cada quadro. Por que um jogo precisa desse laço contínuo, enquanto um programa de console comum roda de cima a baixo e termina?

Ver resposta

✓ Resposta: O laço de jogo é um laço contínuo que se repete muitas vezes por segundo (tipicamente 30 ou 60) e, a cada volta (cada quadro), executa três etapas: processar a entrada do jogador, atualizar o estado do jogo (mover objetos, calcular física, verificar colisões) e desenhar a tela. Um jogo precisa desse laço contínuo porque é interativo e dinâmico em tempo real: o mundo do jogo muda constantemente e precisa reagir à entrada e se redesenhar dezenas de vezes por segundo para criar a ilusão de movimento contínuo. Um programa de console comum apenas executa uma sequência de instruções e termina, pois não precisa manter um mundo vivo e responsivo quadro a quadro.

Exercício 2

No script da Unity MovimentoJogador, identifique: qual método roda uma vez e qual roda a cada quadro, de que classe o script herda, e qual conceito da fase de objetos isso ilustra. Explique por que você não chama o Update você mesmo.

Ver resposta

✓ Resposta: No MovimentoJogador, o método Start roda uma vez (quando o objeto entra na cena) e o Update roda a cada quadro. O script herda de MonoBehaviour, o que ilustra a herança da fase de objetos. Você não chama o Update você mesmo porque é a engine (a Unity) que gerencia o laço de jogo e chama esse método automaticamente, uma vez por quadro — o seu código apenas preenche o que deve acontecer em cada quadro, e o controle do laço pertence à engine.

Exercício 3

Explique, com suas palavras, por que a aula afirma que seu conhecimento de C# "transfere-se diretamente" para o desenvolvimento de jogos. O que você não precisaria reaprender ao migrar para jogos?

Ver resposta

✓ Resposta: O conhecimento transfere-se diretamente porque o desenvolvimento de jogos com C# usa a mesma linguagem e os mesmos conceitos que você aprendeu — objetos, herança, coleções, lógica de decisão e repetição, métodos —, apenas aplicados a um domínio novo (criar mundos e mecânicas de jogo). Ao migrar para jogos, você não precisaria reaprender a linguagem nem os fundamentos: um personagem é modelado como um objeto com características e comportamentos, uma lista de inimigos é uma coleção, as regras do jogo são lógica de decisão — tudo isso você já domina. O que você aprenderia de novo seria específico do domínio de jogos (usar a Unity, gráficos, física), mas a base — a linguagem e o raciocínio de programação — já está construída.

Exercício 4

Compare a Unity e o MonoGame quanto ao laço de jogo: em qual deles você escreve o laço explicitamente, e em qual a engine o gerencia chamando seus métodos? Que compromisso (controle versus produtividade) isso representa?

Ver resposta

✓ Resposta: No MonoGame, o laço de jogo aparece explicitamente: você sobrescreve Update (lógica) e Draw (desenho), que estruturam o laço, tendo mais controle sobre ele. Na Unity, a engine gerencia o laço de jogo e chama seus métodos (Update etc.) automaticamente a cada quadro, escondendo o laço. Isso representa o compromisso clássico: o MonoGame dá mais controle e simplicidade conceitual (você vê e comanda o laço), ao custo de mais trabalho; a Unity dá mais produtividade e ferramentas prontas, ao custo de esconder detalhes. Mais controle versus mais abstração.

Exercício 5

Sem código: identifique, nos exemplos desta aula, dois conceitos que você aprendeu no núcleo do curso e explique onde cada um aparece no desenvolvimento de jogos. O que isso mostra sobre a relação entre o que você aprendeu e a criação de jogos?

Ver resposta

✓ Resposta: Dois conceitos do núcleo que aparecem nos exemplos: a herança — no script da Unity, MovimentoJogador herda de MonoBehaviour (e, no MonoGame, MeuJogo herda de Game), conectando o seu código à engine; e a sobrescrita de métodos com override (da fase de polimorfismo) — no MonoGame, Update e Draw são override da classe-base Game. Isso mostra que a criação de jogos usa a mesma linguagem e os mesmos conceitos fundamentais do curso, apenas aplicados a um domínio novo: os pilares que você aprendeu (classes, herança, polimorfismo, laços) são exatamente as ferramentas com que se constroem jogos, o que significa que você chega ao desenvolvimento de jogos com a base já pronta, precisando aprender apenas as especificidades do domínio, não a programação em si.

Comentários

Mais em Linguagem C#

Laços de Repetição: while e for
Laços de Repetição: while e for

Os dois laços fundamentais do C#: o while, que repete enquanto uma condição…

Variáveis: Gavetas com Nome para Guardar Valores
Variáveis: Gavetas com Nome para Guardar Valores

O conceito mais fundamental da programação, explicado pela metáfora da gaveta…

Boas Práticas: Os Hábitos do Bom Programador
Boas Práticas: Os Hábitos do Bom Programador

Os hábitos que separam código que funciona de código que se sustenta: nomes…