Внутриигровой X = Экранный X мыши - X левого верхнего угла окна игры
Внутриигровой Y = Экранный Y мыши - Y левого верхнего угла окна игрыДля большей точности следует использовать не угол всего окна, а угол клиентской области (исключая заголовок и рамки).
; Координаты левого верхнего угла окна игры (нужно получить заранее)
winX = 100
winY = 80
; Получаем экранные координаты мыши
MouseGetPos, mouseX, mouseY
; Пересчитываем в координаты внутри окна игры
gameX := mouseX - winX
gameY := mouseY - winYВажные замечания:
На этапе разработки вводить координаты вручную утомительно. Гораздо эффективнее сделать хоткей, который при нажатии будет автоматически подставлять текущие координаты мыши в поля GUI скрипта.
; Регистрируем хоткей F1
Hotkey, F1, GetMousePos
return
GetMousePos:
MouseGetPos, mx, my
GuiControl,, FindX, %mx%
GuiControl,, FindY, %my%
ToolTip, Захвачены координаты: X%mx% Y%my%
SetTimer, RemoveTip, -2000
returnТеперь достаточно навести мышь на нужную точку и нажать F1 — координаты автоматически заполнят поля «Поиск X / Поиск Y». При необходимости можно назначить разные хоткеи на разные поля.
Исходный скрипт содержал четыре независимые клавиши, каждая со своей задержкой. Однако в реальной игре часто требуется последовательно отправлять две клавиши (например, сначала навык, затем вспомогательное действие) и только потом выдерживать паузу.
Направления изменений:
SendKeyGroup(useGroup, keyA, keyB, waitMs, minute) {
global TimerCount, TargetHwnd
if (useGroup != 1)
return
if (minute > 0 and Mod(TimerCount, minute * 60) = 0) {
; Отправляем группу клавиш раз в N минут
ControlSend, , {%keyA%}, ahk_id %TargetHwnd%
Sleep, 100
ControlSend, , {%keyB%}, ahk_id %TargetHwnd%
}
if (minute = 0) {
; Отправляем группу клавиш каждый цикл
ControlSend, , {%keyA%}, ahk_id %TargetHwnd%
Sleep, 100
ControlSend, , {%keyB%}, ahk_id %TargetHwnd%
}
}Это самый частый выбор при написании игровых скриптов на AHK:
| Способ | Преимущества | Недостатки |
|---|---|---|
| Легко остановить, не блокирует скрипт, четкая структура | Минимальный интервал ~1 секунда, не подходит для высокочастотных операций |
| Точный контроль интервала между итерациями | Для остановки нужен дополнительный механизм, легко «зависнуть» |
Если вашей игре требуется выполнять действия раз в секунду или реже (например, повторное использование навыков, периодическое наложение баффов), SetTimer — более чистый выбор. Если же нужен контроль с точностью до миллисекунд, лучше использовать цикл Sleep с условием break.
PostMessage или искать другие оконные сообщения. {F1}, {Enter}. MouseGetPos, , , TargetHwndControlClick могут смещаться. Рекомендуется использовать оконный режим игры и установить масштаб отображения на 100%.Превращение простого скрипта переднего плана в фоновую многоклавишную систему сводится к нескольким ключевым изменениям: выбор фоновых команд (ControlSend / ControlClick), пересчет координат в контексте окна и выбор способа управления основным циклом. Приведенные в статье примеры модификаций можно напрямую применять к скриптам для «Water Margin Online» или других игр со схожими требованиями к автоматизации. Если ваша игра использует особые комбинации клавиш или требует кликов по координатам, рекомендую начать тестирование с минимальной версии, работающей в фоне, и постепенно наращивать функционал.