Wikipedia MTA

HUD personalizado en MTA:SA con dxDrawText y dxDrawRectangle (sin librerías externas)

Antes de instalar una librería de interfaces, vale la pena entender cómo funciona un HUD personalizado usando únicamente las funciones nativas de dibujo de MTA:SA: dxDrawText y dxDrawRectangle. Son la base sobre la que están construidas la mayoría de librerías de UI del ecosistema MTA.

Lo primero: todo dibujo va dentro de onClientRender

MTA:SA redibuja la pantalla constantemente, así que cualquier elemento dx debe dibujarse dentro del evento onClientRender, que se ejecuta en cada frame:

addEventHandler("onClientRender", root, function()
    dxDrawRectangle(20, 20, 220, 60, tocolor(0, 0, 0, 150))
    dxDrawText("Vida: 100 / 100", 30, 35, 230, 60, tocolor(255, 255, 255, 255), 1.2, "default-bold")
end)
Esto dibuja un rectángulo semitransparente y un texto encima, en la esquina superior izquierda de la pantalla.

Haciendo el HUD dinámico

Un HUD útil no muestra texto fijo, sino datos reales del jugador. Por ejemplo, mostrar la vida actual del jugador local:

addEventHandler("onClientRender", root, function()
    local health = getElementHealth(localPlayer)
    dxDrawRectangle(20, 20, 220, 60, tocolor(0, 0, 0, 150))
    dxDrawText("Vida: " .. math.floor(health) .. " / 100", 30, 35, 230, 60,
        tocolor(255, 255, 255, 255), 1.2, "default-bold")
end)

Adaptar el HUD a distintas resoluciones de pantalla

No todos los jugadores tienen la misma resolución. Para que el HUD se vea bien en cualquier pantalla se usa guiGetScreenSize() para calcular posiciones relativas en lugar de coordenadas fijas:

local screenW, screenH = guiGetScreenSize()


addEventHandler("onClientRender", root, function()
    local x, y = screenW * 0.02, screenH * 0.02
    dxDrawRectangle(x, y, 220, 60, tocolor(0, 0, 0, 150))
end)
Así, el HUD se posiciona proporcionalmente sin importar si el jugador juega en 1280x720 o en 1920x1080.

Errores comunes al construir un HUD con dx

  • Dibujar fuera de onClientRender: si intentas usar dxDrawText en otro evento (por ejemplo, al presionar una tecla), el texto solo aparecerá un instante y desaparecerá, porque no se está redibujando cada frame.
  • Cálculos pesados dentro de onClientRender: como este evento corre muchas veces por segundo, cualquier operación costosa ahí (recorrer tablas grandes, hacer múltiples consultas) impacta directamente el rendimiento del cliente. Los datos que cambian poco (por ejemplo, el nombre del jugador) conviene calcularlos una sola vez y guardarlos en una variable.
  • No limpiar los addEventHandler al desactivar un recurso: si tu HUD se activa condicionalmente, asegúrate de remover el handler con removeEventHandler cuando ya no se necesite, para no seguir dibujando innecesariamente.
Aporte por:
Nicolas ECM
Udemy

Curso Programación en LUA para MTA

Aprende a programar desde 0 hasta avanzado con ejercicios prácticos

🔥 Ver Curso en Udemy