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
UIacima 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 layoute/ouEvery tick, reposicione elementos com base emViewportLeft,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:
- Ouça o áudio com a tela desligada
- Ganhe Certificado após a conclusão
- + de 5000 cursos para você explorar!
Baixar o aplicativo
Evento: System - On start of layout | Ação: TextScore - Set text to "SCORE: " & Score | Ação: TextHP - Set text to "HP: " & PlayerHPEvento: System - Every tick | (use apenas se não tiver eventos de mudança) Ação: TextScore - Set text to "SCORE: " & ScoreNa 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
BarFillno lado esquerdo (para “encher” da esquerda para a direita). - Use variáveis:
PlayerHPePlayerHPMax.
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 2Evento: Mouse - Is over object BtnPause | Ação: BtnPause - Set frame to 1 | Sub-evento: Else Ação: BtnPause - Set frame to 0Para 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
| Objetivo | Evento | Ações |
|---|---|---|
| Abrir pause | On clicked/touched BtnPause e IsPaused = 0 | Set IsPaused=1; Set time scale = 0; Set visible (overlay/panel/botões)=true |
| Retomar | On clicked/touched BtnResume e IsPaused = 1 | Set IsPaused=0; Set time scale = 1; Set visible (overlay/panel/botões)=false |
| Sair | On clicked/touched BtnExit e IsPaused = 1 | Set 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 trueEvento: 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 falseEvento: 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 = 0em eventos de controle do personagem, tiros, interação com objetos etc. - Ou use um grupo de eventos
Gameplaye desative quandoIsPaused=1.
Evento: IsPaused = 1 | Ação: System - Set group "Gameplay" inactiveEvento: IsPaused = 0 | Ação: System - Set group "Gameplay" activeExercí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,BtnExitcom 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 & " / " & PlayerHPMaxPasso 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: " & ScorePasso 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 trueEvento: 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 truePasso 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 falseEvento: 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
Gameplaye ative/desative conformeIsPaused.
Evento: IsPaused = 1 | Ação: System - Set group "Gameplay" inactiveEvento: IsPaused = 0 | Ação: System - Set group "Gameplay" activeChecklist 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).