mirror of
https://github.com/MaaAssistantArknights/MaaAssistantArknights.git
synced 2026-07-16 17:57:01 +08:00
* feat(controller): 集成 MaaWin32ControlUnit 支持 Win32 窗口截图与控制 - 提取公共滑动插值逻辑到 SwipeHelper.hpp,重构 Minitouch/PlayTools 控制器 - 新增 Win32ControlUnitLoader 动态加载 MaaWin32ControlUnit.dll - 新增 Win32Controller 实现 ControllerAPI,适配 touch_down/move/up 接口 - 添加 AsstAsyncAttachWindow 公开 API 用于绑定 Win32 窗口 - 添加 Win32 截图/输入方式的类型定义和枚举常量 * feat(api): 增加同步版本的 AsstAttachWindow 接口 模仿 AsstConnect 实现同步绑定 Win32 窗口的接口,方便简单场景下直接调用。 该接口标记为 deprecated,建议使用异步版本 AsstAsyncAttachWindow。 * fix: can build MaaCore * feat: 完成整体适配 * feat(ci): 添加 MaaFramework Win32ControlUnit 下载步骤 使用 robinraju/release-downloader 从 MaaFramework 最新 release 下载 win-x64 版本并提取 MaaWin32ControlUnit 到构建产物中 * docs: 添加 Win32Controller 调试所需 MaaWin32ControlUnit 的说明 在开发文档的环境配置步骤中说明调试 Win32Controller 需要手动下载 MaaWin32ControlUnit.dll,并欢迎社区贡献自动下载脚本 * fix(i18n): 修改 UseAttachWindowWarning 措辞为"仅供尝鲜" * fix: 小细节修复 * ci: fix maafw filename * feat: PC 移至连接配置 * feat: 调整描述 * chore: 调整 PC 在连接配置中的顺序 * feat: 设置指引和开始唤醒界面 PC 选项绑定 --------- Co-authored-by: uye <99072975+ABA2396@users.noreply.github.com>
138 lines
3.7 KiB
C++
138 lines
3.7 KiB
C++
#pragma once
|
||
|
||
#include <cmath>
|
||
#include <functional>
|
||
|
||
#include "Common/AsstTypes.h"
|
||
|
||
namespace asst
|
||
{
|
||
|
||
// 三次样条插值函数,用于生成平滑的滑动曲线
|
||
// slope_0: 起点斜率,slope_1: 终点斜率,t: 插值进度 [0, 1]
|
||
inline double cubic_spline(double slope_0, double slope_1, double t)
|
||
{
|
||
const double a = slope_0;
|
||
const double b = -(2 * slope_0 + slope_1 - 3);
|
||
const double c = -(-slope_0 - slope_1 + 2);
|
||
return a * t + b * std::pow(t, 2) + c * std::pow(t, 3);
|
||
}
|
||
|
||
// 滑动插值执行器
|
||
// MoveFunc: bool(int x, int y) - 移动到指定位置的回调,返回 false 表示失败
|
||
// BoundsCheckFunc: bool(int x, int y) - 边界检查回调,返回 true 表示在边界内
|
||
template <typename MoveFunc, typename BoundsCheckFunc>
|
||
bool interpolate_swipe(
|
||
int x1,
|
||
int y1,
|
||
int x2,
|
||
int y2,
|
||
int duration,
|
||
int interval,
|
||
double slope_in,
|
||
double slope_out,
|
||
MoveFunc&& move_func,
|
||
BoundsCheckFunc&& bounds_check)
|
||
{
|
||
for (int cur_time = interval; cur_time < duration; cur_time += interval) {
|
||
double progress = cubic_spline(slope_in, slope_out, static_cast<double>(cur_time) / duration);
|
||
int cur_x = static_cast<int>(std::lerp(static_cast<double>(x1), static_cast<double>(x2), progress));
|
||
int cur_y = static_cast<int>(std::lerp(static_cast<double>(y1), static_cast<double>(y2), progress));
|
||
|
||
if (!bounds_check(cur_x, cur_y)) {
|
||
continue;
|
||
}
|
||
|
||
if (!move_func(cur_x, cur_y)) {
|
||
return false;
|
||
}
|
||
}
|
||
|
||
// 确保到达终点(如果在边界内)
|
||
if (bounds_check(x2, y2)) {
|
||
if (!move_func(x2, y2)) {
|
||
return false;
|
||
}
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
// 简化版本:不需要边界检查
|
||
template <typename MoveFunc>
|
||
bool interpolate_swipe(
|
||
int x1,
|
||
int y1,
|
||
int x2,
|
||
int y2,
|
||
int duration,
|
||
int interval,
|
||
double slope_in,
|
||
double slope_out,
|
||
MoveFunc&& move_func)
|
||
{
|
||
return interpolate_swipe(
|
||
x1,
|
||
y1,
|
||
x2,
|
||
y2,
|
||
duration,
|
||
interval,
|
||
slope_in,
|
||
slope_out,
|
||
std::forward<MoveFunc>(move_func),
|
||
[](int, int) { return true; });
|
||
}
|
||
|
||
// 带暂停检测的滑动插值执行器(用于 MinitouchController 的 swipe_with_pause 功能)
|
||
// PauseCheckFunc: bool(int cur_x, int cur_y, int start_x, int start_y) - 检查是否需要暂停
|
||
// PauseFunc: void() - 执行暂停操作
|
||
template <typename MoveFunc, typename BoundsCheckFunc, typename PauseCheckFunc, typename PauseFunc>
|
||
bool interpolate_swipe_with_pause(
|
||
int x1,
|
||
int y1,
|
||
int x2,
|
||
int y2,
|
||
int duration,
|
||
int interval,
|
||
double slope_in,
|
||
double slope_out,
|
||
MoveFunc&& move_func,
|
||
BoundsCheckFunc&& bounds_check,
|
||
PauseCheckFunc&& pause_check,
|
||
PauseFunc&& pause_func)
|
||
{
|
||
bool pause_triggered = false;
|
||
|
||
for (int cur_time = interval; cur_time < duration; cur_time += interval) {
|
||
double progress = cubic_spline(slope_in, slope_out, static_cast<double>(cur_time) / duration);
|
||
int cur_x = static_cast<int>(std::lerp(static_cast<double>(x1), static_cast<double>(x2), progress));
|
||
int cur_y = static_cast<int>(std::lerp(static_cast<double>(y1), static_cast<double>(y2), progress));
|
||
|
||
// 检查是否需要触发暂停
|
||
if (!pause_triggered && pause_check(cur_x, cur_y, x1, y1)) {
|
||
pause_triggered = true;
|
||
pause_func();
|
||
}
|
||
|
||
if (!bounds_check(cur_x, cur_y)) {
|
||
continue;
|
||
}
|
||
|
||
if (!move_func(cur_x, cur_y)) {
|
||
return false;
|
||
}
|
||
}
|
||
|
||
// 确保到达终点(如果在边界内)
|
||
if (bounds_check(x2, y2)) {
|
||
if (!move_func(x2, y2)) {
|
||
return false;
|
||
}
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
} // namespace asst
|