Skip to content

Instantly share code, notes, and snippets.

@oneleo
Last active January 27, 2026 04:31
Show Gist options
  • Select an option

  • Save oneleo/dd1162a16f7c6efa250e39db1b2778e7 to your computer and use it in GitHub Desktop.

Select an option

Save oneleo/dd1162a16f7c6efa250e39db1b2778e7 to your computer and use it in GitHub Desktop.
AutoHotKeyV2_王國之心三_連點攻擊
; ========================================================
; AutoHotkey 腳本:王國之心三自動連點攻擊
; 使用說明:
; 1. 使用 Chocolatey 安裝 AutoHotKeyV2: choco install -y autohotkey.portable
; 2. 請將這份文字保存至 "D:\Users\Public\Documents\AutoHotkey\myahk_王國之心三_連點攻擊.ahk"
; 3. 開啟 AutoHotkey 請用 CMD.exe 執行以下指令:
; "%ProgramData%\chocolatey\lib\autohotkey.portable\tools\AutoHotkey.exe" "D:\Users\Public\Documents\AutoHotkey\myahk_王國之心三_連點攻擊.ahk"
; 4. 請截一張 512*512 大小的圖片,此圖片為在戰鬥結束時出現約 3 秒的全白畫面,並命名為 "D:/Users/Public/Documents/AutoHotkey/end.bmp"
; 5. 請在進到戰鬥傳送門,且戰鬥開始後再按 F8 啟動腳本,並在需要時按下 F9 以停止腳本
; ========================================================
#Requires AutoHotkey v2.0
#SingleInstance Force
; Coordinate system settings
CoordMode "Mouse", "Window"
CoordMode "Pixel", "Window"
; =========================
; Configuration
; =========================
global IMAGE_PATH := "D:/Users/Public/Documents/AutoHotkey/end.bmp" ; 圖片路徑
global GAME_WINDOW_TITLE := "KINGDOM HEARTS III" ; 遊戲視窗標題
global IMAGE_CHECK_INTERVAL := 500 ; 圖像檢測間隔 (毫秒)
global IMAGE_TOLERANCE := 1 ; 圖像匹配容差 (0-255, 越大越寬鬆)
global COOLDOWN_DURATION := 45000 ; 冷卻時間 (毫秒) - 45 秒
global SHOULD_MOVE_FORWARD := true
; =========================
; Global State
; =========================
global isRunning := false
global isPaused := false
global heldKeys := Map()
global wasdKeys := ["w", "a", "s", "d"] ; 改為小寫避免 Shift
global wasdIndex := 1
global gameWinID := 0 ; 遊戲視窗 ID
global lastTriggerTime := 0 ; 上次觸發時間 (新增)
; =========================
; Hotkeys
; =========================
F8::StartAll()
F9::StopAll()
; =========================
; Master Control
; =========================
StartAll()
{
global isRunning, wasdIndex, isPaused, gameWinID, lastTriggerTime
if (isRunning)
return
; Get game window handle
if (!WinExist(GAME_WINDOW_TITLE))
{
MsgBox "找不到遊戲視窗: " . GAME_WINDOW_TITLE . "`n請確認遊戲已啟動或修改 GAME_WINDOW_TITLE 變數", "錯誤", "Icon!"
return
}
gameWinID := WinExist(GAME_WINDOW_TITLE)
isRunning := true
isPaused := false
wasdIndex := 1
lastTriggerTime := 0 ; 重置冷卻時間
HoldKey("d")
SetTimer PressEnter, 99
SetTimer PressR, 3000
SetTimer ImageDetector, IMAGE_CHECK_INTERVAL
ToolTip "自動腳本已啟動 (F9 停止)"
SetTimer () => ToolTip(), -3000 ; 3 秒後隱藏提示
}
StopAll()
{
global isRunning
isRunning := false
SetTimer PressEnter, 0
SetTimer PressR, 0
SetTimer ImageDetector, 0
ReleaseAllKeys()
ToolTip "自動腳本已停止"
SetTimer () => ToolTip(), -2000
}
; =========================
; Image Detection (MODIFIED - 加入冷卻機制)
; =========================
ImageDetector()
{
global isRunning, isPaused, gameWinID, lastTriggerTime, COOLDOWN_DURATION
if (!isRunning || isPaused)
return
; Check cooldown status
currentTime := A_TickCount
timeSinceLastTrigger := currentTime - lastTriggerTime
if (lastTriggerTime > 0 && timeSinceLastTrigger < COOLDOWN_DURATION)
{
; Still in cooldown period - skip detection
remainingCooldown := (COOLDOWN_DURATION - timeSinceLastTrigger) // 1000 ; Convert to seconds
; Optional: Show cooldown status (comment out if too annoying)
; ToolTip "冷卻中: " . remainingCooldown . " 秒"
return
}
; Check if game window still exists
if (!WinExist("ahk_id " . gameWinID))
{
StopAll()
MsgBox "遊戲視窗已關閉,腳本自動停止", "通知", "Icon!"
return
}
; Get game window size
WinGetPos &winX, &winY, &winWidth, &winHeight, "ahk_id " . gameWinID
; Search area: center 1/2 of window
searchX1 := winWidth // 4
searchY1 := winHeight // 4
searchX2 := winWidth * 3 // 4
searchY2 := winHeight * 3 // 4
; Activate game window for coordinate accuracy
WinActivate "ahk_id " . gameWinID
; Search for image
try
{
if (ImageSearch(&foundX, &foundY, searchX1, searchY1, searchX2, searchY2, "*" . IMAGE_TOLERANCE . " " . IMAGE_PATH))
{
; Image found - record trigger time and execute
lastTriggerTime := A_TickCount ; 記錄觸發時間
ExecuteInterruptSequence()
}
}
catch as err
{
; Image file not found or other error
StopAll()
MsgBox "圖像搜尋錯誤: " . err.Message . "`n`n請確認圖片路徑正確: " . IMAGE_PATH, "錯誤", "Icon!"
}
}
ExecuteInterruptSequence()
{
global isPaused, gameWinID
isPaused := true
; === STEP 1: 完全停止所有 Timer (新增) ===
SetTimer PressEnter, 0
SetTimer PressR, 0
SetTimer ImageDetector, 0
; Release all held keys temporarily
ReleaseAllKeys()
; Visual feedback
ToolTip "偵測到圖片!執行中斷序列... (冷卻 45 秒)"
; === STEP 2: 確保視窗持續激活 ===
;WinActivate "ahk_id " . gameWinID
;Sleep 200 ; 等待視窗激活
; Wait 18 seconds
Sleep 18000
; Press s (小寫避免 Shift) 走向前
if (SHOULD_MOVE_FORWARD)
{
PressKey("w", 399, 399)
Sleep 1000
}
; === STEP 3: 強制重新激活視窗 ===
;WinActivate "ahk_id " . gameWinID
;Sleep 300
; Press f (小寫避免 Shift) 點選戰鬥傳送門
PressKey("f", 40, 80)
Sleep 2000
; === STEP 4: 再次確認焦點 ===
;WinActivate "ahk_id " . gameWinID
;Sleep 200
; Press s (小寫避免 Shift) 選擇「是」
PressKey("s", 40, 80)
Sleep 1000
; === STEP 5: 最後確認焦點 + 使用正確按鍵名稱 ===
;WinActivate "ahk_id " . gameWinID
;Sleep 300
; 方案 A: 使用大寫 Enter (推薦) 確認
PressKey("Enter", 40, 80)
PressKey("Enter", 40, 80)
PressKey("Enter", 40, 80)
; 方案 B: 如果方案 A 無效,改用 SendEvent (取消下行註解)
; SendEvent "{Enter Down}"
; Sleep Random(40, 80)
; SendEvent "{Enter Up}"
Sleep 3000 ; 等待遊戲響應
; === STEP 6: 恢復操作 ===
; Restore held keys
HoldKey("d")
; Resume normal operations
isPaused := false
; 重新啟動 Timer
SetTimer PressEnter, 99
SetTimer PressR, 3000
SetTimer ImageDetector, IMAGE_CHECK_INTERVAL
ToolTip "中斷序列完成,恢復正常操作 (冷卻進行中)"
SetTimer () => ToolTip(), -2000
}
; =========================
; Timers (MODIFIED)
; =========================
PressEnter()
{
global isRunning, isPaused
if (!isRunning || isPaused)
return
PressKey("Enter", 40, 70)
}
PressR()
{
global isRunning, isPaused
if (!isRunning || isPaused)
return
PressKey("r", 60, 120)
}
WASDCycleStep()
{
global wasdIndex, wasdKeys, isRunning, isPaused
if (!isRunning || isPaused)
return
PressKey(wasdKeys[wasdIndex], 60, 100)
wasdIndex := wasdIndex >= wasdKeys.Length ? 1 : wasdIndex + 1
}
; =========================
; Input Utilities
; =========================
PressKey(key, downMin := 40, downMax := 80)
{
Send "{" . key . " Down}"
Sleep Random(downMin, downMax)
Send "{" . key . " Up}"
}
HoldKey(key)
{
global heldKeys
if (heldKeys.Has(key))
return
Send "{" . key . " Down}"
heldKeys[key] := true
}
ReleaseAllKeys()
{
global heldKeys
for key in heldKeys
Send "{" . key . " Up}"
heldKeys.Clear()
}
; =========================
; 運作流程圖(主程式)
; =========================
;F8 啟動
; ↓
;持續按住 D 鍵
; ↓
;┌─────────────────────────────┐
;│ 每 99ms → 按 Enter │
;│ 每 3000ms → 按 R │
;│ 每 500ms → 檢查 end.png │ ← 平行執行
;└─────────────────────────────┘
; ↓ (偵測到圖片)
;暫停所有操作 (isPaused = true)
; ↓
;等待 9 秒 → F → 等 1 秒 → S → 等 1 秒 → Enter
; ↓
;恢復操作 (isPaused = false)
; ↓
;繼續循環...
; =========================
; 運作流程圖(偵測圖片)
; =========================
;ImageDetector() 每 500ms 執行
; ↓
; 檢查冷卻狀態
; ↓
;┌────────┴────────┐
;│ 冷卻中? │
;│ (距上次<30秒) │
;└────────┬────────┘
; ├─ 是 → 跳過偵測,直接返回
; │
; └─ 否 → 執行圖像搜尋
; ↓
; 找到圖片?
; ↓
; ┌────┴────┐
; │ 是 │ 否
; ↓ └→ 繼續循環
; 記錄 lastTriggerTime
; 執行中斷序列 (15秒等待 + 按鍵)
; ↓
; 進入 30 秒冷卻期
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment