文件 玩法擴展

畫板

在遊戲畫面上畫文字框、面板、進度條、圖片、貼著地面的圈和帶箭頭的路線。執行環境每幀自己繪製,不修改遊戲狀態,多人局也安全;Python、HTTP、直接寫共享記憶體都行。

外部程式可以在遊戲畫面上畫文字框、面板、進度條、圖片、地上的圈、地上的路線(帶箭頭),由執行環境每幀自己繪製。拿來做自己的 HUD、輔助線、提示、教學標註、直播資訊板,都很合適。

畫板和 JASS 畫面函式,怎麼選

畫板(本頁)JASS 畫面函式
誰來畫執行環境自繪遊戲自己(浮動文字、特效、面板、頭像對白……)
多人局安全:只畫在本機畫面上,不建立遊戲物件、不修改遊戲狀態只能單人局
樣式隨意:中文字型、圓角、半透明、邊框、任意顏色、本機圖片遊戲原生風格
跟著東西走跟單位、世界座標、螢幕位置;地上的圈貼著地形起伏看具體函式
開銷實測每幀 0.2 ~ 0.35 ms(9 個元素)每次呼叫約 13 ms

兩條路可以一起用:原生風格的效果用 JASS,自訂的面板、輔助線和提示用畫板。

Python

c = g.canvas                               # 第一次使用時執行環境裝好繪製掛鉤(約 0.1 秒)
c.text("title", "你好,這是畫板", screen=(40, 110), color=(255, 220, 80),
       bg=(0, 0, 0, 170), border="#C49C40", size=22, bold=True)
c.panel("status", "玩伴 · 小聖", ["心情:開心", "擊殺:12"], screen=(16, 330))
c.bar("hp", 0.62, unit=hero, lift=260, width=100, height=12, color=(80, 220, 80), text="62%")   # 跟著單位走
c.text("tag", "Boss 要放大招了!", unit=boss, lift=320, color=(255, 80, 80), size=22, bold=True)
c.circle("danger", (x, y), 300, color=(255, 60, 60), fill=(255, 60, 60, 60), width=3)          # 地上的危險區
c.circle("aura", hero, 450, color=(80, 200, 255, 220))                                         # 跟著單位走的圈
c.path("route", [(x1, y1), (x2, y2), (x3, y3)], color=(255, 220, 0), width=5, arrow=True)
c.image("icon", "icon.png", screen=(40, 170), width=64, height=64)
c.remove("danger"); c.hide("tag"); c.clear()   # clear 只清自己畫的
c.expire("tag", 5)                         # 5 秒後自己消失
with c.batch(): ...                        # 一次改很多條,只寫一次共享記憶體
c.stats()                                  # drawnFrames 在增加 = 真的在畫

每個元素用一個 key 識別:同一個 key 再畫一次就是更新。

能點:文字框和面板加上 clickable=True(滑鼠停在上面時的顏色用 hover= 設定),點中時事件流裡會來一條 ui.click,ev.key 就是這個 key,點在它上面的那一下遊戲收不到。現成的按鈕、選項卡片、熱鍵、點地面請見 介面與輸入。

位置(每個元素給一個):

  • screen=(x, y):螢幕像素,負數表示從右邊 / 下邊往回算;center=True 以中心對齊;
  • frac=(0.5, 0.1):螢幕比例;
  • world=(x, y):世界座標;
  • unit=單位:跟著單位走。世界和單位上的文字、進度條以底邊中點對準那一點,lift 往上抬。

世界和單位上的元素預設避開底部的操作面板和頂部的晝夜球(over_ui=True 則蓋在上面)。顏色可以寫 (r, g, b)、(r, g, b, a)、"#RRGGBB" 或 "#RRGGBBAA"。

方法畫什麼常用參數
text(key, 文字, ...)文字框,多行用 \ncolor、bg 底色(不給就透明)、border、size、bold、shadow、width(依這個寬度換行)、radius 圓角
panel(key, 標題, [行...], ...)面板(深色半透明底、金邊)同 text
bar(key, 0..1, ...)進度條:血量、冷卻、讀條width、height、color、bg、border、text
image(key, 路徑, ...)本機圖片(png / jpg / bmp / gif)width、height(不給就是原尺寸)
circle(key, 單位或點, 半徑, ...)地上的圈,貼著地形color 線色、fill 填色(帶透明度)、width 線寬
path(key, [點...], ...)地上的折線color、width、arrow 末端箭頭;點可以是座標或單位

HTTP(任何語言)

遠見後端(只監聽本機):

POST /api/instances/20/canvas
{"set": [
   {"key": "banner", "kind": "text", "text": "來自 HTTP 的畫板", "frac": [0.5, 0.12], "center": true,
    "color": "#FFDC50", "bg": [0, 0, 0, 180]},
   {"key": "hp", "kind": "bar", "value": 0.8, "unit": 596125988, "lift": 260, "text": "80%"},
   {"key": "zone", "kind": "circle", "center": 596125988, "radius": 600, "color": [255, 200, 0], "width": 4},
   {"key": "route", "kind": "path", "points": [[-4587, -9092], [-5387, -8792]], "color": "#50C8FF"}
 ],
 "remove": ["old"], "clear": false}

GET  /api/instances/20/canvas        目前畫著哪些元素 + 畫了多少幀

kind 就是 Python 的方法名稱,參數名稱也一樣;單位寫快照裡的位址 addr。

直接寫共享記憶體

不經過 Python 和遠見也可以:先送一次語意命令 canvas_enable(W3P 操作碼 73),執行環境會建好共享記憶體區塊 Local\War3Canvas_<pid>:標頭 64 位元組 + 256 條 × 112 位元組 + 64 KB 文字 / 點池。依 seqlock 寫入(序號變奇數 → 寫條目和池 → 序號變偶數),執行環境每幀讀一次,讀到寫了一半的就沿用上一幀,並回寫已繪製幀數、元素數和異常計數。Python 參考實作是 sdk/python/w3canvas.py,結構定義在協定標頭檔裡,見 W3P 協定。

好幾個程式同時畫

模組、遠見、MCP、閘道可能同時在同一局裡畫東西,畫板只有一塊。規矩是:每個程式只動自己的元素。

  • 寫入之前先取得一把具名鎖,讀出現有的元素,保留別人的,換上自己的,再寫回去;
  • 每個元素記著是誰畫的(行程 ID + 行程內序號),畫它的程式結束了,下一次有人寫入時順手清掉;它的按鈕也不再攔截點擊;
  • 元素編號從共用的計數器分配,不會撞號。

Python SDK 已經這麼做了,clear() 也只清自己的。自己直接寫共享記憶體的話照這個來,否則會把別人的東西沖掉。配置細節見 W3P 協定。

實測與注意事項

  • 2026-09-25 實測(1920×1080,2 倍速):9 個元素每幀 0.27 ~ 0.34 ms,約 63 幀 / 秒,0 次異常;寫入 9 條用時 6 ms;英雄走動時,跟著單位的圈、文字、血條都跟得上。內容變了才重畫貼圖,只挪動位置不重畫。
  • 畫在遊戲介面之後、滑鼠游標之前:蓋在遊戲自己的血條、單位和介面上面,滑鼠游標則蓋在它上面。它會避開底部操作面板和頂部晝夜球,但不會避讓地圖自己的面板(右上角的排行榜、倒數計時)—— 自己的面板別放在右上角。
  • 不在對局裡(主選單、結算畫面)時,放在世界座標和單位上的元素不畫,螢幕位置的照畫。
  • 地上的圈是把圓周上的 64 個點各自投影到地面上,地形有高低時形狀會跟著起伏 —— 這是對的:它畫在真實的地面上。
  • 第一次開啟要裝掛鉤、預熱字型,約 1 秒,期間文字類元素先不畫,圈和線照畫。
  • 繪製時出現一次異常,本次工作階段就不再畫(和頭頂氣泡同一套保護),stats() 裡的 faults 會變成 1。
  • 文字、圖片路徑和點一共 64 KB,最多 256 個元素;圖片路徑必須是遊戲行程讀得到的本機路徑。

AI 玩伴 的狀態面板就是用畫板畫的:血條、正在做什麼、心情、擊殺和補血次數。