2
votes

Clic de souris Python pour le jeu (entrée directe)

J'ai beaucoup cherché des simulations de clics de souris et de mouvements pour les jeux directx. J'ai trouvé de bonnes sources sur la pression des touches, mais rien pour la souris. En fait, il existe un bon sujet de stackoverflow sur la pression des touches avec saisie directe ( Simuler les pressions de touches Python pour contrôler un jeu ). Mais je n'ai pas assez d'expérience pour le faire fonctionner pour les clics de souris sur un certain emplacement.

J'ai essayé beaucoup de modules python comme pyautogui, win32 etc. ils ne fonctionnent pas. Même j'ai essayé de cliquer dessus sur autohotkey avec l'envoi d'arguments au fichier '.ahk' mais ce n'est pas stable et ce n'est pas un bon moyen. J'apprécierai pour chaque commentaire. Je travaille juste sur ce clic pendant 2 jours et je suis totalement perdu. Merci!


J'ai trouvé ce code de reddit pour les clics dans le jeu mais il ne fonctionne pas non plus.

import ctypes

PUL = ctypes.POINTER(ctypes.c_ulong)

class KeyBdInput(ctypes.Structure):
    _fields_ = [("wVk", ctypes.c_ushort),
                ("wScan", ctypes.c_ushort),
                ("dwFlags", ctypes.c_ulong),
                ("time", ctypes.c_ulong),
                ("dwExtraInfo", PUL)]


class HardwareInput(ctypes.Structure):
    _fields_ = [("uMsg", ctypes.c_ulong),
                ("wParamL", ctypes.c_short),
                ("wParamH", ctypes.c_ushort)]


class MouseInput(ctypes.Structure):
    _fields_ = [("dx", ctypes.c_long),
                ("dy", ctypes.c_long),
                ("mouseData", ctypes.c_ulong),
                ("dwFlags", ctypes.c_ulong),
                ("time", ctypes.c_ulong),
                ("dwExtraInfo", PUL)]


class Input_I(ctypes.Union):
    _fields_ = [("ki", KeyBdInput),
                ("mi", MouseInput),
                ("hi", HardwareInput)]

class Input(ctypes.Structure):
    _fields_ = [("type", ctypes.c_ulong),
                ("ii", Input_I)]

def set_pos(x, y):
    x = 1 + int(x * 65536./1920.)
    y = 1 + int(y * 65536./1080.)
    extra = ctypes.c_ulong(0)
    ii_ = Input_I()
    ii_.mi = MouseInput(x, y, 0, (0x0001 | 0x8000), 0, ctypes.pointer(extra))
    command = Input(ctypes.c_ulong(0), ii_)
    ctypes.windll.user32.SendInput(1, ctypes.pointer(command), ctypes.sizeof(command))

def left_click():
    extra = ctypes.c_ulong(0)
    ii_ = Input_I()
    ii_.mi = MouseInput(0, 0, 0, 0x0002, 0, ctypes.pointer(extra))
    x = Input(ctypes.c_ulong(0), ii_)
    ctypes.windll.user32.SendInput(1, ctypes.pointer(x), ctypes.sizeof(x))

    extra = ctypes.c_ulong(0)
    ii_ = Input_I()
    ii_.mi = MouseInput(0, 0, 0, 0x0004, 0, ctypes.pointer(extra))
    x = Input(ctypes.c_ulong(0), ii_)
    ctypes.windll.user32.SendInput(1, ctypes.pointer(x), ctypes.sizeof(x))

La fonction left_click () fonctionne mais click fonctionne avec tous les modules dont j'ai besoin, c'est set_pos () pour fonctionner mais malheureusement ce n'est pas le cas.


0 commentaires

3 Réponses :


1
votes

Pour les jeux Directx, vous devez le tester automatiquement, si l'entrée directe fonctionne.

Mais avec le package pywinauto, vous pouvez simuler des clics et des mouvements de souris.

Regardez pywinauto.mouse

Pour installer le package pywinauto pour python 27, vous pouvez utiliser ce fichier bat.

install-Pywinauto.bat

import pywinauto
pywinauto.mouse.double_click(button='left', coords=(0, 0))

Maintenant, vous sont prêts.

Clic-souris-gauche.py

import pywinauto
pywinauto.mouse.click(button='left', coords=(0, 0)) 

Double-Left-Mouse-Click.py

C:\Python27\scripts\pip.exe install pywinauto
pause


3 commentaires

Merci pour ton commentaire mais ça ne marche pas. C'est juste du travail sans jeu. Il ne peut pas cliquer sur une coordonnée donnée en jeu.


ok, pouvez-vous dire dans quel jeu cela ne fonctionne pas, et avez-vous essayé ensemble AutoPythonLauncher (il peut envoyer / exécuter sans focus le Windows). - note: si cela ne fonctionne toujours pas que le Game Maker n'a empêché d'utiliser les mouvements de coordonnées de la souris par des commandes, il est alors pris par le Game Self. (peut-être que vous pouvez essayer de faire des mouvements de macro étape par étape, Exemple: getmousePosition + then true envoyer une macro de raccourcis clavier Send 10xUp (key) + 10xLeft (key)


Et puis si le pointeur de la souris est arrivé sur cette coordonnée, vous pouvez peut-être essayer de faire un Simuler MouseClick avec un raccourci clavier Exemple: envoyer 1xEnter (clé)



2
votes

J'ai fait beaucoup de recherches et j'ai trouvé le module pyautoit. C'est vraiment génial et facile à utiliser. Je pense que cela ne fonctionne qu'avec python 32 bits, je ne pouvais pas l'installer en version 64 bits. Vous devriez également installer autoitx3 mais je ne suis pas sûr qu'il puisse fonctionner avec une seule DLL. Après avoir installé autoitx3 et le module pyautoit, vous pouvez utiliser cet exemple de code:

import autoit
import time

time.sleep(2)
#"left" stand for left click, 1243 and 1035 is x and y coordinates and 1 is number of clicks.
autoit.mouse_click("left", 1243, 1035, 1)


0 commentaires

1
votes
def move(x=None, y=None, duration=0.25, absolute=True, interpolate=False, **kwargs):

    if (interpolate):
        print("mouse move {}".format(interpolate))
        current_pixel_coordinates = win32api.GetCursorPos()
        if interpolate:
            current_pixel_coordinates = win32api.GetCursorPos()
            start_coordinates = _to_windows_coordinates(*current_pixel_coordinates)

            end_coordinates = _to_windows_coordinates(x, y)
            print("In interpolate")
            coordinates = _interpolate_mouse_movement(
                start_windows_coordinates=start_coordinates,
                end_windows_coordinates=end_coordinates
            )
            print(coordinates)
        else:
            coordinates = [end_coordinates]

        for x, y in coordinates:
            extra = ctypes.c_ulong(0)
            ii_ = Input_I()
            ii_.mi = MouseInput(x, y, 0, (0x0001 | 0x8000), 0, ctypes.pointer(extra))
            x = Input(ctypes.c_ulong(0), ii_)
            ctypes.windll.user32.SendInput(1, ctypes.pointer(x), ctypes.sizeof(x))

            time.sleep(duration / len(coordinates))
    else:
        x = int(x)
        y = int(y)

        coordinates = _interpolate_mouse_movement(
            start_windows_coordinates=(0, 0),
            end_windows_coordinates=(x, y)
        )

        for x, y in coordinates:
            extra = ctypes.c_ulong(0)
            ii_ = Input_I()
            ii_.mi = MouseInput(x, y, 0, 0x0001, 0, ctypes.pointer(extra))
            x = Input(ctypes.c_ulong(0), ii_)
            ctypes.windll.user32.SendInput(1, ctypes.pointer(x), ctypes.sizeof(x))

            time.sleep(duration / len(coordinates))


def _to_windows_coordinates(x=0, y=0):
    display_width = win32api.GetSystemMetrics(0)
    display_height = win32api.GetSystemMetrics(1)

    windows_x = (x * 65535) // display_width
    windows_y = (y * 65535) // display_height

    return windows_x, windows_y

def _interpolate_mouse_movement(start_windows_coordinates, end_windows_coordinates, steps=20):
    x_coordinates = [start_windows_coordinates[0], end_windows_coordinates[0]]
    y_coordinates = [start_windows_coordinates[1], end_windows_coordinates[1]]

    if x_coordinates[0] == x_coordinates[1]:
        x_coordinates[1] += 1

    if y_coordinates[0] == y_coordinates[1]:
        y_coordinates[1] += 1

    interpolation_func = scipy.interpolate.interp1d(x_coordinates, y_coordinates)

    intermediate_x_coordinates = np.linspace(start_windows_coordinates[0], end_windows_coordinates[0], steps + 1)[1:]
    coordinates = list(map(lambda x: (int(round(x)), int(interpolation_func(x))), intermediate_x_coordinates))
Attach this code to yours and call it using move(x,y).
This is the link to the full code https://github.com/SerpentAI/SerpentAI/blob/dev/serpent/input_controllers/native_win32_input_controller.py 
Also it might help to run python with Administrative privileges 

1 commentaires

renvoie les coordonnées dans _interpolate_mouse_movement