我要用触摸操控新建一个逆战未来塔防模式下用上帝视角安放陷阱的脚本,对于每次缩放的角度和方向我该怎么统一,才能确保每局放置陷阱的位置是统一的

HAMI_3834018734 · 13 小时前
第 1 条补充
·
13 小时前

我编辑脚本的时候每次坐标点击的位置我都要录入吗?塔防模式的地图是有9关,第9关是boss 关卡,每关对应的陷阱位置可能有所不同,根据金钱数进行陷阱的放置,出怪口位置不同可能就需要移动视角到对应的出怪口安置陷阱,上帝视角是有一个按钮的,每次按下都会恢复初始状态,每次安放陷阱就需要对应的进行模拟双指缩放,然后再平移到对应的位置安放陷阱,我了解到没有脚本录制功能,对于陷阱的对应坐标位置不少,我需要一个 个录入,还有每个关卡结束,新的关卡开始,我是不是要加入识图,还是固定的时间去点击,每关可能对于重要的陷阱还要去进行补放,防止陷阱没了没有发现
现在不知道从什么方向下手,没有一个好的思路,还要加入延迟,模拟真人点击,不能直接移过去


回答

Hamibot AI
1
· 13 小时前

确保每局放置陷阱位置统一,核心在于坐标归一化相对定位。游戏界面通常存在动态变化,直接写死坐标极易失效。以下是实现稳定性的关键方案:

1. 分辨率自动缩放(核心)

不同手机屏幕分辨率不同,必须使用 setScreenMetrics() 将脚本的坐标系固定在设计时的分辨率。这样无论实际设备是什么,脚本计算的坐标都会自动按比例放缩。

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

// 设置设计分辨率,例如 1080x1920
setScreenMetrics(1080, 1920);

2. 以屏幕中心为锚点

不要依赖绝对坐标(如 Tap(500, 500)),而是以屏幕中心或某个固定 UI 元素为基准,计算偏移量。

  • 获取当前屏幕尺寸:使用 device.widthdevice.height
  • 计算中心点centerX = width / 2, centerY = height / 2
  • 计算目标点targetX = centerX + offsetX, targetY = centerY + offsetY

3. 统一视角与缩放

上帝视角下,每次开局相机位置可能不同。建议优先寻找游戏内的“重置视角”按钮。如果没有,需通过手势模拟缩放,但需注意手势的稳定性。

  • 重置视角:点击界面上的“复位”或“小地图居中”图标。
  • 手势缩放:如果必须手动缩放,使用 swipe 模拟双指操作。Hamibot 支持多点触控指令,但建议先尝试单指滑动调整。
  • 等待加载:每次操作前增加延时,确保地图渲染完成。

4. 稳定性保障

  • 异步非阻塞:触摸操作是异步的,必须在动作后加 sleep()
  • 异常处理:检测关键 UI 是否存在,不存在则重试或退出。

代码示例

以下是一个基于相对定位的放置陷阱逻辑框架:

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

function main() {
    // 1. 设置分辨率基准
    setScreenMetrics(1080, 1920);

    // 2. 定义陷阱相对于屏幕中心的偏移量
    var offsetX = 200; 
    var offsetY = -300; 

    // 3. 循环执行多局
    for (var i = 0; i < 5; i++) {
        log("开始第 " + (i + 1) + " 局");

        // 4. 等待游戏进入可操作状态
        waitForReady();

        // 5. 重置视角(如果有该按钮)
        if (text("重置视角").exists()) {
            text("重置视角").findOne().click();
            sleep(2000);
        } else {
            // 如果没有按钮,尝试点击屏幕中心强制刷新视角
            click(device.width / 2, device.height / 2);
            sleep(1000);
        }

        // 6. 计算目标坐标
        var centerX = device.width / 2;
        var centerY = device.height / 2;
        var targetX = centerX + offsetX;
        var targetY = centerY + offsetY;

        // 7. 点击放置陷阱
        click(targetX, targetY);
        toast("已放置陷阱:" + targetX + "," + targetY);

        // 8. 等待结算或下一轮
        sleep(5000);
    }
}

function waitForReady() {
    // 等待特定文字出现表示就绪,例如“准备开始”
    var startTime = new Date().getTime();
    while (true) {
        if (text("准备开始").exists()) {
            return true;
        }
        if (new Date().getTime() - startTime > 30000) {
            return false;
        }
        sleep(500);
    }
}

main();

注意事项

  1. 兼容性:Rhino 引擎不支持箭头函数和默认参数,请检查代码语法。
  2. 权限:确保无障碍服务和悬浮窗权限已开启。
  3. 风险:自动化操作可能违反游戏服务条款,请自行承担风险。
  4. 调试:首次运行建议开启控制台日志,观察坐标是否随分辨率变化而正确缩放。

详细的技术文档和 API 接口说明,请访问:https://docs.hamibot.com/

ℹ️ 内容由 AI 生成,可能不准确,请注意核实
Hamibot AI
1
· 13 小时前

这是一个非常典型的复杂自动化场景。由于 Hamibot 没有内置的脚本录制功能,你需要手动规划逻辑并校准坐标。针对你的需求(多关卡、视角重置、缩放平移、补放陷阱),建议采用模块化设计相对定位策略。

以下是具体的实施思路和代码框架:

1. 核心思路规划

  1. 分辨率标准化:必须使用 setScreenMetrics 锁定基准分辨率,否则不同手机上的坐标会失效。
  2. 数据驱动:将每一关的陷阱位置存储为数组对象,而不是硬编码在逻辑里。这样修改关卡配置只需改数据。
  3. 状态检测:不要依赖固定时间判断关卡结束,建议使用 OCR 识别文字或图像匹配来确认“下一关开始”或“结算完成”。
  4. 模拟真人:点击和滑动需要加入随机延迟,避免被系统判定为机器行为。
  5. 视觉反馈:利用控制台日志实时查看脚本运行到了哪一步,方便调试。

2. 关键技术点实现

A. 坐标校准与归一化

不要直接写死 click(500, 500)。先获取当前屏幕尺寸,计算相对比例。

// 设置设计时的分辨率,例如 1080x1920
setScreenMetrics(1080, 1920);

在编辑器中开启「设备调试」,点击界面上的按钮,查看其坐标。记录时尽量以屏幕中心或某个固定 UI 元素(如“上帝视角”按钮)为参照物。

B. 关卡切换检测

推荐使用 OCR 识别结算界面的关键词(如“胜利”、“失败”、“下一关”)。

// 等待特定文字出现表示关卡结束
function waitForLevelEnd(keyword) {
    var startTime = new Date().getTime();
    while (true) {
        // 截取屏幕并识别文字
        var text = ocrText(); 
        if (text.indexOf(keyword) > -1) {
            return true;
        }
        if (new Date().getTime() - startTime > 30000) {
            log("未检测到关卡结束标志");
            return false;
        }
        sleep(1000);
    }
}

C. 视角控制与缩放

上帝视角按钮用于复位。双指缩放和平移需要使用 swipe 指令。为了模拟真人,滑动路径应包含随机性。

// 模拟双指缩放
function simulateZoom(startX, startY, endX, endY, duration) {
    // 这里需要根据实际游戏手势调整,通常是两点同时移动
    // 示例:单指滑动模拟部分操作,具体需结合游戏手势
    swipe(startX, startY, endX, endY, duration);
}

D. 陷阱补放检测

放置前检查该位置是否已有陷阱图标。如果没有,则执行放置;如果有,跳过。

3. 脚本代码框架

以下是一个兼容 Rhino 引擎的基础框架,你可以在此基础上填充具体坐标和数据。

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

// 全局配置
var CONFIG = {
    screenWidth: 1080,
    screenHeight: 1920,
    godViewBtnText: "上帝视角", // 假设按钮文字
    levelEndKeyword: "胜利",     // 关卡结束识别词
    trapMenuBtnText: "陷阱"      // 打开陷阱菜单的按钮
};

// 陷阱数据配置 (示例:每关一个数组,每个对象代表一个陷阱位置)
// x, y 为相对于屏幕中心的偏移量,或者绝对坐标
var LEVEL_TRAPS = [
    {
        level: 1,
        traps: [
            { offsetX: 100, offsetY: -200 },
            { offsetX: -100, offsetY: 200 }
        ]
    },
    {
        level: 9,
        traps: [
            { offsetX: 0, offsetY: -500 } // Boss 关特殊位置
        ]
    }
];

// 主函数
function main() {
    setScreenMetrics(CONFIG.screenWidth, CONFIG.screenHeight);
    
    var currentLevel = 1;
    var maxLevels = 9;

    while (currentLevel <= maxLevels) {
        log("准备进入第 " + currentLevel + " 关");
        
        // 1. 重置视角
        resetView();
        sleep(2000);

        // 2. 打开陷阱菜单
        openTrapMenu();
        sleep(1500);

        // 3. 遍历本关所有陷阱位置
        var traps = getTrapsForLevel(currentLevel);
        for (var i = 0; i < traps.length; i++) {
            var trap = traps[i];
            placeTrapAtPosition(trap.offsetX, trap.offsetY);
            sleep(randomDelay(1000, 2000)); // 模拟思考时间
        }

        // 4. 关闭菜单
        closeTrapMenu();
        sleep(1000);

        // 5. 等待关卡结束
        if (!waitForLevelEnd(CONFIG.levelEndKeyword)) {
            log("未能检测到关卡结束,可能超时");
            break;
        }

        // 6. 进入下一关
        nextLevel();
        currentLevel++;
    }
    
    toast("全部关卡完成");
}

// 辅助函数:重置视角
function resetView() {
    if (text(CONFIG.godViewBtnText).exists()) {
        text(CONFIG.godViewBtnText).findOne().click();
    } else {
        log("未找到上帝视角按钮");
    }
}

// 辅助函数:获取当前关卡陷阱数据
function getTrapsForLevel(level) {
    for (var i = 0; i < LEVEL_TRAPS.length; i++) {
        if (LEVEL_TRAPS[i].level === level) {
            return LEVEL_TRAPS[i].traps;
        }
    }
    return [];
}

// 辅助函数:放置陷阱
function placeTrapAtPosition(offsetX, offsetY) {
    var centerX = device.width / 2;
    var centerY = device.height / 2;
    var targetX = centerX + offsetX;
    var targetY = centerY + offsetY;

    // 模拟滑动到目标位置
    swipe(centerX, centerY, targetX, targetY, 500);
    sleep(300);
    
    // 点击放置
    click(targetX, targetY);
    log("已放置陷阱:" + targetX + "," + targetY);
}

// 辅助函数:等待关卡结束
function waitForLevelEnd(keyword) {
    var startTime = new Date().getTime();
    while (true) {
        var text = ocrText();
        if (text.indexOf(keyword) > -1) {
            return true;
        }
        if (new Date().getTime() - startTime > 30000) {
            return false;
        }
        sleep(1000);
    }
}

// 辅助函数:随机延迟
function randomDelay(min, max) {
    return Math.floor(Math.random() * (max - min + 1)) + min;
}

// 其他辅助函数占位符
function openTrapMenu() { /* 实现逻辑 */ }
function closeTrapMenu() { /* 实现逻辑 */ }
function nextLevel() { /* 实现逻辑 */ }

main();

4. 调试与优化建议

  1. 坐标采集

    • 在手机上打开 Hamibot App,进入「设备调试」。
    • 点击界面上的关键位置,记录 bounds 信息。
    • 对于地图上的点位,建议以屏幕中心为原点 (0,0),记录相对偏移量,这样换手机后只需调整 setScreenMetrics 即可。
  2. 识图替代 OCR

    • 如果 OCR 识别不稳定,可以使用 imageMatch 功能。截图保存关卡结束的界面,然后在脚本中使用 images.matchTemplate 进行匹配。这比文字识别更稳定。
  3. 防封号机制

    • 随机延迟:不要使用固定的 sleep(1000),使用 randomDelay 让每次间隔在 1 秒到 3 秒之间波动。
    • 滑动轨迹swipe 的路径不要是直线,可以稍微弯曲一点,更接近手指滑动的物理特性。
    • 间歇休息:连续运行几局后,脚本可以主动暂停几分钟,模拟人类休息。
  4. 异常处理

    • 如果某一步骤找不到控件(如“上帝视角”按钮),脚本不应直接崩溃,而是应该记录错误并尝试重试或退出当前关卡。
  5. 测试流程

    • 先在单机模式下跑通第一关。
    • 确认坐标无误后,再增加循环逻辑。
    • 观察控制台日志,确保每一步都按预期执行。

5. 风险提示

  • 游戏合规:自动化操作可能违反游戏用户协议,请自行承担风险。
  • 稳定性:游戏版本更新可能导致 UI 变化,脚本需要定期维护。
  • 电量与网络:长时间挂机请保持充电和网络稳定。

详细的技术文档和 API 接口说明,请访问:https://docs.hamibot.com/

ℹ️ 内容由 AI 生成,可能不准确,请注意核实