// 获取脚本配置
const env = hamibot.env;

let xiaotiNum = parseInt(env.xiaotinum) || 0;
let datiNum = parseInt(env.datinum) || 0;
let dayetype = env.dayetype;

auto.waitFor();

//setScreenMetrics(1260, 2800);

if (!requestScreenCapture()) {
hamibot.exit(); // 没获得授权,退出
}
captureScreen();
sleep(1000); // 可选,短暂延迟,避免截图包含确认框

function captureAndSave(img_cap, regionKey) {
log("保存图片:", regionKey);
let img_clip;
try {
const region = global_region[regionKey];
if (!region)
throw new Error(Region key "${regionKey}" not found in global_region);

img_clip = images.clip(
  img_cap,
  region.x,
  region.y,
  region.width,
  region.height
);
const filePath = files.join(root_path, `${regionKey}.png`);
images.save(img_clip, filePath);
confirmViewFile(filePath);

} catch (e) {
toastLog("Error capturing or saving image: " + e.message);
} finally {
if (img_clip) img_clip.recycle();
}
}

// 采集素材
function collect_img() {
let img_cap = captureScreen();
sleep(1000);

// 滑动测试
swipe(
global_region["最大等级"].x,
global_region["最大等级"].y + global_region["最大等级"].height / 2,
global_region["最大等级"].x + global_region["最大等级"].width,
global_region["最大等级"].y + global_region["最大等级"].height / 2,
200
);

toastLog("模板采集完毕");
}

function swipeMaxLevel() {
sleep(500);
toastLog("开始滑动最大等级");
swipe(
global_region["最大等级"].x,
global_region["最大等级"].y + global_region["最大等级"].height / 2,
global_region["最大等级"].x + global_region["最大等级"].width,
global_region["最大等级"].y + global_region["最大等级"].height / 2,
200
);
sleep(1000);
}

我这个脚本有啥问题?为什么截屏权限弹窗弹出两次,为什么报错没有clip方法,为什么没有swipe方法,优化代码

已存档
HAMI_4990598444 · 20 天前

回答

Hamibot AI
1
· 20 天前

文档地址 https://docs.hamibot.com/

你的脚本存在几个关键问题,主要涉及 API 兼容性、方法调用错误和逻辑顺序。以下是详细分析与优化建议:


❌ 问题一:images.clip 方法不存在

Hamibot 的 images 模块 没有 clip() 方法,正确的方法是 images.clip(image, x, y, width, height) 实际上并 不存在于当前 Hamibot 环境中

✅ 正确做法是使用 images.copy() 配合 Rect 截取区域,但更推荐使用 images.findMultiColorsimages.readPixel 结合控件查找进行图像处理。如果你只是想裁剪截图,应使用 Android 原生方式或通过 canvas 操作(不推荐)。

但最实际的方案是:避免依赖底层图像裁剪,改用 Hamibot 提供的图像匹配功能(如 findImage, matchTemplate)配合坐标区域判断。


❌ 问题二:swipe() 方法未定义

你直接调用了 swipe(...),但在 Hamibot 中,swipe 不是全局函数,你需要使用:

device.swipe(x1, y1, x2, y2, duration);

或者启用 auto 模式后使用 gesture 相关 API。


❌ 问题三:截屏权限弹窗出现两次

这是因为你在脚本中 多次调用了 captureScreen(),并且每次调用都会触发一次权限请求(如果尚未持久授权)。虽然 Hamibot 应该记住授权状态,但如果在短时间内重复请求或设备未正确授予“始终允许”,就会反复弹出。

解决办法:

  1. 只调用一次 requestScreenCapture(),并在用户允许后不再重复请求。
  2. 确保你在设置中将 Hamibot 的录屏权限设为“始终允许”。
  3. 不要频繁调用 captureScreen(),它代价高且容易触发系统提示。

✅ 优化后的代码示例

// 文档地址 https://docs.hamibot.com/

// 获取脚本配置
const env = hamibot.env;

let xiaotiNum = parseInt(env.xiaotinum) || 0;
let datiNum = parseInt(env.datinum) || 0;
let dayetype = env.dayetype;

// 等待 accessibility service 启动
auto.waitFor();

// 请求截屏权限(只调用一次)
if (!requestScreenCapture()) {
    toastLog('❌ 未获得截屏权限,脚本退出');
    hamibot.exit();
}

// 定义屏幕尺寸(请根据实际分辨率调整)
// setScreenMetrics(1260, 2800); // 已废弃,请勿使用

// 模拟滑动:从最大等级区域左侧滑到右侧
function swipeMaxLevel() {
    let region = global_region["最大等级"];
    if (!region) {
        toastLog("⚠️ 区域 '最大等级' 未定义");
        return;
    }

    let x1 = region.x + 10;
    let y1 = region.y + region.height / 2;
    let x2 = region.x + region.width - 10;
    let y2 = region.y + region.height / 2;

    device.swipe(x1, y1, x2, y2, 200); // 使用 device.swipe
    sleep(1000);
}

// 示例:采集当前屏幕并尝试做点事(仅演示)
function collect_img() {
    let img = captureScreen();
    if (!img) {
        toastLog("📷 截图失败");
        return;
    }
    sleep(500);

    // 这里可以加入模板匹配逻辑,例如:
    // let point = images.findImage(img, templateImg);

    swipeMaxLevel();
    toastLog("✅ 模板采集完成");
}

// 主执行流程
collect_img();

🛠️ 建议与最佳实践

  1. 不要依赖 images.clip
    Hamibot 当前版本不支持此方法。若需图像识别,请使用 findImage, matchTemplate, 或结合 ocr 功能。

  2. 使用 device.swipe() 替代 swipe()
    所有触摸操作应通过 device 对象完成,如:

    device.touchDown(0, x, y);
    device.touchMove(0, x2, y2);
    device.touchUp(0, x2, y2);
    
ℹ️ 本回答由 AI 生成,内容仅供参考