fix: resolve mouse simulation issue due to resolution change on screen off (#1230)

* fix: resolve mouse simulation issue due to resolution change on screen off

* fix: typo
This commit is contained in:
秋云
2025-03-05 00:30:35 +08:00
committed by GitHub
parent aead279c78
commit 4e44bb0e78
3 changed files with 49 additions and 27 deletions

View File

@@ -476,11 +476,13 @@ public class TpTask(CancellationToken ct)
/// <param name="y2">鼠标移动后位置y</param>
public async Task MouseClickAndMove(int x1, int y1, int x2, int y2)
{
GlobalMethod.MoveMouseTo(x1, y1);
// GlobalMethod.MoveMouseTo(x1, y1);
GameCaptureRegion.GameRegionMove((rect, scale) => (x1 * scale, y1 * scale));
await Delay(50, ct);
GlobalMethod.LeftButtonDown();
await Delay(50, ct);
GlobalMethod.MoveMouseTo(x2, y2);
// GlobalMethod.MoveMouseTo(x2, y2);
GameCaptureRegion.GameRegionMove((rect, scale) => (x2 * scale, y2 * scale));
await Delay(50, ct);
GlobalMethod.LeftButtonUp();
await Delay(50, ct);
@@ -541,31 +543,9 @@ public class TpTask(CancellationToken ct)
private async Task MouseMoveMap(int pixelDeltaX, int pixelDeltaY, int steps = 10)
{
// 确保不影响总移动距离
int totalX = 0;
int totalY = 0;
// 梯形缩放因子
double scaleFactor = 0.75;
// 计算每一步的位移从steps/2逐渐减小到0
int[] stepX = new int[steps];
int[] stepY = new int[steps];
for (int i = 0; i < steps; i++)
{
double factor = ((double)(steps - Math.Max(i, steps / 2)) / (steps / 2)) / scaleFactor;
stepX[i] = (int)(pixelDeltaX * factor / steps);
stepY[i] = (int)(pixelDeltaY * factor / steps);
totalX += stepX[i];
totalY += stepY[i];
}
// 均匀分配多余的部分到前半段
int remainingX = (pixelDeltaX - totalX);
int remainingY = (pixelDeltaY - totalY);
for (int i = 0; i < steps / 2 + 1; i++)
{
stepX[i] += remainingX / (steps / 2 + 1) + ((remainingX % (steps / 2 + 1) > i) ? 0 : 1);
stepY[i] += remainingY / (steps / 2 + 1) + ((remainingX % (steps / 2 + 1) > i) ? 0 : 1);
}
int[] stepX = GenerateSteps(pixelDeltaX, steps);
int[] stepY = GenerateSteps(pixelDeltaY, steps);
// 随机起点以避免地图移动无效
GameCaptureRegion.GameRegionMove((rect, _) =>
@@ -575,13 +555,42 @@ public class TpTask(CancellationToken ct)
Simulation.SendInput.Mouse.LeftButtonDown();
for (var i = 0; i < steps; i++)
{
Simulation.SendInput.Mouse.MoveMouseBy(stepX[i], stepY[i]);
var i1 = i;
await Delay(_tpConfig.StepIntervalMilliseconds, ct);
// Simulation.SendInput.Mouse.MoveMouseBy(stepX[i], stepY[i]);
GameCaptureRegion.GameRegionMoveBy((_, scale) => (stepX[i1] * scale, stepY[i1] * scale));
}
Simulation.SendInput.Mouse.LeftButtonUp();
}
private int[] GenerateSteps(int delta, int steps) {
double[] factors = new double[steps];
double sum = 0;
for (int i = 0; i < steps; i++) {
factors[i] = Math.Cos(i * Math.PI / (2 * steps));
sum += factors[i];
}
int[] stepsArr = new int[steps];
int remaining = delta;
// 两阶段分配:基础值 + 余数补偿
for (int i = 0; i < steps; i++) {
double ratio = factors[i] / sum;
stepsArr[i] = (int)(delta * ratio); // 基础值
remaining -= stepsArr[i];
}
int center = steps / 2;
for (int r = 0; r < Math.Abs(remaining); r++) {
int target = (center + r) % steps; // 从中点开始螺旋分配
stepsArr[target] += remaining > 0 ? 1 : -1;
}
return stepsArr;
}
public Point2f GetPositionFromBigMap()
{
return GetBigMapCenterPoint();

View File

@@ -61,6 +61,11 @@ public class DesktopRegion : Region
Simulation.SendInput.Mouse.MoveMouseTo(cx * 65535 * 1d / PrimaryScreen.WorkingArea.Width,
cy * 65535 * 1d / PrimaryScreen.WorkingArea.Height);
}
public static void DesktopRegionMoveBy(double dx, double dy)
{
Simulation.SendInput.Mouse.MoveMouseBy((int)dx, (int)dy);
}
public GameCaptureRegion Derive(Bitmap captureBitmap, int x, int y)
{

View File

@@ -102,6 +102,14 @@ public class GameCaptureRegion(Bitmap bitmap, int initX, int initY, Region? owne
DesktopRegion.DesktopRegionMove(captureAreaRect.X + cx, captureAreaRect.Y + cy);
}
public static void GameRegionMoveBy(Func<Size, double, (double, double)> deltaFunc)
{
var captureAreaRect = TaskContext.Instance().SystemInfo.CaptureAreaRect;
var assetScale = TaskContext.Instance().SystemInfo.ScaleTo1080PRatio;
var (dx, dy) = deltaFunc(new Size(captureAreaRect.Width, captureAreaRect.Height), assetScale);
DesktopRegion.DesktopRegionMoveBy(dx, dy);
}
/// <summary>
/// 静态方法,输入1080P下的坐标,方法会自动转换到当前游戏捕获区域大小下的坐标并点击
/// </summary>