Как на Python реализовать алгоритм автоматического перемещения персонажа по заранее заданному маршруту в игре Genshin Impact?

Я разрабатываю на Python систему построения маршрутов для Genshin Impact: цель — автоматически прокладывать путь персонажа между точками фарма. Пробовал несколько подходов, но столкнулся с проблемами:
  • 15 июня 2026 г. 0:00
Ответы на вопрос 2
Коротко и прямо — две важных вещи перед тем, как продолжить:
1) Genshin Impact — онлайн-ориентированная игра, автоматизация управления персонажем (особенно в фоновом режиме/без участия игрока) почти наверняка нарушает правила использования и может привести к бану. Я не могу помогать в создании читов/эксплойтов или в обходе защиты.  
2) Я могу помочь с алгоритмом построения маршрута, с архитектурой и с примером «научно-образовательного» прототипа на Python (используя внешние средства захвата экрана и управления клавиатурой). Использовать это на реальном аккаунте — ваш риск.

Ниже — практическое руководство и примерные решения, которые можно использовать для разработки системы построения маршрута и отладки (например, в исследовательских целях, для автономного теста в оффлайн‑сценарии, или для генерации удобных маршрутов для человека).

1) Общая архитектура
- Представление маршрута: список контрольных точек (waypoints) в удобной системе координат — пиксели мини‑карты или мировые координаты (если доступны).
- Локализация: периодически определяем текущее положение/ориентацию персонажа (через мини‑карту или OCR/визуальное распознавание).
- Навигация: для перехода между точками — алгоритм вычисления вектора движения, поворота камеры и нажатий клавиш.
- Обход препятствий: простые эвристики (обойти влево/вправо, прыгнуть, перегенерировать путь), или полноценный локальный планировщик (A*, DWA, RRT) при доступной карте/навигационной сетке.
- Надёжность: детекция «застревания», таймауты, логирование, плавность движений (человеческие паузы), адаптация к пингу/фризам.

2) Алгоритм высокого уровня (итеративно)
- Задать список waypoints: [(x1,y1), (x2,y2), ...] — координаты на мини‑карте или в мире.
- На каждом шаге:
  1. Считать экран/мини‑карту, найти позицию и ориентацию игрока.
  2. Вычислить вектор до текущей цели: delta = goal - pos.
  3. Если расстояние < порог — переключиться на следующий waypoint.
  4. Вычислить требуемый угол поворота; вращать камеру или выполнять поворот персонажа.
  5. Нажать «движение вперёд» и корректировать клавиши (A/D) для центровки на цель.
  6. Отслеживать прогресс: если расстояние не уменьшается за N секунд — считать «застрял» и выполнить эвакуационную манёвру (прыжок, поворот, короткий откат), либо добавить промежуточную точку в сторону.
  7. Плавность: не делать мгновенных резких нажатий — имитировать человеческие задержки и микрокоррекции.

3) Подходы к локализации
- Мини‑карта: часто самый надёжный способ — найти ячейку/иконку игрока на мини‑карте (шаблонное сопоставление OpenCV), конвертировать пиксели мини‑карты в координаты маршрута.
- Визуальные ориентиры: сопоставление фрагментов (SIFT/ORB) — если хотите локализоваться на большой карте.
- Внутриигровые данные: чтение памяти/пакетов — обычно запрещено и рискованно.

4) Управление движением
- Простейшая реализация: pyautogui или pynput для нажатий клавиш/движения мыши. Недостатки: зависимость от фокуса окна, легко детектируется.
- Боле тонко: управлять камерой мышью (плавный drag) и держать клавишу вперед в течение интервала, корректируя углы.
- Управляющий контроллер: реализовать PID для угла поворота (чтобы избежать «перескакиваний»).

5) Обход препятствий и локальное планирование
- Если у вас карта/навигационная сетка: A* + сглаживание (Bezier) — оптимально.
- Без карты: поведенческий подход: «стукнулся» -> повернуть на 45°, шаг в сторону, двигаться дальше; или генерировать круговую траекторию вокруг препятствия.
- Детекция препятствий: сравнивать ожидаемое расстояние до цели с реальным; оптический поток (OpenCV) для определения, движется ли экран.

6) Простейший примерный прототип на Python (минимальный, на основе мини‑карты + pyautogui + OpenCV)
Примечание: код ниже — образовательный. Требует настройки шаблона и координат мини‑карты.

from time import sleep, time
import cv2
import numpy as np
import pyautogui

# Настройки (подгоните под свой экран)
MINIMAP_REGION = (1700, 50, 300, 300)  # (left, top, width, height) — пример
PLAYER_TEMPLATE = cv2.imread('player_marker.png', cv2.IMREAD_UNCHANGED)  # шаблон маркера на миникарте
WAYPOINTS = [(150, 120), (220, 80), (50, 200)]  # координаты в пикселях миникарты

def grab_minimap():
    img = pyautogui.screenshot(region=MINIMAP_REGION)
    return cv2.cvtColor(np.array(img), cv2.COLOR_RGB2BGR)

def find_player(minimap):
    res = cv2.matchTemplate(minimap, PLAYER_TEMPLATE, cv2.TM_CCOEFF_NORMED)
    _, maxval, _, maxloc = cv2.minMaxLoc(res)
    if maxval < 0.7:
        return None
    w,h = PLAYER_TEMPLATE.shape[1], PLAYER_TEMPLATE.shape[0]
    cx = maxloc[0] + w/2
    cy = maxloc[1] + h/2
    return (int(cx), int(cy))

def move_towards(delta_x, delta_y):
    # простая логика: поворот мышью и удержание вперёд
    angle = np.arctan2(-delta_y, delta_x)  # вектор в координатах миникарты
    deg = np.degrees(angle)
    # Повернуть камеру: имитируем движение мыши в пикселях в зависимости от угла
    dx = int(np.cos(angle) * 50)
    dy = int(np.sin(angle) * 50)
    pyautogui.mouseDown()  # захват мыши, если нужно
    pyautogui.moveRel(dx, dy, duration=0.15)
    pyautogui.mouseUp()
    # Нажать вперед
    pyautogui.keyDown('w')
    sleep(0.6)  # движение вперёд
    pyautogui.keyUp('w')

def distance(a,b):
    return ((a[0]-b[0])**2 + (a[1]-b[1])**2)**0.5

def main_loop():
    cur_wp = 0
    stuck_timer = time()
    last_dist = None
    while cur_wp < len(WAYPOINTS):
        minimap = grab_minimap()
        pos = find_player(minimap)
        if pos is None:
            print("Игрок не найден на миникарте")
            sleep(1)
            continue
        goal = WAYPOINTS[cur_wp]
        d = distance(pos, goal)
        if d < 15:
            print("Достигнута точка", cur_wp)
            cur_wp += 1
            sleep(0.5)
            continue
        delta = (goal[0]-pos[0], goal[1]-pos[1])
        move_towards(*delta)
        # простая проверка застревания
        if last_dist is None or d < last_dist - 2:
            stuck_timer = time()
        else:
            if time() - stuck_timer > 3.0:
                print("Кажется, застряли. Выполняю эвакуацию.")
                pyautogui.press('space')  # прыжок
                sleep(0.5)
                pyautogui.keyDown('s'); sleep(0.4); pyautogui.keyUp('s')
                stuck_timer = time()
        last_dist = d
        sleep(0.1)

if __name__ == '__main__':
    sleep(3)  # время, чтобы переключиться в окно игры
    main_loop()

7) Советы по улучшению
- Калибровка: шаблон игрока, масштаб мини‑карты, соотношение пикселей↔мир.
- Плавность: реализуйте PID для контроля угла и скоростей.
- Локальный планировщик: если карту можно получить, делайте A* по сетке/навмешу и сглаживайте путь.
- Тестируйте в безопасной среде (offline, тренировки).
- Логирование и симуляция с низкой скоростью для отладки.

8) Ресурсы и методы
- Книги/статьи: «Artificial Intelligence for Games» (Sean E. Luke) — по навигации и поведению.
- Steering behaviors (seek, arrive, obstacle avoidance) — классический набор.
- Алгоритмы планирования: A*, Dijkstra, DWA (Dynamic Window Approach), RRT.

Если скажете, какие конкретно у вас были проблемы (локализация не работает, персонаж застревает, поворот камеры не синхронизуется и т. п.), опишете вашу текущую реализацию (как получаете координаты, что используете для ввода), я смогу дать более конкретные рекомендации или помочь доработать код.
без доступа к внутрянке, сложно. <br/> <br/> Миникарта - как отправная точка, вы точно пробовали? потому что точность там в играх  достаточно неплохая. <br/> <br/> Есть SAM, очень быстрый алгоритм машинного зрения, дает подробно с масками, с метками что есть что. Т.е. можно двигаться по миникарте, уточняя положение по информации от машинного зрения. Кстати, покрутить камерой под известными боту углами, позволят с отличной точностью определить координаты объектов относительно центра (персонажа), т.е. идете, и периодически покачиваете камерой влево вправо. Так как бот знает на какой угол повернул камеру (на миникарте это тоже видно) то можно рассчитать, где ожидать какой-нибудь объект, и сравнивая смещение  между тем что возвращает SAM и тем что ожидалось <b>при повороте камеры или на сколько шагов сдвинулся или при прыжках</b> , покажет, на сколько смещен объект от плоскости относительно персонажа. <br/> <br/> Так можно детектить препятствия, кочки, деревья, монстров (кстати по подписям они детектятся еще проще), так же можно детектить что бот застрял (он перестал двигаться при нажатой кнопке движения) и тоже принимать решение. <br/> <br/> разметка объектов (без смысловой привязки) <br/> <a href="https://github.com/facebookresearch/sam3" rel="nofollow">https://github.com/facebookresearch/sam3</a> <br/> <a href="https://huggingface.co/facebook/sam3" rel="nofollow">https://huggingface.co/facebook/sam3</a> <br/> <br/> смысловая разметка <br/> <a href="https://github.com/sithu31296/semantic-segmentation" rel="nofollow">https://github.com/sithu31296/semantic-segmentation</a> <br/> <br/> готовый sdk для realtime <br/> <a href="https://developer.nvidia.com/deepstream-sdk" rel="nofollow">https://developer.nvidia.com/deepstream-sdk</a> <br/> <a href="https://github.com/NVIDIA-AI-IOT/deepstream_python_apps" rel="nofollow">https://github.com/NVIDIA-AI-IOT/deepstream_python_apps</a> <br/> <br/> segnet для jetson (по уму на всех nvidia картах заведется) <br/> <a href="https://github.com/dusty-nv/jetson-inference" rel="nofollow">https://github.com/dusty-nv/jetson-inference</a> <br/> <br/> для любых видеокарт <br/> <a href="https://github.com/openvinotoolkit/openvino" rel="nofollow">https://github.com/openvinotoolkit/openvino</a>
Похожие вопросы