J.J. Huang   2026-04-19   Python OpenCV 08.專案實作篇   瀏覽次數:次  

Python | OpenCV 專案:天堂私服遊戲輔助(一)主程式 GUI 框架與 HP/MP 血量監控

📑 目錄
  1. ⚠️ 免責聲明
  2. 📚 前言
  3. 🎯 本篇目標
  4. 🗂️ 本篇專案結構
  5. 🛠️ 套件安裝
  6. 💻 視窗擷取模組:window_capture.py
  7. 💻 血量監控模組:hp_monitor.py
  8. 💻 主程式:main.py
  9. 🚀 執行流程
  10. ⚠️ 常見問題
  11. 🎯 結語

⚠️ 免責聲明

本文章內容僅供學術研究與電腦視覺技術學習之用途,所有程式碼與技術說明均以教育目的為出發點。

  • 本文作者不提供任何形式的輔助程式販售、散佈或商業服務
  • 本文所有範例程式僅限在自行架設的私有伺服器環境中測試,不得用於任何正式營運的線上遊戲伺服器。
  • 使用遊戲輔助程式可能違反個別遊戲的使用者條款,並導致帳號封鎖、法律責任等後果,讀者須自行承擔一切相關風險與責任
  • 本文技術內容若被用於任何違法或損害他人利益之行為,作者概不負責
  • 私有伺服器的架設與使用涉及遊戲著作權相關法律問題,讀者應自行評估所在地區的法規,並確認於合法範圍內使用。

本系列的核心目的是展示 GUI 設計、多執行緒架構、螢幕擷取、影像分析 等電腦視覺技術的整合應用,相同技術同樣適用於工廠監控、遠端桌面分析等正當場景。

📚 前言

在上一篇 天堂私服 YOLOv8 物件偵測實戰 中,我們完成了 YOLOv8 怪物偵測模型的訓練與即時推論。​‌‌‌​​​​​‌‌‌‌​​‌​‌‌‌​‌​​​‌‌​‌​​​​‌‌​‌‌‌‌​‌‌​‌‌‌​​​‌​‌‌​‌​‌‌​‌‌‌‌​‌‌‌​​​​​‌‌​​‌​‌​‌‌​‌‌‌​​‌‌​​​‌‌​‌‌‌​‌‌​​​‌​‌‌​‌​​‌‌​​‌​​​‌‌​​​​​​‌‌​​‌​​​‌‌​‌‌​​​‌‌​​​​​​‌‌​‌​​​​‌‌​​​‌​​‌‌‌​​‌​​‌​‌‌​‌​‌‌‌​​​​​‌‌‌‌​​‌​‌‌‌​‌​​​‌‌​‌​​​​‌‌​‌‌‌‌​‌‌​‌‌‌​​​‌​‌‌​‌​‌‌​‌‌‌‌​‌‌‌​​​​​‌‌​​‌​‌​‌‌​‌‌‌​​‌‌​​​‌‌​‌‌‌​‌‌​​​‌​‌‌​‌​‌‌‌​​​​​‌‌‌​​‌​​‌‌​‌‌‌‌​‌‌​‌​‌​​‌‌​​‌​‌​‌‌​​​‌‌​‌‌‌​‌​​​​‌​‌‌​‌​‌‌​‌‌​​​‌‌​‌​​‌​‌‌​‌‌‌​​‌‌​​‌​‌​‌‌​​​​‌​‌‌​​‌‌‌​‌‌​​‌​‌​​‌​‌‌​‌​‌‌​​​​‌​‌‌‌​​‌‌​‌‌‌​​‌‌​‌‌​‌​​‌​‌‌‌​​‌‌​‌‌‌​‌​​​‌‌​​​​‌​‌‌​‌‌‌​​‌‌‌​‌​​

這個系列(共 5 篇)將把訓練好的模型整合進一套完整的遊戲輔助程式,以逐步增加功能的方式帶你理解整個系統架構,每篇都附上可直接執行的完整 main.py

系列總覽:

篇次 主題 重點功能
本篇(一) 主程式 GUI 框架與 HP/MP 血量監控 tkinter UI、螢幕擷取、血量偵測
自動補藥 閾值設定、熱鍵模擬、補藥邏輯
YOLOv8 怪物偵測整合 偵測執行緒、即時預覽視窗
四(最終篇) 目標優先序選擇 優先類別、距離排序、目標鎖定

🎯 本篇目標

  • 建立 tkinter 暗色主題遊戲輔助視窗
  • 實作「🎯 選取視窗」按鈕,讓使用者點擊即鎖定任一目標視窗(取得 hwnd、標題、PID)
  • 用 pywin32 PrintWindow 擷取選定視窗畫面
  • 用 HSV 色相範圍 + 最右側有色像素比例偵測 HP/MP 血量
  • 在主程式內整合「⚙ 校準血條」按鈕,框選 HP / MP 血條位置
  • 設計 SharedState + threading.Lock 的執行緒安全資料結構

🗂️ 本篇專案結構

1
2
3
4
5
lineage_assistant/
├── main.py ← 主程式:UI、視窗選取、血條校準(本篇完成)
├── window_capture.py ← 視窗擷取與滑鼠選窗模組(本篇完成)
├── hp_monitor.py ← HP/MP 血量監控模組(本篇完成)
└── config.json ← 由主程式「⚙ 校準血條」按鈕寫入

後續每篇會在同一目錄中新增模組,並更新 main.py。​‌‌‌​​​​​‌‌‌‌​​‌​‌‌‌​‌​​​‌‌​‌​​​​‌‌​‌‌‌‌​‌‌​‌‌‌​​​‌​‌‌​‌​‌‌​‌‌‌‌​‌‌‌​​​​​‌‌​​‌​‌​‌‌​‌‌‌​​‌‌​​​‌‌​‌‌‌​‌‌​​​‌​‌‌​‌​​‌‌​​‌​​​‌‌​​​​​​‌‌​​‌​​​‌‌​‌‌​​​‌‌​​​​​​‌‌​‌​​​​‌‌​​​‌​​‌‌‌​​‌​​‌​‌‌​‌​‌‌‌​​​​​‌‌‌‌​​‌​‌‌‌​‌​​​‌‌​‌​​​​‌‌​‌‌‌‌​‌‌​‌‌‌​​​‌​‌‌​‌​‌‌​‌‌‌‌​‌‌‌​​​​​‌‌​​‌​‌​‌‌​‌‌‌​​‌‌​​​‌‌​‌‌‌​‌‌​​​‌​‌‌​‌​‌‌‌​​​​​‌‌‌​​‌​​‌‌​‌‌‌‌​‌‌​‌​‌​​‌‌​​‌​‌​‌‌​​​‌‌​‌‌‌​‌​​​​‌​‌‌​‌​‌‌​‌‌​​​‌‌​‌​​‌​‌‌​‌‌‌​​‌‌​​‌​‌​‌‌​​​​‌​‌‌​​‌‌‌​‌‌​​‌​‌​​‌​‌‌​‌​‌‌​​​​‌​‌‌‌​​‌‌​‌‌‌​​‌‌​‌‌​‌​​‌​‌‌‌​​‌‌​‌‌‌​‌​​​‌‌​​​​‌​‌‌​‌‌‌​​‌‌‌​‌​​

🛠️ 套件安裝

1
pip install opencv-python pywin32

💡 pywin32 提供 win32guiwin32uiwin32apiwin32process,用來呼叫 PrintWindowWindowFromPointGetAsyncKeyStateGetWindowThreadProcessId 等 Windows API。若 import win32gui 失敗,補跑一次 post-install:

1
python -m pywin32_postinstall -install

Python - 圖 1 (flow)
Python - 圖 2 (architecture)

💻 視窗擷取模組:window_capture.py

用 Windows PrintWindow API 擷取指定 hwnd 的視窗畫面,即使視窗被其他視窗遮擋也能拿到完整畫面(最小化除外)。​‌‌‌​​​​​‌‌‌‌​​‌​‌‌‌​‌​​​‌‌​‌​​​​‌‌​‌‌‌‌​‌‌​‌‌‌​​​‌​‌‌​‌​‌‌​‌‌‌‌​‌‌‌​​​​​‌‌​​‌​‌​‌‌​‌‌‌​​‌‌​​​‌‌​‌‌‌​‌‌​​​‌​‌‌​‌​​‌‌​​‌​​​‌‌​​​​​​‌‌​​‌​​​‌‌​‌‌​​​‌‌​​​​​​‌‌​‌​​​​‌‌​​​‌​​‌‌‌​​‌​​‌​‌‌​‌​‌‌‌​​​​​‌‌‌‌​​‌​‌‌‌​‌​​​‌‌​‌​​​​‌‌​‌‌‌‌​‌‌​‌‌‌​​​‌​‌‌​‌​‌‌​‌‌‌‌​‌‌‌​​​​​‌‌​​‌​‌​‌‌​‌‌‌​​‌‌​​​‌‌​‌‌‌​‌‌​​​‌​‌‌​‌​‌‌‌​​​​​‌‌‌​​‌​​‌‌​‌‌‌‌​‌‌​‌​‌​​‌‌​​‌​‌​‌‌​​​‌‌​‌‌‌​‌​​​​‌​‌‌​‌​‌‌​‌‌​​​‌‌​‌​​‌​‌‌​‌‌‌​​‌‌​​‌​‌​‌‌​​​​‌​‌‌​​‌‌‌​‌‌​​‌​‌​​‌​‌‌​‌​‌‌​​​​‌​‌‌‌​​‌‌​‌‌‌​​‌‌​‌‌​‌​​‌​‌‌‌​​‌‌​‌‌‌​‌​​​‌‌​​​​‌​‌‌​‌‌‌​​‌‌‌​‌​​

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# window_capture.py
from ctypes import windll
import numpy as np
import win32gui
import win32process
import win32ui

GA_ROOT = 2 # GetAncestor flag:取頂層視窗

def window_from_point(x, y):
"""回傳 (x, y) 螢幕座標下的頂層視窗 (hwnd, title, pid);找不到回傳 (None, '', 0)"""
hwnd = win32gui.WindowFromPoint((x, y))
if not hwnd:
return None, "", 0
hwnd = win32gui.GetAncestor(hwnd, GA_ROOT)
_, pid = win32process.GetWindowThreadProcessId(hwnd)
return hwnd, win32gui.GetWindowText(hwnd), pid

def capture_window(hwnd):
"""用 PrintWindow 擷取視窗畫面:被遮擋也能抓,最小化會拿到黑畫面"""
left, top, right, bottom = win32gui.GetWindowRect(hwnd)
w, h = right - left, bottom - top
if w <= 0 or h <= 0:
return None

hwnd_dc = win32gui.GetWindowDC(hwnd)
mfc_dc = win32ui.CreateDCFromHandle(hwnd_dc)
save_dc = mfc_dc.CreateCompatibleDC()
save_bmp = win32ui.CreateBitmap()
save_bmp.CreateCompatibleBitmap(mfc_dc, w, h)
save_dc.SelectObject(save_bmp)

# flag=2 (PW_RENDERFULLCONTENT):支援 DWM 合成畫面,對多數現代應用必要
result = windll.user32.PrintWindow(hwnd, save_dc.GetSafeHdc(), 2)
img = np.frombuffer(save_bmp.GetBitmapBits(True), dtype=np.uint8).reshape((h, w, 4))

win32gui.DeleteObject(save_bmp.GetHandle())
save_dc.DeleteDC()
mfc_dc.DeleteDC()
win32gui.ReleaseDC(hwnd, hwnd_dc)

return img[:, :, :3].copy() if result == 1 else None # BGRA → BGR

💻 血量監控模組:hp_monitor.py

HPMonitor 透過 HSV 色彩比例 推算血條填充:

  1. 從畫面截出血條 ROI
  2. 轉換為 HSV 色彩空間
  3. 對目標色(HP 紅 / MP 藍)做閾值遮罩
  4. 找最右側有色像素欄位,除以總寬度得到填充比例(0.0 ~ 1.0)

HP / MP 兩組 ROI 各自儲存在 config.json,可用「⚙ 校準血條」按鈕隨時重新框選。

⚠️ HSV 的紅色色相橫跨 0 與 180 兩端,本範例只取 H=0~10 足以應付多數血條;若你的遊戲血條偏紫紅(H > 170),要同時 cv2.inRange 兩段再用 |(OR)合併成一張遮罩。​‌‌‌​​​​​‌‌‌‌​​‌​‌‌‌​‌​​​‌‌​‌​​​​‌‌​‌‌‌‌​‌‌​‌‌‌​​​‌​‌‌​‌​‌‌​‌‌‌‌​‌‌‌​​​​​‌‌​​‌​‌​‌‌​‌‌‌​​‌‌​​​‌‌​‌‌‌​‌‌​​​‌​‌‌​‌​​‌‌​​‌​​​‌‌​​​​​​‌‌​​‌​​​‌‌​‌‌​​​‌‌​​​​​​‌‌​‌​​​​‌‌​​​‌​​‌‌‌​​‌​​‌​‌‌​‌​‌‌‌​​​​​‌‌‌‌​​‌​‌‌‌​‌​​​‌‌​‌​​​​‌‌​‌‌‌‌​‌‌​‌‌‌​​​‌​‌‌​‌​‌‌​‌‌‌‌​‌‌‌​​​​​‌‌​​‌​‌​‌‌​‌‌‌​​‌‌​​​‌‌​‌‌‌​‌‌​​​‌​‌‌​‌​‌‌‌​​​​​‌‌‌​​‌​​‌‌​‌‌‌‌​‌‌​‌​‌​​‌‌​​‌​‌​‌‌​​​‌‌​‌‌‌​‌​​​​‌​‌‌​‌​‌‌​‌‌​​​‌‌​‌​​‌​‌‌​‌‌‌​​‌‌​​‌​‌​‌‌​​​​‌​‌‌​​‌‌‌​‌‌​​‌​‌​​‌​‌‌​‌​‌‌​​​​‌​‌‌‌​​‌‌​‌‌‌​​‌‌​‌‌​‌​​‌​‌‌‌​​‌‌​‌‌‌​‌​​​‌‌​​​​‌​‌‌​‌‌‌​​‌‌‌​‌​​

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# hp_monitor.py
import cv2
import json
import numpy as np
import os

CONFIG_FILE = "config.json"
DEFAULT_HP_ROI = (10, 10, 200, 20)
DEFAULT_MP_ROI = (10, 35, 200, 20)


class HPMonitor:
def __init__(self):
self.hp_roi = DEFAULT_HP_ROI
self.mp_roi = DEFAULT_MP_ROI
self._load_config()

def _load_config(self):
if not os.path.exists(CONFIG_FILE):
return
with open(CONFIG_FILE) as f:
cfg = json.load(f)
for key in ("hp_roi", "mp_roi"):
if key in cfg:
setattr(self, key, tuple(cfg[key]))

def _color_ratio(self, frame, roi, lower, upper) -> float:
"""HSV 色相範圍遮罩 + 最右側有色像素欄 / 總寬度"""
x, y, w, h = roi
if w == 0 or h == 0:
return 0.0
hsv = cv2.cvtColor(frame[y:y+h, x:x+w], cv2.COLOR_BGR2HSV)
mask = cv2.inRange(hsv, np.array(lower), np.array(upper))
cols = np.any(mask > 0, axis=0)
if not np.any(cols):
return 0.0
return min(1.0, (int(np.max(np.where(cols))) + 1) / w)

def read(self, frame):
hp = self._color_ratio(frame, self.hp_roi,
[0, 100, 80], [10, 255, 255])
mp = self._color_ratio(frame, self.mp_roi,
[100, 100, 80], [130, 255, 255])
return hp, mp

💻 主程式:main.py

這段內容已加密
需要 ☕ 咖啡會員 或更高等級的密碼才能閱讀
💡 年度公開密碼,到 /support 直接取得

主程式按下「🎯 選取視窗」後滑鼠變十字,點擊遊戲視窗即鎖定 hwnd / 標題 / PID;再按「⚙ 校準血條」彈出 OpenCV 視窗框選 HP、MP 血條後自動寫回 config.json
圖:主程式按下「🎯 選取視窗」後滑鼠變十字,點擊遊戲視窗即鎖定 hwnd / 標題 / PID;再按「⚙ 校準血條」彈出 OpenCV 視窗框選 HP、MP 血條後自動寫回 config.json

以 tkinter 建立暗色主題輔助視窗,Worker Thread 即時擷取畫面並偵測 HP/MP,每 200ms 更新 UI 進度條與日誌
圖:以 tkinter 建立暗色主題輔助視窗,Worker Thread 即時擷取畫面並偵測 HP/MP,每 200ms 更新 UI 進度條與日誌

🚀 執行流程

1
python main.py
  1. 🎯 選取視窗 → 滑鼠變十字,點擊目標遊戲視窗即鎖定(hwnd、標題、PID)
  2. ⚙ 校準血條 → 彈出 OpenCV 視窗,依序框選 HP 血條與 MP 魔力條(Enter 確認 / C 重選)
  3. ▶ 啟動 → HP/MP 以 5fps 即時更新

下次啟動會自動讀取 config.json 裡已儲存的 ROI,不用重新校準。​‌‌‌​​​​​‌‌‌‌​​‌​‌‌‌​‌​​​‌‌​‌​​​​‌‌​‌‌‌‌​‌‌​‌‌‌​​​‌​‌‌​‌​‌‌​‌‌‌‌​‌‌‌​​​​​‌‌​​‌​‌​‌‌​‌‌‌​​‌‌​​​‌‌​‌‌‌​‌‌​​​‌​‌‌​‌​​‌‌​​‌​​​‌‌​​​​​​‌‌​​‌​​​‌‌​‌‌​​​‌‌​​​​​​‌‌​‌​​​​‌‌​​​‌​​‌‌‌​​‌​​‌​‌‌​‌​‌‌‌​​​​​‌‌‌‌​​‌​‌‌‌​‌​​​‌‌​‌​​​​‌‌​‌‌‌‌​‌‌​‌‌‌​​​‌​‌‌​‌​‌‌​‌‌‌‌​‌‌‌​​​​​‌‌​​‌​‌​‌‌​‌‌‌​​‌‌​​​‌‌​‌‌‌​‌‌​​​‌​‌‌​‌​‌‌‌​​​​​‌‌‌​​‌​​‌‌​‌‌‌‌​‌‌​‌​‌​​‌‌​​‌​‌​‌‌​​​‌‌​‌‌‌​‌​​​​‌​‌‌​‌​‌‌​‌‌​​​‌‌​‌​​‌​‌‌​‌‌‌​​‌‌​​‌​‌​‌‌​​​​‌​‌‌​​‌‌‌​‌‌​​‌​‌​​‌​‌‌​‌​‌‌​​​​‌​‌‌‌​​‌‌​‌‌‌​​‌‌​‌‌​‌​​‌​‌‌‌​​‌‌​‌‌‌​‌​​​‌‌​​​​‌​‌‌​‌‌‌​​‌‌‌​‌​​

⚠️ 常見問題

  • 血條偵測不準確:再按一次 ⚙ 校準血條 重新框選,範圍要涵蓋整條血條但不超出 UI 邊框。
  • HP 一直顯示 0%:調整 hp_monitor.py 的 H(色相)範圍,不同遊戲血條的紅 / 藍色調差異頗大。
  • 按 🎯 選取視窗 後點到錯的子視窗:程式已用 GetAncestor(GA_ROOT) 自動取頂層,若仍不正確就再按一次重選。
  • 按 🎯 選取視窗 沒反應:本功能用 GetAsyncKeyState 輪詢全域滑鼠,若被其他程式攔截(例如部分遠端桌面),改用滑鼠直接點實體視窗。
  • 畫面是黑的:視窗被最小化時 Windows 不 render 畫面,PrintWindow 拿不到內容;把視窗從工作列還原即可。

🎯 結語

本篇建立了整個系列的骨架:tkinter 暗色 UI、SharedState 執行緒安全架構、pywin32 視窗擷取,以及用 HSV 色彩比例偵測 HP/MP 的血量監控模組。

下一篇將加入 (二)自動補藥 功能,當 HP 或 MP 低於設定閾值時自動按下補藥熱鍵,並為 UI 增加閾值與熱鍵設定面板。

📖 如在學習過程中遇到疑問,或是想了解更多相關主題,建議回顧一下 Python | OpenCV 系列導讀,掌握完整的章節目錄,方便快速找到你需要的內容。

​‌‌‌​​​​​‌‌‌‌​​‌​‌‌‌​‌​​​‌‌​‌​​​​‌‌​‌‌‌‌​‌‌​‌‌‌​​​‌​‌‌​‌​‌‌​‌‌‌‌​‌‌‌​​​​​‌‌​​‌​‌​‌‌​‌‌‌​​‌‌​​​‌‌​‌‌‌​‌‌​​​‌​‌‌​‌​​‌‌​​‌​​​‌‌​​​​​​‌‌​​‌​​​‌‌​‌‌​​​‌‌​​​​​​‌‌​‌​​​​‌‌​​​‌​​‌‌‌​​‌​​‌​‌‌​‌​‌‌‌​​​​​‌‌‌‌​​‌​‌‌‌​‌​​​‌‌​‌​​​​‌‌​‌‌‌‌​‌‌​‌‌‌​​​‌​‌‌​‌​‌‌​‌‌‌‌​‌‌‌​​​​​‌‌​​‌​‌​‌‌​‌‌‌​​‌‌​​​‌‌​‌‌‌​‌‌​​​‌​‌‌​‌​‌‌‌​​​​​‌‌‌​​‌​​‌‌​‌‌‌‌​‌‌​‌​‌​​‌‌​​‌​‌​‌‌​​​‌‌​‌‌‌​‌​​​​‌​‌‌​‌​‌‌​‌‌​​​‌‌​‌​​‌​‌‌​‌‌‌​​‌‌​​‌​‌​‌‌​​​​‌​‌‌​​‌‌‌​‌‌​​‌​‌​​‌​‌‌​‌​‌‌​​​​‌​‌‌‌​​‌‌​‌‌‌​​‌‌​‌‌​‌​​‌​‌‌‌​​‌‌​‌‌‌​‌​​​‌‌​​​​‌​‌‌​‌‌‌​​‌‌‌​‌​​

註:以上參考了
pywin32 GitHub
tkinter 官方文件
WindowFromPoint - Win32 API
GetAsyncKeyState - Win32 API