// 获取脚本配置
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方法,优化代码
回答
文档地址 https://docs.hamibot.com/
你的脚本存在几个关键问题,主要涉及 API 兼容性、方法调用错误和逻辑顺序。以下是详细分析与优化建议:
❌ 问题一:images.clip 方法不存在
Hamibot 的 images 模块 没有 clip() 方法,正确的方法是 images.clip(image, x, y, width, height) 实际上并 不存在于当前 Hamibot 环境中。
✅ 正确做法是使用 images.copy() 配合 Rect 截取区域,但更推荐使用 images.findMultiColors 或 images.readPixel 结合控件查找进行图像处理。如果你只是想裁剪截图,应使用 Android 原生方式或通过 canvas 操作(不推荐)。
但最实际的方案是:避免依赖底层图像裁剪,改用 Hamibot 提供的图像匹配功能(如 findImage, matchTemplate)配合坐标区域判断。
❌ 问题二:swipe() 方法未定义
你直接调用了 swipe(...),但在 Hamibot 中,swipe 不是全局函数,你需要使用:
device.swipe(x1, y1, x2, y2, duration);
或者启用 auto 模式后使用 gesture 相关 API。
❌ 问题三:截屏权限弹窗出现两次
这是因为你在脚本中 多次调用了 captureScreen(),并且每次调用都会触发一次权限请求(如果尚未持久授权)。虽然 Hamibot 应该记住授权状态,但如果在短时间内重复请求或设备未正确授予“始终允许”,就会反复弹出。
解决办法:
- 只调用一次
requestScreenCapture(),并在用户允许后不再重复请求。 - 确保你在设置中将 Hamibot 的录屏权限设为“始终允许”。
- 不要频繁调用
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();
🛠️ 建议与最佳实践
-
不要依赖
images.clip
Hamibot 当前版本不支持此方法。若需图像识别,请使用findImage,matchTemplate, 或结合ocr功能。 -
使用
device.swipe()替代swipe()
所有触摸操作应通过device对象完成,如:device.touchDown(0, x, y); device.touchMove(0, x2, y2); device.touchUp(0, x2, y2);