学号 20241202 《Python程序设计》实验四报告

课程:《Python程序设计》
班级: 2412
姓名: 王凯
学号:20241202
实验教师:王志强
实验日期:2025年5月14日
必修/选修: 公选课

1.实验内容

基于所玩游戏需要抢部分商品,鉴于手速过慢,所抢人数过多,想编写一个连点器的代码,从单纯的连点进阶到预设点位连点,具有连点器该有的基本功能,以此帮助自己。

2. 实验过程及结果

(1)先写了一份初版代码,此版代码无法预设点位,只能单纯设置间隔时间与连点(在最后一节python课上帮助我抢到三次回答问题的机会)。
视频链接在下方,此处只插入一张图片为证(强哥应该不会因为我用代码抢答而揍我吧??)。

(2)此为初版代码运行截屏。

(3)按照面向对象的设计思路,实现 AutoClicker 类,包含以下主要方法:(询问了ai)

init():初始化程序状态和参数
start_clicking():控制自动点击的主循环
toggle_clicking():切换点击状态(开始 / 停止)
set_interval():设置点击间隔时间
set_click_type():设置点击类型(左 / 右 / 中键)
add_point():添加当前鼠标位置为预设点位
clear_points():清除所有预设点位
list_points():列出所有预设点位
set_loop_mode():设置循环模式
on_press():处理键盘按键事件
run():启动程序,初始化线程和键盘监听器
(4)由于一些部分自己并不会,是由ai编写改进的代码,因此专门去查询了解了实验原理————动连点器基于 Python 的多个库协同工作实现功能:

pyautogui 库:用于控制鼠标的移动和点击操作,实现自动化点击功能。
pynput.keyboard 库:监听键盘事件,实现快捷键控制程序运行状态、设置参数等功能。
threading 库:实现多线程编程,将点击操作与键盘监听分离,确保程序响应灵敏。
time 库:控制点击间隔时间,实现精确的自动点击频率。
(5)诞生了进阶版连点器代码。代码实现了在提前预设点位的准备下进行游戏内商品的抢取(当然也可用在其它方面)。下图为运行截图,后有视频链接。

3.代码

import threading
import pyautogui
from pynput import keyboard


class AutoClicker:
    def __init__(self):
        self.running = False
        self.program_running = True
        self.click_interval = 0.1  # 默认点击间隔0.1秒
        self.click_type = "left"  # 默认左键点击
        self.points = []  # 存储预设点位
        self.current_point_index = 0  # 当前点位索引
        self.loop_mode = "sequence"  # 点击模式: sequence(顺序) 或 repeat(重复单点)

    def start_clicking(self):
        while self.program_running:
            while self.running and self.points:
                x, y = self.points[self.current_point_index]
                pyautogui.moveTo(x, y)  # 移动到点位
                if self.click_type == "left":
                    pyautogui.click(button="left")
                elif self.click_type == "right":
                    pyautogui.click(button="right")
                elif self.click_type == "middle":
                    pyautogui.click(button="middle")

                # 更新点位索引
                if self.loop_mode == "sequence":
                    self.current_point_index = (self.current_point_index + 1) % len(self.points)
                # 延迟
                time.sleep(self.click_interval)
            time.sleep(0.1)

    def toggle_clicking(self):
        self.running = not self.running
        status = "开始" if self.running else "停止"
        print(f"{status}连点,间隔: {self.click_interval}秒,模式: {self.loop_mode}")

    def set_interval(self, interval):
        try:
            self.click_interval = max(0.01, float(interval))  # 最小间隔0.01秒
            print(f"设置点击间隔为: {self.click_interval}秒")
        except ValueError:
            print("输入无效,请输入数字")

    def set_click_type(self, click_type):
        if click_type in ["left", "right", "middle"]:
            self.click_type = click_type
            print(f"设置点击按钮为: {self.click_type}键")
        else:
            print("无效的点击类型,请选择: left, right, middle")

    def add_point(self):
        """添加当前鼠标位置为预设点位"""
        x, y = pyautogui.position()
        self.points.append((x, y))
        print(f"已添加点位 {len(self.points)}: ({x}, {y})")

    def clear_points(self):
        """清除所有预设点位"""
        self.points = []
        self.current_point_index = 0
        print("已清除所有预设点位")

    def list_points(self):
        """列出所有预设点位"""
        if not self.points:
            print("没有预设点位")
            return
        print("预设点位列表:")
        for i, (x, y) in enumerate(self.points, 1):
            print(f"{i}. ({x}, {y})")

    def set_loop_mode(self, mode):
        """设置循环模式: sequence(顺序) 或 repeat(重复单点)"""
        if mode in ["sequence", "repeat"]:
            self.loop_mode = mode
            print(f"设置循环模式为: {self.loop_mode}")
        else:
            print("无效的模式,请选择: sequence 或 repeat")

    def exit(self):
        self.running = False
        self.program_running = False
        print("程序已退出")

    def on_press(self, key):
        try:
            if key.char == 's':  # S键开始/停止连点
                self.toggle_clicking()
            elif key.char == 'i':  # I键设置间隔
                new_interval = input("请输入点击间隔(秒): ")
                self.set_interval(new_interval)
            elif key.char == 't':  # T键设置点击类型
                new_type = input("请输入点击类型(left/right/middle): ")
                self.set_click_type(new_type)
            elif key.char == 'a':  # A键添加当前鼠标位置为点位
                self.add_point()
            elif key.char == 'c':  # C键清除所有点位
                self.clear_points()
            elif key.char == 'l':  # L键列出所有点位
                self.list_points()
            elif key.char == 'm':  # M键设置循环模式
                new_mode = input("请输入循环模式(sequence/repeat): ")
                self.set_loop_mode(new_mode)
            elif key.char == 'q':  # Q键退出程序
                self.exit()
                return False
        except AttributeError:
            pass

    def run(self):
        print("自动连点器已启动")
        print("快捷键:")
        print("S: 开始/停止连点")
        print("I: 设置点击间隔")
        print("T: 设置点击类型")
        print("A: 添加当前鼠标位置为预设点位")
        print("C: 清除所有预设点位")
        print("L: 列出所有预设点位")
        print("M: 设置循环模式(顺序/重复)")
        print("Q: 退出程序")

        click_thread = threading.Thread(target=self.start_clicking)
        click_thread.daemon = True
        click_thread.start()

        with keyboard.Listener(on_press=self.on_press) as listener:
            listener.join()


if __name__ == "__main__":
    clicker = AutoClicker()
    clicker.run()    

4. 实验过程中遇到的问题和解决过程

  • 问题1:在写代码时,遇到一些配置上的问题。

  • 问题1解决方案:询问豆包后,进行了配置。(以下为解决过程的截图)

  • 问题2:在用户输入设置参数时,可能与自动点击线程产生冲突。

  • 问题2解决方案:使用线程锁保护共享资源。(代码如下)


class AutoClicker:
    def __init__(self):
        self.lock = threading.Lock()
        # 其他初始化代码...
        
    def start_clicking(self):
        while self.program_running:
            while self.running and self.points:
                with self.lock:
                    x, y = self.points[self.current_point_index]
  • 问题3:在某些受保护的应用程序中,键盘监听器可能无法工作。

  • 问题3解决方案:使用全局热键而非应用内快捷键;图形界面替代命令行输入,使用 tkinter 或 PyQt 创建窗口。

5.运行视频链接

1.https://www.bilibili.com/video/BV1fMTez8EAC/?spm_id_from=333.1387.upload.video_card.click&vd_source=9d355fcfc6d4f05dde0c634c52e6fa8f(初版)
2.https://www.bilibili.com/video/BV1e6TvztECG/?spm_id_from=333.1387.list.card_archive.click&vd_source=9d355fcfc6d4f05dde0c634c52e6fa8f(进阶版)

其他(感悟、思考等)

在经历一个学期的学习后,回想课程的点点滴滴,是一段有趣且收获颇丰的经历,在课程中学到了知识,虽然只是初窥门径,但老师的讲法以及python本身的简便性确实提升了我对python的兴趣。丛老师带着写实验到最后一次的自我发挥,明显感觉到了自己的进步,讲实话,最后一次实验设计成自我发挥简直是神之一手,给了我们自我发挥自己想法的一个很好的机会。希望今后的日子里能继续与python结缘。

参考资料

1.《0基础学python》
2.豆包ai

posted @ 2025-06-09 23:14  若梦若孟  阅读(25)  评论(0)    收藏  举报