HOOZi文档
Skip to content

draw

屏幕绘制。所有 draw.* 调用打到当前帧的前景 draw list,必须在每渲染帧 event.on("frame_update") 内调用。draw list 每帧重置,漏一帧 = 屏幕上空白闪一下。详见 入门指南

颜色参数:下文 color 均是 number 类型(32-bit packed 颜色),由 draw.rgba / draw.u8 / draw.hex 构造;不能直接传 {r,g,b,a} table(table 形态仅用于 ESP 元素配色 opts)。


颜色构造(返 packed uint32)

draw.rgba(r, g, b, a) → uint32 —— floats 0..1

draw.u8(r, g, b, a) → uint32 —— ints 0..255

draw.hex(packed : int) → uint32 —— 直接传 0xRRGGBBAA


颜色变换(输入/输出都是 packed uint32)

不引入新类型,跟现有 rgba/u8/hex 互通。

draw.color_mod_a(col, v) → uint32

现有 alpha 乘以 v(0..1)。不是覆盖,叠加效果,适合渐隐。

lua
local half = draw.color_mod_a(red, 0.5)  -- alpha 砍半

draw.color_lerp(a, b, t) → uint32

双色逐分量线性插值(包含 alpha),t 自动 saturate 到 0..1。

lua
-- 低血从绿渐变到红
local hp_col = draw.color_lerp(draw.rgba(1,0,0,1), draw.rgba(0,1,0,1), hp / 100)

draw.color_darken(col, v) → uint32

RGB × (1-v),alpha 保留。v=0.5 = 暗 50%。

draw.color_lighten(col, v) → uint32

RGB 朝 255 插值 v,alpha 保留。v=0.5 = 朝白色靠拢 50%。

draw.color_hsv(h, s, v, a?) → uint32

HSV 构造。h ∈ [0,360) 度(超出会模),s/v/a ∈ [0,1]。a 默认 1.0。

lua
-- 彩虹流动
local hue = (time.now() * 60) % 360
local rainbow = draw.color_hsv(hue, 1.0, 1.0)

形状

draw.line(x1, y1, x2, y2, color, opts?)

opts{thickness = 1.0}

draw.rect(x1, y1, x2, y2, color, opts?)

opts{filled = false, rounding = 0, thickness = 1, flags = 0}

draw.rect_gradient(x1, y1, x2, y2, c_tl, c_tr, c_br, c_bl)

4 角各自一色的渐变矩形。常用做渐变血条 / 渐变背景。

draw.triangle_multicolor(x1, y1, c1, x2, y2, c2, x3, y3, c3)

3 顶点各自一色,GPU 自动插值填充。适合 fade 箭头、命中标记的渐变填充。

draw.circle_multicolor(x, y, r, center_col, edge_col, opts?)

圆心 → 圆周径向渐变(圆心一色,圆周一色,中间插值)。 opts:{segments = 36}。常用做能量球、雷达 marker 发光、minimap 边缘淡出。

lua
-- 中心亮白外圈透明的发光球
local cy = draw.rgba(1, 0.9, 0.4, 0.9)
local cx = draw.rgba(1, 0.9, 0.4, 0)
draw.circle_multicolor(x, y, 30, cy, cx)

draw.circle(x, y, r, color, opts?)

opts{filled = false, segments = 0, thickness = 1, fill = 1.0}

  • fill ∈ [0,1] —— 顺时针扇形,从 12 点位起。fill = 1.0(默认)= 完整圆。
    • filled = true + fill < 1.0 → 画扇形 pie(圆心 → 弧 → 圆心)
    • filled = false + fill < 1.0 → 画弧线(不闭合)
    • 用于 CD 进度环 / loading spinner / 雷达扇区。fill = 1.0 走 ImGui 原生 fast path,无性能损失。
lua
-- 75% 进度环
draw.circle(cx, cy, 30, draw.rgba(0.3,0.9,0.4,1),
            { fill = 0.75, thickness = 4 })

-- 实心扇形(pie)
draw.circle(cx, cy, 30, draw.rgba(1,0.6,0,0.4),
            { filled = true, fill = 0.5 })

draw.triangle(x1, y1, x2, y2, x3, y3, color, opts?)

opts{filled = false, thickness = 1}。适合方向箭头、FOV 三角指示、down arrow。

draw.quad(x1, y1, x2, y2, x3, y3, x4, y4, color, opts?)

opts{filled = false, thickness = 1}。投影 3D box 的核心:玩家世界空间 8 顶点投到屏幕后顶面/底面就是 4-vertex quad。

draw.polyline(points, color, opts?)

points:点序列,两种写法都接受

  • flat:{x1, y1, x2, y2, ...}(偶数长度)
  • nested:{ {x1, y1}, {x2, y2}, ... }

opts{thickness = 1, closed = false, filled = false}

  • closed = true → 末尾连回起点
  • filled = true → 用 AddConvexPolyFilled仅凸多边形可靠);走 filled 路径时 closed / thickness 都被忽略

万能兜底,能画 quad / 投影 box 的 polygonal outline / radar 形状 / FOV 弧。


阴影 + 外发光 (composite helper)

纯像素 helper —— 多圈叠加近似柔和模糊,不需要 shader。col 的 alpha 通道作为基准强度,opts.alpha 是叠加倍数(0..1)。

draw.shadow_line(x1, y1, x2, y2, color, opts?)

线段投影。 opts:{offset_x = 0, offset_y = 2, blur = 3, layers = 3, alpha = 1.0}

blur 大 → 阴影更柔;layers 越多越平滑但 batch 也增。offset_x/y 是阴影相对原始位置的偏移(模拟光源方向)。

lua
-- 在描边文字下加暗阴影
draw.shadow_line(x, y + 12, x + w, y + 12,
                 draw.rgba(0, 0, 0, 0.6),
                 { offset_y = 1, blur = 2 })

draw.shadow_rect(x1, y1, x2, y2, color, opts?)

矩形外阴影。 opts:{spread = 6, rounding = 0, layers = 3, alpha = 1.0}

外推 spread 像素等分 layers 圈,内圈接近实色外圈淡出。rounding 跟主体 rect 圆角一致即可。layers 越大越柔但 batch 也越多,默认 3 已够看,N 玩家批量 ESP 用时建议保持默认或降到 2。

lua
-- 给 hp bar 加底阴影,提升菜单背景对比
draw.shadow_rect(x, y, x + w, y + h,
                 draw.rgba(0, 0, 0, 0.5),
                 { spread = 4, rounding = 2 })
draw.rect(x, y, x + w, y + h, hp_col,
          { filled = true, rounding = 2 })

draw.glow_circle(x, y, r, color, opts?)

圆形外发光。 opts:{spread = 8, layers = 4, alpha = 1.0}

外推 spread 像素逐层径向衰减(平方曲线 → 中心亮边缘淡)。适合配 circle 当焦点 marker / 警示灯。layers 是性能拐点 —— 默认 4 + 平方衰减下,N 玩家 marker 批量调用仍可控。

lua
-- 雷达 marker 高亮(发光 + 实心圆心)
draw.glow_circle(mx, my, 6, draw.rgba(1, 0.3, 0.3, 0.7))
draw.circle(mx, my, 4, draw.rgba(1, 0.3, 0.3, 1), { filled = true })

文字 + 图像

draw.text(x, y, color, text, opts?)

opts

  • font — 字体句柄,从 draw.font(name) 取(默认 = 系统字体)
  • size — 强制字号 float;不传 = ImGui::GetFontSize()(当前活动字体的 size,不是传入 font 参数的默认 size)
  • outline
    • true → 主题深灰描边(项目统一风格)
    • uint32 color → 自定义颜色描边
    • 不传 / false → 不描边

描边实现 = 4 向 1px 偏移叠加,连续无锯齿;比脚本自己手动多次 draw.text 加偏移正确。

draw.image(tex_handle, x, y, w, h, opts?)

参数tex_handle 来自 file.image:load / :svg / :create

opts{tint = uint32_white, uv0 = {0,0}, uv1 = {1,1}}

uv0 / uv1 必须是 array-style table {u, v},不接受 {u=..., v=...} 命名形式。

draw.image_rotated(tex_handle, cx, cy, w, h, angle_deg, opts?)

(cx, cy) 旋转 angle_deg 度的图像。w/h 是旋转前的尺寸。 opts:同 draw.image(tint / uv0 / uv1)。

lua
-- 罗盘指针随玩家朝向转
draw.image_rotated(arrow_tex, sw/2, sh/2, 32, 32, yaw_deg)

裁剪栈

draw.push_clip(x1, y1, x2, y2, intersect?)

压栈一个矩形裁剪区,后续绘制只在此矩形内可见。

  • intersect 默认 true(跟当前 clip 求交,嵌套裁剪更安全)
  • 必须在 frame_update 内成对调用 pop_clip,跨帧不持久

draw.pop_clip()

弹出最近一次 push_clip 推入的矩形。

lua
-- 进度条 mask(图像上盖一层 clip,实现剪裁式进度)
draw.push_clip(x, y, x + w * progress, y + h)
draw.image(icon, x, y, w, h)
draw.pop_clip()

度量

draw.measure(text, opts?) → w, h

opts{font, size} —— 不传 = 用当前活动 font + ImGui::GetFontSize 测量

draw.screen() → w, h

当前帧屏幕分辨率。


字体

字体由项目启动时加载(ImGui font atlas 一次性构建),运行时不支持新加字体——用户字体需放 res/fonts/ 启动时自动扫入。

draw.fonts() → table<string>

列出可用字体名清单。内置 7 个:"default" / "small" / "icon" / "logo" / "esp" / "loot" / "models";加上 res/fonts/ 目录下扫到的 .ttf/.otf 文件名(无扩展)。

draw.font(name) → Font | nil

取字体句柄,nil 表示该 name 不存在。

注意:当前 draw.font(name) 仅暴露 7 个内置字体("default" / "small" / "icon" / "logo" / "esp" / "loot" / "models");draw.fonts() 会列出 res/fonts/ 下额外的 .ttf/.otf 文件名,但实际取句柄按内置名走(额外字体目前不挂句柄,未来扩展用)。


示例

lua
event.on("frame_update", function(e)
    local sw, sh = draw.screen()
    local red    = draw.rgba(1.0, 0.2, 0.2, 1.0)
    local trans  = draw.u8(255, 255, 255, 90)

    -- 屏幕中央十字
    draw.line(sw/2 - 8, sh/2, sw/2 + 8, sh/2, red, { thickness = 2 })
    draw.line(sw/2, sh/2 - 8, sw/2, sh/2 + 8, red, { thickness = 2 })

    -- 左上 watermark(渐变背景)
    draw.rect_gradient(10, 10, 200, 40,
        draw.rgba(0.1, 0.1, 0.15, 0.7), draw.rgba(0.2, 0.2, 0.3, 0.7),
        draw.rgba(0.2, 0.2, 0.3, 0.7), draw.rgba(0.1, 0.1, 0.15, 0.7))

    -- 描边文字(自动跟主题)
    local big = draw.font("logo")
    draw.text(15, 18, draw.rgba(1, 1, 1, 1), "HELLO",
              { font = big, size = 24, outline = true })

    -- 方向箭头(朝向某玩家)
    local cx, cy = sw/2, sh - 100
    draw.triangle(cx, cy - 12, cx - 10, cy + 8, cx + 10, cy + 8,
                  draw.rgba(1, 0.8, 0.2, 1), { filled = true })
end)

动画综合示例(CD ring + 渐变颜色 + clip 进度条 + 旋转图标)

lua
local start_t = time.now()
event.on("frame_update", function(e)
    local t = (time.now() - start_t) % 4.0
    local progress = t / 4.0
    local sw, sh = draw.screen()

    -- CD 环(顺时针填充)
    local ring_col = draw.color_lerp(draw.rgba(0,0.9,1,1), draw.rgba(0.2,1,0.4,1), progress)
    draw.circle(120, 120, 36, ring_col, { fill = progress, thickness = 5 })

    -- 进度条 mask: clip 限制图像左半截
    local bar_x, bar_y, bar_w, bar_h = 80, 200, 240, 14
    draw.rect(bar_x, bar_y, bar_x + bar_w, bar_y + bar_h,
              draw.color_darken(ring_col, 0.7), { filled = true, rounding = 6 })
    draw.push_clip(bar_x, bar_y, bar_x + bar_w * progress, bar_y + bar_h)
    draw.rect(bar_x, bar_y, bar_x + bar_w, bar_y + bar_h,
              ring_col, { filled = true, rounding = 6 })
    draw.pop_clip()

    -- 旋转图标(如果有 file.image:load 的句柄)
    -- draw.image_rotated(spinner_tex, 300, 120, 32, 32, progress * 360)
end)