У меня есть код аимбота на Python с YOLOv11 для Fortnite, но у меня не получается сделать позиционирование прицела, прицел прыгает вокруг цели
моя модель
Вот мой код
import cv2
import numpy as np
from ultralytics import YOLO
import torch
import ctypes
from ctypes.wintypes import DWORD, WORD
import keyboard
import mss
import win32api
import win32gui
import vgamepad as vg
# Инициализация виртуального геймпада (DualShock4)
gamepad = vg.VDS4Gamepad()
# Чувствительность для джойстика
sensitivity = 150.0
model = YOLO('runs/detect/train/weights/best.pt')
sct = mss.mss()
TARGET_CLASS = "player"
screen_width = win32api.GetSystemMetrics(0)
screen_height = win32api.GetSystemMetrics(1)
center_point = (screen_width // 2, screen_height // 2)
print(f"Screen resolution: {screen_width}x{screen_height}")
device = 'cuda' if torch.cuda.is_available() else 'cpu'
print("Используется:", device) # cuda - видеокарта, cpu - процессор (Лучше cuda)
# Структуры для мыши (оставлены для справки, но не используются с геймпадом)
emptyLong = ctypes.c_ulong()
class MouseInput(ctypes.Structure):
_fields_ = [("dx", ctypes.c_long),
("dy", ctypes.c_long),
("mouseData", DWORD),
("dwFlags", DWORD),
("time", DWORD),
("dwExtraInfo", ctypes.POINTER(ctypes.c_ulong))]
class KeybdInput(ctypes.Structure):
_fields_ = [("wVk", WORD),
("wScan", WORD),
("dwFlags", DWORD),
("time", DWORD),
("dwExtraInfo", ctypes.POINTER(ctypes.c_ulong))]
class HardwareInput(ctypes.Structure):
_fields_ = [("uMsg", DWORD),
("wParamL", WORD),
("wParamH", WORD)]
class InputList(ctypes.Union):
_fields_ = [("mi", MouseInput),
("ki", KeybdInput),
("hi", HardwareInput)]
class Input(ctypes.Structure):
_fields_ = [("type", ctypes.c_ulong),
("inputList", InputList)]
MOUSEEVENTF_MOVE = 0x0001
MOUSEEVENTF_ABSOLUTE = 0x8000
# Получение позиции и размера окна игры
game_window_title = "Fortnite"
hwnd = win32gui.FindWindow(None, game_window_title)
if hwnd:
rect = win32gui.GetWindowRect(hwnd)
window_x, window_y, window_width, window_height = rect[0], rect[1], rect[2] - rect[0], rect[3] - rect[1]
client_rect = win32gui.GetClientRect(hwnd)
client_width, client_height = client_rect[2] - client_rect[0], client_rect[3] - client_rect[1]
else:
print("Окно игры не найдено!")
window_x, window_y, client_width, client_height = 0, 0, 1920, 1080
# Определение параметров геймпада
if isinstance(gamepad, vg.VX360Gamepad):
GAMEPAD_TYPE = "X360"
CENTER = 0
MIN_VAL = -32768
MAX_VAL = 32767
SIGN_Y = -1
SCALE_FACTOR = 1
elif isinstance(gamepad, vg.VDS4Gamepad):
GAMEPAD_TYPE = "DS4"
CENTER = 128
MIN_VAL = 0
MAX_VAL = 255
SIGN_Y = 1 # Исправлено для DualShock4
SCALE_FACTOR = 127.5 / 32767.5
else:
raise ValueError("Unsupported gamepad type")
MOUSEEVENTF_MOVE = 0x0001
MOUSEEVENTF_ABSOLUTE = 0x8000
# Получение позиции и размера окна игры
game_window_title = "Fortnite"
hwnd = win32gui.FindWindow(None, game_window_title)
if hwnd:
rect = win32gui.GetWindowRect(hwnd)
window_x, window_y, window_width, window_height = rect[0], rect[1], rect[2] - rect[0], rect[3] - rect[1]
client_rect = win32gui.GetClientRect(hwnd)
client_width, client_height = client_rect[2] - client_rect[0], client_rect[3] - client_rect[1]
else:
print("Окно игры не найдено!")
window_x, window_y, client_width, client_height = 0, 0, 1920, 1080
# Параметры для DualShock4
CENTER = 128
MIN_VAL = 0
MAX_VAL = 255
STICK_OFFSET = 250 # Начальное значение для отклонения джойстика (подстройте под игру)
def real_time_detect(image):
# Получаем результаты детекции
results = model(image)[0]
# Исходное изображение
image = results.orig_img
# Словарь классов и цвета для визуализации
classes_names = results.names
colors = np.random.uniform(0, 255, size=(len(classes_names), 3))
# Сбор детекций
detections = []
# Обрабатываем каждую детекцию
for box, cls, conf in zip(results.boxes.xyxy.cpu().numpy(),
results.boxes.cls.cpu().numpy(),
results.boxes.conf.cpu().numpy()):
class_id = int(cls)
class_name = classes_names[class_id]
box = box.astype(np.int32)
confidence = float(conf)
# Добавляем детекцию в список
detections.append((class_name, confidence, box, class_id))
# Визуализация (опционально)
color = colors[class_id % len(colors)]
x1, y1, x2, y2 = box
cv2.rectangle(image, (x1, y1), (x2, y2), color, 2)
cv2.putText(image, f"{class_name} {confidence:.2f}",
(x1, y1 - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.4, color, 2)
# Отображение общего количества объектов
cv2.putText(image, f'Total objects: {len(detections)}',
(10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)
return image, detections
# Функция для поиска ближайшей цели
def find_closest_target(detections, center_point):
target_detections = [d for d in detections if d['class_name'] == TARGET_CLASS]
if not target_detections:
return None
closest = None
min_distance = float('inf')
for detection in target_detections:
x, y, w, h = detection['bbox']
target_center_x = (x + w / 2).item()
target_center_y = (y + h / 2).item()
distance = ((target_center_x - center_point[0]) ** 2 + (target_center_y - center_point[1]) ** 2) ** 0.5
if distance < min_distance:
min_distance = distance
closest = (int(target_center_x), int(target_center_y))
return closest
def check_pgup():
return keyboard.is_pressed('pgup')
def capture_screen(img):
"""Захват всего экрана"""
img = np.array(img)
return cv2.cvtColor(img, cv2.COLOR_BGRA2BGR)
# Основной цикл
cap = cv2.VideoCapture(0)
cap.set(3, screen_width)
cap.set(4, screen_height)
# Проверка разрешения захвата
w = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
h = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
print(f"Capture resolution: {w}x{h}")
if w != screen_width or h != screen_height:
print("Warning: Capture resolution does not match screen resolution! Adjust OBS settings.")
while True:
ret, frame = cap.read()
if not ret:
continue
# Выполнение детекции
results = model(frame, agnostic_nms=True)
detections = []
for r in results:
boxes = r.boxes
for box in boxes:
x1, y1, x2, y2 = box.xyxy[0]
x, y, w, h = x1, y1, x2 - x1, y2 - y1
conf = box.conf[0]
cls = int(box.cls[0])
class_name = model.names[cls]
detections.append({'bbox': (x, y, w, h), 'conf': conf, 'class_name': class_name})
# Визуализация детекций
for det in detections:
x, y, w, h = det['bbox']
cv2.rectangle(frame, (int(x), int(y)), (int(x+w), int(y+h)), (0, 255, 0), 2)
cv2.putText(frame, f"{det['class_name']} {det['conf']:.2f}", (int(x), int(y-10)), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)
cv2.imshow('YOLO Vision', frame)
# Проверка нажатия 'Page Up' для активации аимбота
if keyboard.is_pressed('page up'): # Используем 'page up' для надежности
if detections:
target = find_closest_target(detections, center_point)
if target:
# Вычисляем смещение до цели
offset_x = target[0] - center_point[0]
offset_y = target[1] - center_point[1]
# Определяем направление движения
dir_x = 1 if offset_x > 0 else -1 if offset_x < 0 else 0
dir_y = 1 if offset_y > 0 else -1 if offset_y < 0 else 0
# Устанавливаем небольшое отклонение джойстика
stick_x = CENTER + dir_x * STICK_OFFSET
stick_y = CENTER + dir_y * STICK_OFFSET
# Ограничиваем значения в диапазоне 0-255
stick_x = max(min(stick_x, MAX_VAL), MIN_VAL)
stick_y = max(min(stick_y, MAX_VAL), MIN_VAL)
# Устанавливаем положение джойстика
gamepad.right_joystick(int(stick_x), int(stick_y))
gamepad.update()
print(f"Moving to {target} with joystick values: x={stick_x}, y={stick_y}")
else:
# Возвращаем джойстик в нейтральное положение
gamepad.right_joystick(int(CENTER), int(CENTER))
gamepad.update()
# Выход из цикла при нажатии 'q'
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# Освобождение ресурсов
cap.release()
cv2.destroyAllWindows()
gamepad.reset()
я пытался сделать наводку но прицел не наводится на персонажа а прыгает туда сюда