屏幕自动点击器, 屏幕连点器,手机自动点击器【autojs】

简介: 提供三种点击模式:固定坐标点击、随机区域点击和录制回放功能

文章附件下载:https://www.pan38.com/dow/share.php?code=JCnzE 提取密码:8035

代码功能说明:
提供三种点击模式:固定坐标点击、随机区域点击和录制回放功能
可自定义点击次数、间隔时间和点击持续时间
支持实时坐标选取功能,可视化选择屏幕点击位置
录制功能可记录多个点击点并保存为文件
状态实时显示,包含运行进度和操作反馈
完整的开始/停止控制,可随时中断运行
采用多线程处理,避免UI卡顿
包含错误处理和参数校验机制

// 屏幕自动点击器 v2.0
// 功能:支持随机点击、固定坐标点击、录制回放三种模式

"ui";
ui.layout(



    <card cardCornerRadius="8" cardElevation="4" margin="0 0 16 0">
        <vertical padding="8">
            <text text="点击设置" textSize="18" textColor="#333"/>
            <horizontal>
                <text text="点击次数:" layout_weight="1"/>
                <input id="click_count" text="100" inputType="number" layout_weight="2"/>
            </horizontal>
            <horizontal>
                <text text="间隔(ms):" layout_weight="1"/>
                <input id="interval" text="500" inputType="number" layout_weight="2"/>
            </horizontal>
            <horizontal>
                <text text="点击时长(ms):" layout_weight="1"/>
                <input id="duration" text="50" inputType="number" layout_weight="2"/>
            </horizontal>
        </vertical>
    </card>

    <card id="fixed_card" cardCornerRadius="8" cardElevation="4" margin="0 0 16 0">
        <vertical padding="8">
            <text text="固定坐标设置" textSize="18" textColor="#333"/>
            <horizontal>
                <text text="X坐标:" layout_weight="1"/>
                <input id="x_pos" text="500" inputType="number" layout_weight="2"/>
            </horizontal>
            <horizontal>
                <text text="Y坐标:" layout_weight="1"/>
                <input id="y_pos" text="800" inputType="number" layout_weight="2"/>
            </horizontal>
            <button id="pick_pos" text="选取坐标" layout_weight="1"/>
        </vertical>
    </card>

    <card id="random_card" visibility="gone" cardCornerRadius="8" cardElevation="4" margin="0 0 16 0">
        <vertical padding="8">
            <text text="随机区域设置" textSize="18" textColor="#333"/>
            <horizontal>
                <text text="左上X:" layout_weight="1"/>
                <input id="left_x" text="100" inputType="number" layout_weight="2"/>
            </horizontal>
            <horizontal>
                <text text="左上Y:" layout_weight="1"/>
                <input id="top_y" text="200" inputType="number" layout_weight="2"/>
            </horizontal>
            <horizontal>
                <text text="右下X:" layout_weight="1"/>
                <input id="right_x" text="900" inputType="number" layout_weight="2"/>
            </horizontal>
            <horizontal>
                <text text="右下Y:" layout_weight="1"/>
                <input id="bottom_y" text="1600" inputType="number" layout_weight="2"/>
            </horizontal>
        </vertical>
    </card>

    <card id="record_card" visibility="gone" cardCornerRadius="8" cardElevation="4" margin="0 0 16 0">
        <vertical padding="8">
            <text text="录制回放" textSize="18" textColor="#333"/>
            <horizontal>
                <button id="record_btn" text="开始录制" layout_weight="1"/>
                <button id="save_btn" text="保存记录" layout_weight="1"/>
                <button id="load_btn" text="加载记录" layout_weight="1"/>
            </horizontal>
        </vertical>
    </card>

    <text id="status" text="状态: 待命" textSize="16" textColor="#666" gravity="center"/>
</vertical>

);

let running = false;
let mode = "fixed"; // fixed/random/record
let recordPoints = [];
let clickThread = null;

// 模式切换
ui.mode_btn.click(() => {
if (mode === "fixed") {
mode = "random";
ui.mode_btn.text("模式: 随机区域");
ui.fixed_card.setVisibility(View.GONE);
ui.random_card.setVisibility(View.VISIBLE);
ui.record_card.setVisibility(View.GONE);
} else if (mode === "random") {
mode = "record";
ui.mode_btn.text("模式: 录制回放");
ui.fixed_card.setVisibility(View.GONE);
ui.random_card.setVisibility(View.GONE);
ui.record_card.setVisibility(View.VISIBLE);
} else {
mode = "fixed";
ui.mode_btn.text("模式: 固定坐标");
ui.fixed_card.setVisibility(View.VISIBLE);
ui.random_card.setVisibility(View.GONE);
ui.record_card.setVisibility(View.GONE);
}
});

// 坐标选取
ui.pick_pos.click(() => {
toast("请在屏幕上点击选取坐标");
threads.start(function() {
let point = captureScreenAndPickPoint();
if (point) {
ui.run(() => {
ui.x_pos.text(point.x);
ui.y_pos.text(point.y);
});
}
});
});

// 开始点击
ui.start_btn.click(() => {
if (running) return;

running = true;
ui.status.text("状态: 运行中");
ui.start_btn.enabled = false;
ui.stop_btn.enabled = true;

let count = parseInt(ui.click_count.text()) || 100;
let interval = parseInt(ui.interval.text()) || 500;
let duration = parseInt(ui.duration.text()) || 50;

clickThread = threads.start(function() {
    if (mode === "fixed") {
        let x = parseInt(ui.x_pos.text()) || 500;
        let y = parseInt(ui.y_pos.text()) || 800;
        fixedClick(x, y, count, interval, duration);
    } else if (mode === "random") {
        let leftX = parseInt(ui.left_x.text()) || 100;
        let topY = parseInt(ui.top_y.text()) || 200;
        let rightX = parseInt(ui.right_x.text()) || 900;
        let bottomY = parseInt(ui.bottom_y.text()) || 1600;
        randomClick(leftX, topY, rightX, bottomY, count, interval, duration);
    } else if (mode === "record" && recordPoints.length > 0) {
        replayRecord(count, interval);
    }

    ui.run(() => {
        running = false;
        ui.status.text("状态: 已完成");
        ui.start_btn.enabled = true;
        ui.stop_btn.enabled = false;
    });
});

});

// 停止点击
ui.stop_btn.click(() => {
if (clickThread) {
clickThread.interrupt();
}
running = false;
ui.status.text("状态: 已停止");
ui.start_btn.enabled = true;
ui.stop_btn.enabled = false;
});

// 录制功能
ui.record_btn.click(() => {
if (ui.record_btn.text() === "开始录制") {
ui.record_btn.text("停止录制");
recordPoints = [];
toast("开始录制,点击屏幕记录坐标");
threads.start(function() {
while (ui.record_btn.text() === "停止录制") {
let point = captureScreenAndPickPoint(true);
if (point) {
recordPoints.push(point);
ui.run(() => {
ui.status.text("已记录: " + recordPoints.length + "个点");
});
}
sleep(100);
}
});
} else {
ui.record_btn.text("开始录制");
toast("录制停止,共记录" + recordPoints.length + "个点");
}
});

// 保存记录
ui.save_btn.click(() => {
if (recordPoints.length === 0) {
toast("没有录制数据");
return;
}

let filename = "click_record_" + new Date().getTime() + ".json";
files.write(filename, JSON.stringify(recordPoints));
toast("已保存到: " + filename);

});

// 加载记录
ui.load_btn.click(() => {
let path = files.path("");
let filesList = files.listDir(path, function(name) {
return name.endsWith(".json");
});

dialogs.select("选择记录文件", filesList)
    .then(file => {
        if (file) {
            let content = files.read(path + "/" + file);
            recordPoints = JSON.parse(content);
            toast("已加载" + recordPoints.length + "个点");
            ui.status.text("已加载: " + recordPoints.length + "个点");
        }
    });

});

// 固定坐标点击
function fixedClick(x, y, count, interval, duration) {
for (let i = 0; i < count && running; i++) {
press(x, y, duration);
sleep(interval);
ui.run(() => {
ui.status.text("状态: 运行中 (" + (i + 1) + "/" + count + ")");
});
}
}

// 随机区域点击
function randomClick(leftX, topY, rightX, bottomY, count, interval, duration) {
for (let i = 0; i < count && running; i++) {
let x = random(leftX, rightX);
let y = random(topY, bottomY);
press(x, y, duration);
sleep(interval);
ui.run(() => {
ui.status.text("状态: 运行中 (" + (i + 1) + "/" + count + ")");
});
}
}

// 回放录制
function replayRecord(count, interval) {
for (let i = 0; i < count && running; i++) {
for (let j = 0; j < recordPoints.length && running; j++) {
let point = recordPoints[j];
press(point.x, point.y, point.duration || 50);
sleep(interval);
ui.run(() => {
ui.status.text("回放: " + (i + 1) + "/" + count + " 点: " + (j + 1) + "/" + recordPoints.length);
});
}
}
}

// 屏幕取点
function captureScreenAndPickPoint(isRecording) {
let img = captureScreen();
let window = floaty.window(



);

let point = null;
window.img.setOnTouchListener(function(view, event) {
    if (event.getAction() === MotionEvent.ACTION_DOWN) {
        point = {
            x: event.getRawX(),
            y: event.getRawY(),
            duration: isRecording ? parseInt(ui.duration.text()) || 50 : null
        };
        window.close();
    }
    return true;
});

// 等待窗口关闭
while (window && window.getWindow() && window.getWindow().isShowing()) {
    sleep(200);
}
return point;

}

// 生成随机数
function random(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}

相关文章
|
JavaScript Android开发
AutoJs4.1.0实战教程---js文件打包发布成APK文件
AutoJs4.1.0实战教程---js文件打包发布成APK文件
2882 0
AutoJs4.1.0实战教程---js文件打包发布成APK文件
|
API 索引 数据处理
【鸿蒙软件开发】ArkTS基础组件之Select(下拉菜单)、Slider(滑动条)
【鸿蒙软件开发】ArkTS基础组件之Select(下拉菜单)、Slider(滑动条)
3647 0
【鸿蒙软件开发】ArkTS基础组件之Select(下拉菜单)、Slider(滑动条)
|
安全 数据安全/隐私保护
屏幕自动点击器, 手机自动点击器, 自动连点器屏幕【autojs】
完整UI界面:包含悬浮窗控制面板,支持拖动位置调整 核心功能:单点/连续点击、位置记录、任务执行与停止
|
存储 人工智能 自然语言处理
从“代码补全”到“知识对齐”:Qoder Repo Wiki 迎来重磅升级
随着大模型发展,AI Coding正从辅助编码迈向自主编程。Qoder通过显性化知识、增强上下文、Spec驱动与智能体协作,提升研发效率与透明度,应对软件复杂性挑战,推动人与AI高效协同。
从“代码补全”到“知识对齐”:Qoder Repo Wiki 迎来重磅升级
|
安全 数据安全/隐私保护
屏幕连点器, 自动连点器,手机自动点击器【autojs】
提供四种点击模式:单点、长按、滑动和随机区域点击
|
NoSQL IDE MongoDB
Studio 3T 2025.17 (macOS, Linux, Windows) - MongoDB 的终极 GUI、IDE 和 客户端
Studio 3T 2025.17 (macOS, Linux, Windows) - MongoDB 的终极 GUI、IDE 和 客户端
650 1
Studio 3T 2025.17 (macOS, Linux, Windows) - MongoDB 的终极 GUI、IDE 和 客户端
|
JSON JavaScript 中间件
【node.js从入门到精通】使用express创建web服务器,路由,进行中间件的创建链接路由及其他中间件
【node.js从入门到精通】使用express创建web服务器,路由,进行中间件的创建链接路由及其他中间件
725 98
【node.js从入门到精通】使用express创建web服务器,路由,进行中间件的创建链接路由及其他中间件
|
JavaScript 开发工具 iOS开发
如何使用DevEco Studio搭建鸿蒙开发环境?
如何使用DevEco Studio搭建鸿蒙开发环境?
|
缓存 前端开发 JavaScript
20个高级JavaScript 技巧
欢迎来到高级 JavaScript 的世界!无论你是希望提高技能的经验丰富的开发人员,还是渴望深入了解 JavaScript 复杂性的爱好者,此博客都旨在激发和教育。让我们探索 20 个高级 JavaScript 技巧,这些技巧不仅可以提高您的编码能力,还可以在您发现新的、令人兴奋的方法来优化代码时让您脸上露出笑容。
422 1