无法弄清楚,为什么 Jython 上的脚本与 Pascal 上的脚本工作方式不同

Can't figure out, why script on Jython working differently from script on Pascal

长话短说:我正在使用 SikuliX 编写脚本,它应该像人类一样移动鼠标并进行点击(实际上是机器人)。 SikuliX 使用 Jython 2.7 作为 scritps 的语言。 我为我的目的找到了很好的库(像人一样移动鼠标):mouse.simba 用类似 Pascal 的语言编写,并在 jython 中重写函数 _humanWindMouse()。它有效,但不像我预期的那样。

测试 运行 我的脚本,绘制矩形:

https://prtscr.cx.ua/storage/5b/5b2203.jpg

使用相同坐标的原始函数的结果:

https://prtscr.cx.ua/storage/bb/bb3ff5.jpg

抱歉链接,我还不能 post 图片(

我的代码:

import random
import time
import math
from time import sleep
from math import sqrt
from math import ceil
from math import hypot

from java.awt import Robot

def distance(x1, y1, x2, y2):
    return math.hypot(x2 - x1, y2 - y1)

def myrandom(x):
    return random.randint(0, x-1)

def myround(x):
    return int(round(x))

# function MMouseMove (MyMouseMove) for moving mouse using only coord
def MMouseMove(x,y):
    robot = Robot()
    robot.mouseMove(x,y)

# function HumanWindMouse by BenLand100 & Flight, python implementation
def humanWindMouse(xs, ys, xe, ye, gravity, wind):
    veloX = veloY = windX=windY=veloMag=dist=randomDist=lastDist=D=0
    lastX=lastY=MSP=W=TDist=0

    mouseSpeed = 20
    MSP = mouseSpeed
    sqrt2 = sqrt(2)
    sqrt3 = sqrt(3)
    sqrt5 = sqrt(5)

    TDist = distance(myround(xs), myround(ys), myround(xe), myround(ye))
    t = time.time() + 10000
    while True:
        if time.time() > t:
            break

        dist = hypot(xs - xe, ys - ye)
        wind = min(wind, dist)
        if dist < 1:
            dist = 1

        D = (myround((myround(TDist)*0.3))/7)
        if D > 25:
            D = 25
        if D < 5:
            D = 5

        rCnc = myrandom(6)
        if rCnc == 1:
            D = random.randint(2,3)

        if D <= myround(dist):
            maxStep = D
        else:
            maxStep = myround(dist)

        windX= windX / sqrt2
        windY= windY / sqrt2

        veloX= veloX + windX
        veloY= veloY + windY
        veloX= veloX + gravity * (xe - xs) / dist
        veloY= veloY + gravity * (ye - ys) / dist

        if hypot(veloX, veloY) > maxStep:
            temp = int(myround(maxStep) // 2)
            if temp == 0:
                temp = 1
            randomDist= maxStep / 2.0 + myrandom(temp)
            veloMag= sqrt(veloX * veloX + veloY * veloY)
            veloX= (veloX / veloMag) * randomDist
            veloY= (veloY / veloMag) * randomDist

        lastX= myround(xs)
        lastY= myround(ys)
        xs= xs + veloX
        ys= ys + veloY

        if lastX <> myround(xs) or lastY <> myround(ys):
            MMouseMove(myround(xs), myround(ys))

        W = (myrandom((myround(100/MSP)))*6)
        if W < 5:
            W = 5
        W = myround(W*0.9)
        sleep(W/1000.0)
        lastdist= dist

        if hypot(xs - xe, ys - ye) < 1:
            break

    if myround(xe) <> myround(xs) or myround(ye) <> myround(ys):
        MMouseMove(myround(xe), myround(ye)) 
    mouseSpeed = MSP    
    return;

def MMouse(x,y):
    mouseSpeed = 20
    randSpeed = (myrandom(mouseSpeed) / 2.0 + mouseSpeed) / 10.0
    curPos = Mouse.at()
    x1 = curPos.x
    y1 = curPos.y
    humanWindMouse(x1, y1, x, y, 5, 10.0/randSpeed)
    return;

我是这样用的:

MMouseMove(227, 146)

mouseDown(Button.LEFT)
MMouse(396, 146)
MMouse(396, 252)
MMouse(227, 252)
MMouse(227, 146)
mouseUp(Button.LEFT)

exit()

mouseDown()mouseUp() 是 SikuliX 中的内置函数
而且我没有使用内置的 mouseMove(),因为它从 A 到 B 太慢了。

如有任何帮助,我们将不胜感激

经过几个小时的调试,我发现了问题:在源代码中,由于未知原因,作者在调用函数 _humanWindMouse() 时将名为 MOUSE_HUMAN 的常量传递给名为 gravity 的变量,这在我看来是个错误。这就是为什么我决定在我的代码中解决这个问题,并删除函数的一个参数和几行代码(这是错误的举动)。重新添加所需代码后,我的功能如我所料正常工作。

所以,这是工作代码:

# function HumanWindMouse by BenLand100 & Flight, 
# python implementation by Nokse
def humanWindMouse(xs, ys, xe, ye, gravity, wind, targetArea):
    veloX = veloY = windX=windY=veloMag=dist=randomDist=lastDist=D=0
    lastX=lastY=MSP=W=TDist=0

    mouseSpeed = 20
    MSP = mouseSpeed
    sqrt2 = sqrt(2)
    sqrt3 = sqrt(3)
    sqrt5 = sqrt(5)

    TDist = distance(myround(xs), myround(ys), myround(xe), myround(ye))
    t = time.time() + 10000
    while True:
        if time.time() > t:
            break

        dist = hypot(xs - xe, ys - ye)
        wind = min(wind, dist)
        if dist < 1:
            dist = 1

        D = (myround((myround(TDist)*0.3))/7)
        if D > 25:
            D = 25
        if D < 5:
            D = 5

        rCnc = myrandom(6)
        if rCnc == 1:
            D = random.randint(2,3)

        if D <= myround(dist):
            maxStep = D
        else:
            maxStep = myround(dist)

        if dist >= targetArea:
            windX = windX / sqrt3 + (myrandom(myround(wind) * 2 + 1) - wind) / sqrt5
            windY = windY / sqrt3 + (myrandom(myround(wind) * 2 + 1) - wind) / sqrt5
        else:
            windX = windX / sqrt2
            windY = windY / sqrt2

        veloX = veloX + windX
        veloY = veloY + windY
        veloX = veloX + gravity * (xe - xs) / dist
        veloY = veloY + gravity * (ye - ys) / dist

        if hypot(veloX, veloY) > maxStep:
            halfSteps = int(myround(maxStep) // 2)
            if halfSteps == 0:
                halfSteps = 1
            randomDist = maxStep / 2.0 + myrandom(halfSteps)
            veloMag = sqrt(veloX * veloX + veloY * veloY)
            veloX = (veloX / veloMag) * randomDist
            veloY = (veloY / veloMag) * randomDist

        lastX = myround(xs)
        lastY = myround(ys)
        xs = xs + veloX
        ys = ys + veloY

        if lastX <> myround(xs) or lastY <> myround(ys):
            MMouseMove(myround(xs), myround(ys))

        W = (myrandom((myround(100/MSP)))*6)
        if W < 5:
            W = 5
        W = myround(W*0.9)
        sleep(W/1000.0)
        lastdist = dist
        #condition for exiting while loop
        if hypot(xs - xe, ys - ye) < 1:
            break

    if myround(xe) <> myround(xs) or myround(ye) <> myround(ys):
        MMouseMove(myround(xe), myround(ye)) 
    mouseSpeed = MSP    
    return; 

我用不同的参数测试了一下,选择了这个:

humanWindMouse(xs, ys, x, y, 9, 10.0/randSpeed, 10.0*randSpeed)

但我建议先玩玩参数,了解它们如何影响鼠标的行为。

如何计算randSpeed,应该导入什么,还有子函数,比如myround(),可以在我的第一个post找到。 希望这段代码有一天能对某人有所帮助)