本文記錄使用 VC++ 6.0 開發 QQ 連連看遊戲外掛的完整過程,涵蓋視窗句柄取得、遊戲畫面影像擷取、圖塊特徵編碼、連連看路徑尋找演算法、滑鼠模擬點擊等核心技術。
CDC 進行畫面存取struct MYCOLOR { COLORREF c[4]; }; // 4 個採樣點顏色
MYCOLOR tc[230]; // 圖塊類型顏色表
int map[19][11]; // 遊戲盤面索引陣列 (19欄 x 11列)
int tcnum = 1; // 目前圖塊種類計數
void CZg1Dlg::OnButton3() {
int t[4] = {15, 11, 15, 21}; // X 方向相對偏移
int tt[4] = {17, 17, 21, 17}; // Y 方向相對偏移
CPoint p(10, 180); // 遊戲區左上角座標
CDC* pdc = myc->GetDC(); // 取得遊戲視窗 DC
for (int i=0; i<11; i++) { // 列
p.y = 180 + i * 35; // 每列高 35 像素
for (int j=0; j<19; j++) { // 欄
p.x = 10 + j * 31; // 每欄寬 31 像素
// 取得 4 個採樣點顏色
MYCOLOR tmp;
for (int k=0; k<4; k++)
tmp.c[k] = pdc->GetPixel(p.x + t[k], p.y + tt[k]);
// 偵測空白格(特定顏色範圍)
int sh = 0;
for (int t_t=0; t_t<4; t_t++) {
int r = GetRValue(tmp.c[t_t]);
int g = GetGValue(tmp.c[t_t]);
int b = GetBValue(tmp.c[t_t]);
if (r>45 && r<73 && g>50 && g<90 && b>103 && b<129) sh++;
}
if (sh == 4) { map[j][i] = 0; continue; } // 空白格
// 比對現有圖塊類型
int result = findcolor(tmp);
if (result == -1) { // 新類型
tc[tcnum] = tmp;
map[j][i] = tcnum++;
} else {
map[j][i] = result;
}
}
}
// ... 後續驗證與除錯輸出 ...
}
演算法需判斷兩座標間是否存在「最多 2 個轉彎(3 段直線)」的無阻擋路徑。常用策略:
// 使用 SendInput 或 mouse_event 模擬點擊
INPUT input = {0};
input.type = INPUT_MOUSE;
input.mi.dwFlags = MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP;
SendInput(1, &input, sizeof(INPUT));
需點擊兩次滑鼠才能消除一對:因遊戲要求真實滑鼠點擊一次才觸發選取狀態,外掛模擬的第二次點擊才能完成消除。可嘗試鍵盤鉤子或驅動層模擬改善。