Construct do Zero: UI e HUD (Textos, Barras, Ícones e Botões)

Capítulo 10

Tempo estimado de leitura: 9 minutos

+ Exercício

O que é UI e HUD no Construct

UI (User Interface) é tudo que o jogador usa para interagir com o jogo: botões, painéis, menus, ícones e textos de instrução. HUD (Heads-Up Display) é a parte da UI que fica visível durante o gameplay, exibindo informações como vida, energia, munição, moedas e pontuação.

No Construct, a forma mais segura de construir UI/HUD é separar tudo em uma camada própria (ex.: UI) e configurar essa camada para não rolar com a câmera. Assim, o mundo se move, mas a interface permanece fixa na tela.

Organização recomendada: Camada UI e ancoragem na tela

1) Criar e configurar a camada UI

  • Crie uma camada chamada UI acima das camadas do jogo (para ficar sempre por cima).
  • Na camada UI, configure: Parallax X = 0 e Parallax Y = 0 (a UI não acompanha a câmera).
  • Se você usa zoom/efeitos de câmera no gameplay, mantenha a UI em camada separada para não distorcer elementos de HUD.

2) Ancoragem (posicionamento relativo à tela)

Como a camada UI não rola, você pode posicionar elementos usando coordenadas fixas (ex.: canto superior esquerdo). Para manter a UI consistente em diferentes resoluções, use uma destas abordagens:

  • Âncoras por eventos: em On start of layout e/ou Every tick, reposicione elementos com base em ViewportLeft, ViewportTop, ViewportRight, ViewportBottom.
  • Âncoras por containers: use um sprite “invisível” como referência (ex.: UI_AnchorTopLeft) e posicione os demais com offsets.

Exemplo de regra prática: elementos do canto superior esquerdo usam ViewportLeft + margem e ViewportTop + margem; elementos do canto superior direito usam ViewportRight - margem.

Textos no HUD: Text vs SpriteFont

Quando usar Text

  • Rápido para prototipar.
  • Bom para textos curtos e que mudam com frequência (pontuação, vida).
  • Pode variar visual dependendo de fontes instaladas/export.

Quando usar SpriteFont

  • Visual consistente (fonte “desenhada” como sprites).
  • Ótimo para pixel art e HUD retro.
  • Mais controle estético e previsibilidade.

Padrão de atualização por eventos

Evite atualizar texto “a cada tick” sem necessidade. Prefira atualizar quando o valor muda (por exemplo, quando pontua ou toma dano). Se você já tem variáveis globais como PlayerHP e Score, a lógica do HUD pode ser:

Continue em nosso aplicativo e ...
  • Ouça o áudio com a tela desligada
  • Ganhe Certificado após a conclusão
  • + de 5000 cursos para você explorar!
ou continue lendo abaixo...
Download App

Baixar o aplicativo

Evento: System - On start of layout  |  Ação: TextScore - Set text to "SCORE: " & Score  |  Ação: TextHP - Set text to "HP: " & PlayerHP
Evento: System - Every tick  |  (use apenas se não tiver eventos de mudança)  Ação: TextScore - Set text to "SCORE: " & Score

Na prática, para pontuação e vida, o ideal é atualizar nos mesmos eventos que alteram Score e PlayerHP.

Barras de vida/energia: 2 formas comuns

Forma A: Barra por escala (simples e eficiente)

Crie dois sprites na camada UI: BarBack (fundo) e BarFill (preenchimento). A ideia é manter o fundo fixo e alterar a escala X do preenchimento conforme a porcentagem.

  • Defina o ponto de origem (origin) do BarFill no lado esquerdo (para “encher” da esquerda para a direita).
  • Use variáveis: PlayerHP e PlayerHPMax.
Evento: System - Every tick  |  Ação: BarFill - Set width to BarBack.Width * clamp(PlayerHP / PlayerHPMax, 0, 1)

Se preferir escala em vez de largura:

Evento: System - Every tick  |  Ação: BarFill - Set scale X to clamp(PlayerHP / PlayerHPMax, 0, 1)

Forma B: Barra por recorte (crop) ou máscara (visual mais controlado)

Quando a arte da barra tem bordas complexas, você pode recortar o preenchimento. O princípio é o mesmo: calcular a porcentagem e aplicar no recorte horizontal. Use quando a escala distorce a textura.

Ícones no HUD (vida, moedas, arma, etc.)

Ícones normalmente são sprites pequenos na camada UI. Boas práticas:

  • Use nomes claros: IconHeart, IconCoin, IconPause.
  • Mantenha alinhamento por grid (ex.: margens de 16px/24px) para consistência.
  • Se o ícone tiver estados (ex.: som ligado/desligado), use animações ou frames e altere por evento.

Botões clicáveis e touch: como estruturar

Objetos recomendados

  • Sprite para o botão (ex.: BtnPause, BtnResume, BtnExit).
  • Mouse e/ou Touch como input.

Estados visuais do botão (normal/hover/pressed)

Crie 2–3 frames no sprite do botão: 0=Normal, 1=Hover, 2=Pressed. Em seguida:

Evento: Mouse - On object BtnPause  |  Ação: BtnPause - Set frame to 2
Evento: Mouse - Is over object BtnPause  |  Ação: BtnPause - Set frame to 1  |  Sub-evento: Else  Ação: BtnPause - Set frame to 0

Para touch, use Touch - On touched object e, se quiser feedback de pressionado, combine com variáveis (ex.: IsTouchingUI) ou use eventos de “is in touch” se disponível.

Área clicável maior que o ícone

Em mobile, aumente a área clicável. Você pode:

  • Usar um sprite transparente maior como hitbox (ex.: BtnPauseHit) e manter o ícone separado.
  • Ou aumentar o tamanho do botão e manter o ícone centralizado.

Painel de pause: visibilidade, bloqueio de input e time scale

Conceito

Um pause funcional geralmente envolve três coisas:

  • Mostrar/ocultar um painel (overlay) na camada UI.
  • Parar o tempo do gameplay (time scale = 0) para congelar movimentos, animações e timers do mundo.
  • Evitar cliques no jogo enquanto o painel está aberto (bloquear input do gameplay).

Estrutura típica na camada UI:

  • PauseOverlay (sprite semitransparente escurecendo o fundo)
  • PausePanel (janela)
  • BtnResume (retomar)
  • BtnExit (sair)

Deixe esses objetos inicialmente invisíveis.

Variável de controle

Crie uma variável global booleana (0/1): IsPaused.

Eventos essenciais do pause

ObjetivoEventoAções
Abrir pauseOn clicked/touched BtnPause e IsPaused = 0Set IsPaused=1; Set time scale = 0; Set visible (overlay/panel/botões)=true
RetomarOn clicked/touched BtnResume e IsPaused = 1Set IsPaused=0; Set time scale = 1; Set visible (overlay/panel/botões)=false
SairOn clicked/touched BtnExit e IsPaused = 1Set time scale = 1; Set IsPaused=0; Go to layout (menu) ou reiniciar fase

Exemplo em formato de eventos (pseudo):

Evento: Mouse - On object BtnPause  |  Condição: IsPaused = 0  |  Ações: Set IsPaused to 1; System - Set time scale to 0; PauseOverlay/PausePanel/BtnResume/BtnExit - Set visible true
Evento: Mouse - On object BtnResume  |  Condição: IsPaused = 1  |  Ações: Set IsPaused to 0; System - Set time scale to 1; PauseOverlay/PausePanel/BtnResume/BtnExit - Set visible false
Evento: Mouse - On object BtnExit  |  Condição: IsPaused = 1  |  Ações: System - Set time scale to 1; Set IsPaused to 0; System - Go to layout "Menu"

Bloqueando interação do gameplay enquanto pausado

Mesmo com time scale 0, você pode ter eventos que ainda disparam (cliques, toques, algumas lógicas de UI). Para garantir que o jogador não interaja com o mundo:

  • Adicione a condição IsPaused = 0 em eventos de controle do personagem, tiros, interação com objetos etc.
  • Ou use um grupo de eventos Gameplay e desative quando IsPaused=1.
Evento: IsPaused = 1  |  Ação: System - Set group "Gameplay" inactive
Evento: IsPaused = 0  |  Ação: System - Set group "Gameplay" active

Exercício prático: HUD com vida, pontuação, pause e painel

Objetivo do exercício

  • Exibir vida (barra + texto opcional).
  • Exibir pontuação (texto).
  • Adicionar botão de pause no canto superior direito.
  • Ao pausar: abrir painel com Retomar e Sair, congelando o gameplay via time scale e controlando visibilidade.

Passo 1: Montar os objetos na camada UI

  • Crie/importe: BarBack, BarFill, IconHeart (opcional), TextScore, BtnPause.
  • Crie o conjunto do pause: PauseOverlay, PausePanel, BtnResume, BtnExit.
  • Coloque todos na camada UI.
  • Deixe PauseOverlay, PausePanel, BtnResume, BtnExit com Visible = false no início.

Passo 2: Ancorar elementos do HUD na tela

Defina uma margem (ex.: 16). Em On start of layout, posicione:

  • Vida no canto superior esquerdo.
  • Pontuação no topo (ou canto superior esquerdo abaixo da vida).
  • Pause no canto superior direito.
Evento: System - On start of layout  |  Ações (exemplo): BarBack set position (ViewportLeft+120, ViewportTop+32); BarFill set position (BarBack.X, BarBack.Y); TextScore set position (ViewportLeft+16, ViewportTop+72); BtnPause set position (ViewportRight-24, ViewportTop+24)

Se seu jogo muda de resolução/orientação durante a execução, replique essas ações em Every tick ou em um evento que detecte mudança de viewport.

Passo 3: Atualizar a barra de vida

Use a porcentagem de vida para ajustar o preenchimento:

Evento: System - Every tick  |  Ação: BarFill - Set width to BarBack.Width * clamp(PlayerHP / PlayerHPMax, 0, 1)

Se você também quiser texto:

Evento: PlayerHP changed (ou quando tomar dano/curar)  |  Ação: TextHP - Set text to PlayerHP & " / " & PlayerHPMax

Passo 4: Atualizar pontuação

Quando a pontuação mudar (por exemplo, ao coletar ou derrotar inimigo), atualize:

Evento: Score changed (ou no evento de ganhar pontos)  |  Ação: TextScore - Set text to "SCORE: " & Score

Passo 5: Implementar o botão de pause (mouse e touch)

Crie dois eventos (um para mouse e outro para touch) ou use apenas o input do seu alvo principal:

Evento: Mouse - On object BtnPause  |  Condição: IsPaused = 0  |  Ações: Set IsPaused=1; System - Set time scale to 0; PauseOverlay/PausePanel/BtnResume/BtnExit - Set visible true
Evento: Touch - On touched object BtnPause  |  Condição: IsPaused = 0  |  Ações: Set IsPaused=1; System - Set time scale to 0; PauseOverlay/PausePanel/BtnResume/BtnExit - Set visible true

Passo 6: Retomar e sair

Evento: Mouse - On object BtnResume  |  Condição: IsPaused = 1  |  Ações: Set IsPaused=0; System - Set time scale to 1; PauseOverlay/PausePanel/BtnResume/BtnExit - Set visible false
Evento: Mouse - On object BtnExit  |  Condição: IsPaused = 1  |  Ações: System - Set time scale to 1; Set IsPaused=0; System - Go to layout "Menu"

Repita a lógica para touch se necessário.

Passo 7: Garantir que o gameplay não responda durante o pause

Escolha uma estratégia:

  • Estratégia 1 (simples): em eventos de gameplay, adicione a condição IsPaused = 0.
  • Estratégia 2 (organizada): coloque eventos de gameplay em um grupo Gameplay e ative/desative conforme IsPaused.
Evento: IsPaused = 1  |  Ação: System - Set group "Gameplay" inactive
Evento: IsPaused = 0  |  Ação: System - Set group "Gameplay" active

Checklist de validação do exercício

  • Ao mover a câmera, o HUD permanece fixo na tela (camada UI com parallax 0,0).
  • A barra de vida diminui/aumenta corretamente sem “andar” (origin do fill à esquerda).
  • A pontuação atualiza quando o valor muda.
  • O botão pause abre o painel e congela o gameplay (time scale 0).
  • Retomar fecha o painel e volta ao normal (time scale 1).
  • Sair troca de tela sem manter o jogo congelado (garantir time scale 1 antes de sair).

Agora responda o exercício sobre o conteúdo:

Ao criar uma camada chamada UI para HUD no Construct, qual configuração garante que a interface permaneça fixa na tela enquanto a câmera se move pelo cenário?

Você acertou! Parabéns, agora siga para a próxima página

Você errou! Tente novamente.

Ao colocar HUD/ UI em uma camada própria com Parallax X=0 e Parallax Y=0, essa camada não acompanha o movimento da câmera, mantendo os elementos fixos na tela.

Próximo capitúlo

Construct do Zero: Menus e Fluxo de Jogo (Menu, Pause, Game Over e Vitória)

Arrow Right Icon
Capa do Ebook gratuito Construct do Zero: Desenvolvendo Jogos 2D Sem Programar (com Eventos)
56%

Construct do Zero: Desenvolvendo Jogos 2D Sem Programar (com Eventos)

Novo curso

18 páginas

Baixe o app para ganhar Certificação grátis e ouvir os cursos em background, mesmo com a tela desligada.