####一、脚本架构升级:模块化设计与扩展性
在上一篇基础脚本的架构上,我们可以进一步优化设计,采用更先进的模块化架构,提高脚本的可维护性和扩展性。以下是一个升级版的脚本框架:
```python
importpyautogui
importcv2
importnumpyasnp
importtime
importwin32gui
importwin32con
importrandom
importlogging
fromenumimportEnum
fromtypingimportDictListTupleOptional
#配置日志
logging.basicConfig(level=logging.INFOformat='%(asctime)s-%(levelname)s-%(message)s')
logger=logging.getLogger(__name__)
classGameState(Enum):
BATTLE=1#战斗状态
PICKING=2#拾取状态
RETURNING=3#回城状态
RESTING=4#休息状态
ERROR=5#错误状态
classActionType(Enum):
ATTACK=1#攻击
USE_SKILL=2#使用技能
PICK=3#拾取
DRINK_HP=4#喝血药
DRINK_MP=5#喝蓝药
RETURN_TOWN=6#回城
SELL_ITEMS=7#卖物品
REPAIR=8#修理装备
classMonsterType(Enum):
NORMAL=1#普通怪物
ELITE=2#精英怪物
BOSS=3#首领怪物
classLegendAutoScript:
def__init__(self):
#游戏窗口信息
self.game_window_title="复古传奇"
self.game_hwnd=None
self.game_rect=None
#配置参数
self.config={
"safe_hp_percent":30
"safe_mp_percent":20
"battle_interval":(1.02.0)
"pick_interval":3.0
"max_inventory_percent":80#背包最大占用百分比
"skill_key_mapping":{#技能键位映射
"basic_attack":"space"
"skill1":"f1"
"skill2":"f2"
"skill3":"f3"
}
"monster_priority":[MonsterType.BOSSMonsterType.ELITEMonsterType.NORMAL]
}
#游戏状态
self.current_state=GameState.BATTLE
self.last_action=None
self.last_action_time=0
self.current_hp=100
self.current_mp=100
self.inventory_percent=0
self.target_monster=None
#物品和怪物识别模板
self.item_templates=self._load_templates("items")
self.monster_templates=self._load_templates("monsters")
#战斗策略
self.combat_strategies={
MonsterType.NORMAL:["basic_attack"]
MonsterType.ELITE:["basic_attack""skill1"]
MonsterType.BOSS:["basic_attack""skill1""skill2"]
}
#任务系统
self.current_task=None
self.tasks_queue=[]
def_load_templates(selfdirectory:str)->Dict[strTuple[np.ndarrayEnum]]:
"""加载识别模板"""
templates={}
#实际实现中需要从指定目录加载图片并关联类型
#简化示例,实际使用时需完善
returntemplates
definitialize(self)->bool:
"""初始化游戏连接和配置"""
logger.info("正在初始化游戏连接...")
ifnotself._connect_to_game():
logger.error("游戏连接失败")
returnFalse
logger.info("加载识别模板...")
self.item_templates=self._load_templates("items")
self.monster_templates=self._load_templates("monsters")
logger.info("初始化完成")
returnTrue
def_connect_to_game(self)->bool:
"""连接到游戏窗口"""
self.game_hwnd=win32gui.FindWindow(Noneself.game_window_title)
ifnotself.game_hwnd:
logger.error(f"未找到游戏窗口:{self.game_window_title}")
returnFalse
rect=win32gui.GetWindowRect(self.game_hwnd)
self.game_rect=(rect[0]rect[1]rect[2]-rect[0]rect[3]-rect[1])
logger.info(f"找到游戏窗口:{self.game_window_title}位置:{self.game_rect}")
#激活窗口
win32gui.SetForegroundWindow(self.game_hwnd)
time.sleep(0.5)
returnTrue
defupdate_game_state(self):
"""更新游戏状态"""
self._update_health_and_mana()
self._update_inventory()
self._detect_monsters()
self._update_state_machine()
def_update_health_and_mana(self):
"""更新角色血量和魔法值"""
#实际实现中使用图像识别获取血条和魔法条状态
#简化示例
self.current_hp=random.randint(1100)
self.current_mp=random.randint(1100)
logger.debug(f"当前状态:HP={self.current_hp}%MP={self.current_mp}%")
def_update_inventory(self):
"""更新背包状态"""
#实际实现中识别背包物品数量
#简化示例
self.inventory_percent=random.randint(0100)
logger.debug(f"背包状态:{self.inventory_percent}%")
def_detect_monsters(self):
"""检测周围怪物"""
#实际实现中使用图像识别检测怪物
#简化示例
self.target_monster={
"type":random.choice(list(MonsterType))
"location":(random.randint(100500)random.randint(100400))
}
logger.debug(f"检测到怪物:{self.target_monster['type'].name}")
def_update_state_machine(self):
"""更新状态机"""
#根据当前游戏状态决定行为
ifself.current_hp<self.config["safe_hp_percent"]:
self.current_state=GameState.RETURNING
return
ifself.current_mp<self.config["safe_mp_percent"]:
self.current_state=GameState.RETURNING
return
ifself.inventory_percent>self.config["max_inventory_percent"]:
self.current_state=GameState.RETURNING
return
ifself.target_monster:
self.current_state=GameState.BATTLE
else:
self.current_state=GameState.PICKING
defexecute_action(selfaction_type:ActionTypetarget:Optional[Tuple[intint]]=None):
"""执行游戏动作"""
logger.info(f"执行动作:{action_type.name}")
self.last_action=action_type
self.last_action_time=time.time()
#根据不同动作类型执行不同操作
ifaction_type==ActionType.ATTACK:
self._perform_attack(target)
elifaction_type==ActionType.USE_SKILL:
self._use_skill(target)
elifaction_type==ActionType.PICK:
self._pick_item(target)
elifaction_type==ActionType.DRINK_HP:
self._drink_hp_potion()
elifaction_type==ActionType.DRINK_MP:
self._drink_mp_potion()
elifaction_type==ActionType.RETURN_TOWN:
self._return_to_town()
elifaction_type==ActionType.SELL_ITEMS:
self._sell_items()
elifaction_type==ActionType.REPAIR:
self._repair_equipment()
#添加随机延迟,模拟人类操作
delay=random.uniform(0.30.7)
time.sleep(delay)
def_perform_attack(selftarget:Tuple[intint]):
"""执行普通攻击"""
xy=target
screen_x=self.game_rect[0]+x
screen_y=self.game_rect[1]+y
pyautogui.moveTo(screen_xscreen_yduration=0.2+random.random()*0.3)
pyautogui.click()
def_use_skill(selftarget:Tuple[intint]):
"""使用技能"""
#根据怪物类型选择合适的技能
monster_type=self.target_monster["type"]
skills=self.combat_strategies.get(monster_type["basic_attack"])
skill_key=self.config["skill_key_mapping"].get(skills[0]"space")
xy=target
screen_x=self.game_rect[0]+x
screen_y=self.game_rect[1]+y
pyautogui.moveTo(screen_xscreen_yduration=0.2+random.random()*0.3)
pyautogui.press(skill_key)
def_pick_item(selftarget:Tuple[intint]):
"""拾取物品"""
xy=target
screen_x=self.game_rect[0]+x
screen_y=self.game_rect[1]+y
pyautogui.moveTo(screen_xscreen_yduration=0.2+random.random()*0.3)
pyautogui.press('space')
def_drink_hp_potion(self):
"""喝血药"""
pyautogui.press('f4')#假设F4是血药快捷键
def_drink_mp_potion(self):
"""喝蓝药"""
pyautogui.press('f5')#假设F5是蓝药快捷键
def_return_to_town(self):
"""回城"""
logger.info("正在返回城镇...")
pyautogui.press('f2')#假设F2是回城快捷键
time.sleep(8+random.random()*2)#等待回城动画
def_sell_items(self):
"""卖物品"""
logger.info("正在出售物品...")
#实现卖物品逻辑
time.sleep(5+random.random()*2)
def_repair_equipment(self):
"""修理装备"""
logger.info("正在修理装备...")
#实现修理装备逻辑
time.sleep(3+random.random()*1)
defcombat_loop(self):
"""战斗循环"""
whileTrue:
try:
#更新游戏状态
self.update_game_state()
#根据当前状态执行相应动作
ifself.current_state==GameState.BATTLE:
ifself.target_monster:
#选择合适的攻击方式
ifself.current_mp>50andrandom.random()<0.3:
self.execute_action(ActionType.USE_SKILLself.target_monster["location"])
else:
self.execute_action(ActionType.ATTACKself.target_monster["location"])
else:
#没有目标,移动寻找怪物
self._move_to_random_location()
elifself.current_state==GameState.PICKING:
items=self._detect_items()
ifitems:
#优先拾取价值高的物品
valuable_items=sorted(itemskey=lambdax:x[2]reverse=True)
self.execute_action(ActionType.PICKvaluable_items[0][0:2])
else:
#没有物品可拾取,继续寻找怪物
self.current_state=GameState.BATTLE
elifself.current_state==GameState.RETURNING:
self.execute_action(ActionType.RETURN_TOWN)
#回城后执行卖物品和修理装备
ifself.inventory_percent>self.config["max_inventory_percent"]:
self.execute_action(ActionType.SELL_ITEMS)
#检查装备耐久度
ifself._need_repair():
self.execute_action(ActionType.REPAIR)
#补充药水
self._buy_potions()
#回到战斗区域
self._move_to_combat_area()
self.current_state=GameState.BATTLE
elifself.current_state==GameState.RESTING:
#休息恢复状态
time.sleep(5)
self.current_state=GameState.BATTLE
elifself.current_state==GameState.ERROR:
#错误处理
logger.error("脚本遇到错误,尝试恢复...")
time.sleep(5)
self.current_state=GameState.BATTLE
#添加随机延迟,避免行为过于规律
time.sleep(random.uniform(0.51.5))
exceptExceptionase:
logger.error(f"发生异常:{str(e)}")
self.current_state=GameState.ERROR
time.sleep(5)
def_move_to_random_location(self):
"""移动到随机位置"""
ifnotself.game_rect:
return
lefttopwidthheight=self.game_rect
#计算安全移动区域
move_area=(int(width*0.3)int(height*0.3)
int(width*0.4)int(height*0.4))
#随机选择目标位置
x=left+move_area[0]+random.randint(0move_area[2])
y=top+move_area[1]+random.randint(0move_area[3])
#模拟鼠标移动并点击地面
pyautogui.moveTo(xyduration=0.5+random.random())
pyautogui.rightClick()
logger.info(f"移动到位置:({x}{y})")
#等待角色移动
move_time=random.uniform(2.05.0)
time.sleep(move_time)
def_detect_items(self)->List[Tuple[intintint]]:
"""检测地面物品"""
#实际实现中使用图像识别检测物品
#返回值格式:[(x坐标y坐标价值)...]
return[
(random.randint(100500)random.randint(100400)random.randint(1100))
for_inrange(random.randint(03))
]
def_need_repair(self)->bool:
"""检查装备是否需要修理"""
#实际实现中使用图像识别检查装备耐久度
#简化示例
returnrandom.random()<0.3
def_buy_potions(self):
"""购买药水"""
logger.info("正在购买药水...")
#实现购买药水逻辑
time.sleep(3+random.random()*2)
def_move_to_combat_area(self):
"""移动到战斗区域"""
logger.info("正在前往战斗区域...")
#实现移动到预设战斗区域的逻辑
time.sleep(5+random.random()*3)
#脚本入口
if__name__=="__main__":
script=LegendAutoScript()
ifscript.initialize():
script.combat_loop()
```
####二、高级功能实现:智能战斗系统
在上一版基础脚本的基础上,我们实现了更高级的战斗系统,具有以下特性:
1.**状态机设计**:使用状态机管理不同游戏状态(战斗、拾取、回城等)
2.**怪物分类与优先级**:区分普通怪物、精英怪物和首领,设置不同的攻击策略
3.**技能系统**:根据怪物类型和角色状态智能选择技能
4.**背包管理**:自动回城卖物品,保持背包空间
5.**装备维护**:检测装备耐久度,自动修理装备
战斗系统的核心是根据不同怪物类型应用不同的战斗策略:
```python
#战斗策略配置
self.combat_strategies={
MonsterType.NORMAL:["basic_attack"]
MonsterType.ELITE:["basic_attack""skill1"]
MonsterType.BOSS:["basic_attack""skill1""skill2"]
}
#根据怪物类型选择合适的技能
monster_type=self.target_monster["type"]
skills=self.combat_strategies.get(monster_type["basic_attack"])
skill_key=self.config["skill_key_mapping"].get(skills[0]"space")
```
####三、图像识别优化:提高准确性与性能
为了提高脚本的稳定性和可靠性,我们可以采用以下图像识别优化技术:
1.**多分辨率模板匹配**:支持不同分辨率的游戏窗口
2.**特征点匹配**:使用ORB或SIFT特征点匹配,提高复杂场景下的识别率
3.**图像预处理**:灰度化、二值化、降噪等预处理技术
4.**置信度阈值自适应**:根据场景复杂度自动调整匹配阈值
以下是一个优化后的图像识别函数:
```python
deffind_template_on_screen(selftemplatethreshold=0.8use_feature_matching=False)->Optional[Tuple[intintfloat]]:
"""在屏幕上查找模板图像,支持特征点匹配"""
screen=self.capture_game_screen()
ifscreenisNone:
returnNone
screen_gray=cv2.cvtColor(screencv2.COLOR_BGR2GRAY)
ifuse_feature_matching:
#使用特征点匹配
orb=cv2.ORB_create()
kp1des1=orb.detectAndCompute(templateNone)
kp2des2=orb.detectAndCompute(screen_grayNone)
bf=cv2.BFMatcher(cv2.NORM_HAMMINGcrossCheck=True)
matches=bf.match(des1des2)
matches=sorted(matchesby=lambdax:x.distance)
iflen(matches)>10:#至少需要10个匹配点
src_pts=np.float32([kp1[m.queryIdx].ptforminmatches]).reshape(-112)
dst_pts=np.float32([kp2[m.trainIdx].ptforminmatches]).reshape(-112)
Mmask=cv2.findHomography(src_ptsdst_ptscv2.RANSAC5.0)
ifMisnotNone:
hw=template.shape
pts=np.float32([[00][0h-1][w-1h-1][w-10]]).reshape(-112)
dst=cv2.perspectiveTransform(ptsM)
#计算中心点
center_x=int(np.mean(dst[::0]))
center_y=int(np.mean(dst[::1]))
#计算匹配置信度
confidence=len(matches)/max(len(kp1)len(kp2))
return(center_xcenter_yconfidence)
returnNone
else:
#使用模板匹配
result=cv2.matchTemplate(screen_graytemplatecv2.TM_CCOEFF_NORMED)
min_valmax_valmin_locmax_loc=cv2.minMaxLoc(result)
ifmax_val>=threshold:
hw=template.shape
center_x=max_loc[0]+w//2
center_y=max_loc[1]+h//2
return(center_xcenter_ymax_val)
returnNone
```
####四、任务系统设计:实现自动化游戏流程
为了实现更复杂的游戏自动化功能,我们可以设计一个任务系统,使脚本能够按照预设流程完成一系列任务:
```python
classTask:
def__init__(selftask_typetarget=Noneparams=None):
self.task_type=task_type#任务类型:打怪、采集、任务等
self.target=target#任务目标:怪物ID、NPC位置等
self.params=paramsor{}#任务参数
self.status="pending"#任务状态:pendingrunningcompletedfailed
self.progress=0#任务进度
self.start_time=0#任务开始时间
self.end_time=0#任务结束时间
defupdate(selfscript):
"""更新任务状态"""
ifself.status=="pending":
self._start(script)
elifself.status=="running":
self._execute(script)
def_start(selfscript):
"""开始任务"""
self.status="running"
self.start_time=time.time()
logger.info(f"开始任务:{self.task_type}目标:{self.target}")
def_execute(selfscript):
"""执行任务逻辑,由子类实现"""
pass
defcomplete(self):
"""完成任务"""
self.status="completed"
self.end_time=time.time()
logger.info(f"任务完成:{self.task_type}耗时:{self.end_time-self.start_time:.2f}秒")
deffail(selfreason="未知原因"):
"""任务失败"""
self.status="failed"
self.end_time=time.time()
logger.info(f"任务失败:{self.task_type}原因:{reason}耗时:{self.end_time-self.start_time:.2f}秒")
classKillMonsterTask(Task):
def__init__(selfmonster_typecount=1):
super().__init__("kill_monster"monster_type{"count":count})
self.killed_count=0
def_execute(selfscript):
#检查是否达到目标数量
ifself.killed_count>=self.params["count"]:
self.complete()
return
#如果没有目标,寻找目标
ifnotscript.target_monsterorscript.target_monster["type"]!=self.target:
script._find_specific_monster(self.target)
return
#攻击目标
script.execute_action(ActionType.ATTACKscript.target_monster["location"])
#模拟击杀逻辑
ifrandom.random()<0.3:#假设30%的攻击能击杀怪物
self.killed_count+=1
self.progress=self.killed_count/self.params["count"]*100
logger.info(f"击杀怪物{self.target.name}进度:{self.killed_count}/{self.params['count']}")
#在脚本中添加任务管理功能
classLegendAutoScript:
def__init__(self):
#...已有代码...
#任务系统
self.current_task=None
self.tasks_queue=[]
defadd_task(selftask):
"""添加任务到队列"""
self.tasks_queue.append(task)
logger.info(f"添加任务到队列:{task.task_type}目标:{task.target}")
defprocess_tasks(self):
"""处理任务队列"""
ifself.current_taskisNoneandself.tasks_queue:
self.current_task=self.tasks_queue.pop(0)
ifself.current_task:
self.current_task.update(self)
ifself.current_task.statusin["completed""failed"]:
self.current_task=Noneifnotself.tasks_queueelseself.tasks_queue.pop(0)
```
####五、反检测技术:保持脚本使用安全
使用游戏辅助脚本存在被游戏检测的风险,以下是一些常用的反检测技术:
1.**操作随机化**:在鼠标移动、点击间隔、按键时间等加入随机变化
2.**行为模式多样化**:模拟人类玩家的不规则行为,避免固定模式
3.**响应延迟**:添加随机思考时间,模拟人类决策过程
4.**异常处理**:添加意外情况处理机制,如游戏掉线、UI变化等
5.**使用频率控制**:不要长时间连续运行脚本,适当休息
在我们的脚本中,已经实现了部分反检测措施:
```python
#添加随机延迟,模拟人类操作
delay=random.uniform(0.30.7)
time.sleep(delay)
#随机选择目标位置
x=left+move_area[0]+random.randint(0move_area[2])
y=top+move_area[1]+random.randint(0move_area[3])
#模拟鼠标移动曲线,更像人类操作
pyautogui.moveTo(xyduration=0.5+random.random())
```
####六、脚本部署与调试指南
1.**环境准备**
-安装Python3.7+
-安装必要的库:`pipinstallpyautoguiopencv-pythonnumpypywin32`
-准备模板图片:在项目目录下创建`items`和`monsters`文件夹,放入对应的模板图片
2.**配置调整**
-修改脚本中的游戏窗口标题,确保能正确找到游戏窗口
-根据自己的快捷键设置,调整技能键位映射
-根据游戏界面,调整血条、魔法条的识别区域
3.**调试技巧**
-使用日志系统查看脚本运行状态
-先在卸围内测试脚本功能,确保各部分正常工作
-使用截图功能保存游戏画面,便于分析识别问题
-逐步增加功能复杂度,不要一次性添加太多功能
4.**常见问题解决**
-脚本无法找到游戏窗口:检查窗口标题是否正确,确保游戏已启动
-图像识别不准确:调整模板图片质量,尝试不同的匹配阈值
-脚本操作无响应:检查游戏窗口是否被遮挡,是否有焦点
通过这些技术,你可以开发出一个功能强大、稳定可靠的复古传奇自动化脚本,帮助你更轻松地体验游戏。记住合理使用脚本,避免过度依赖,保持游戏的乐趣。
在上一篇基础脚本的架构上,我们可以进一步优化设计,采用更先进的模块化架构,提高脚本的可维护性和扩展性。以下是一个升级版的脚本框架:
```python
importpyautogui
importcv2
importnumpyasnp
importtime
importwin32gui
importwin32con
importrandom
importlogging
fromenumimportEnum
fromtypingimportDictListTupleOptional
#配置日志
logging.basicConfig(level=logging.INFOformat='%(asctime)s-%(levelname)s-%(message)s')
logger=logging.getLogger(__name__)
classGameState(Enum):
BATTLE=1#战斗状态
PICKING=2#拾取状态
RETURNING=3#回城状态
RESTING=4#休息状态
ERROR=5#错误状态
classActionType(Enum):
ATTACK=1#攻击
USE_SKILL=2#使用技能
PICK=3#拾取
DRINK_HP=4#喝血药
DRINK_MP=5#喝蓝药
RETURN_TOWN=6#回城
SELL_ITEMS=7#卖物品
REPAIR=8#修理装备
classMonsterType(Enum):
NORMAL=1#普通怪物
ELITE=2#精英怪物
BOSS=3#首领怪物
classLegendAutoScript:
def__init__(self):
#游戏窗口信息
self.game_window_title="复古传奇"
self.game_hwnd=None
self.game_rect=None
#配置参数
self.config={
"safe_hp_percent":30
"safe_mp_percent":20
"battle_interval":(1.02.0)
"pick_interval":3.0
"max_inventory_percent":80#背包最大占用百分比
"skill_key_mapping":{#技能键位映射
"basic_attack":"space"
"skill1":"f1"
"skill2":"f2"
"skill3":"f3"
}
"monster_priority":[MonsterType.BOSSMonsterType.ELITEMonsterType.NORMAL]
}
#游戏状态
self.current_state=GameState.BATTLE
self.last_action=None
self.last_action_time=0
self.current_hp=100
self.current_mp=100
self.inventory_percent=0
self.target_monster=None
#物品和怪物识别模板
self.item_templates=self._load_templates("items")
self.monster_templates=self._load_templates("monsters")
#战斗策略
self.combat_strategies={
MonsterType.NORMAL:["basic_attack"]
MonsterType.ELITE:["basic_attack""skill1"]
MonsterType.BOSS:["basic_attack""skill1""skill2"]
}
#任务系统
self.current_task=None
self.tasks_queue=[]
def_load_templates(selfdirectory:str)->Dict[strTuple[np.ndarrayEnum]]:
"""加载识别模板"""
templates={}
#实际实现中需要从指定目录加载图片并关联类型
#简化示例,实际使用时需完善
returntemplates
definitialize(self)->bool:
"""初始化游戏连接和配置"""
logger.info("正在初始化游戏连接...")
ifnotself._connect_to_game():
logger.error("游戏连接失败")
returnFalse
logger.info("加载识别模板...")
self.item_templates=self._load_templates("items")
self.monster_templates=self._load_templates("monsters")
logger.info("初始化完成")
returnTrue
def_connect_to_game(self)->bool:
"""连接到游戏窗口"""
self.game_hwnd=win32gui.FindWindow(Noneself.game_window_title)
ifnotself.game_hwnd:
logger.error(f"未找到游戏窗口:{self.game_window_title}")
returnFalse
rect=win32gui.GetWindowRect(self.game_hwnd)
self.game_rect=(rect[0]rect[1]rect[2]-rect[0]rect[3]-rect[1])
logger.info(f"找到游戏窗口:{self.game_window_title}位置:{self.game_rect}")
#激活窗口
win32gui.SetForegroundWindow(self.game_hwnd)
time.sleep(0.5)
returnTrue
defupdate_game_state(self):
"""更新游戏状态"""
self._update_health_and_mana()
self._update_inventory()
self._detect_monsters()
self._update_state_machine()
def_update_health_and_mana(self):
"""更新角色血量和魔法值"""
#实际实现中使用图像识别获取血条和魔法条状态
#简化示例
self.current_hp=random.randint(1100)
self.current_mp=random.randint(1100)
logger.debug(f"当前状态:HP={self.current_hp}%MP={self.current_mp}%")
def_update_inventory(self):
"""更新背包状态"""
#实际实现中识别背包物品数量
#简化示例
self.inventory_percent=random.randint(0100)
logger.debug(f"背包状态:{self.inventory_percent}%")
def_detect_monsters(self):
"""检测周围怪物"""
#实际实现中使用图像识别检测怪物
#简化示例
self.target_monster={
"type":random.choice(list(MonsterType))
"location":(random.randint(100500)random.randint(100400))
}
logger.debug(f"检测到怪物:{self.target_monster['type'].name}")
def_update_state_machine(self):
"""更新状态机"""
#根据当前游戏状态决定行为
ifself.current_hp<self.config["safe_hp_percent"]:
self.current_state=GameState.RETURNING
return
ifself.current_mp<self.config["safe_mp_percent"]:
self.current_state=GameState.RETURNING
return
ifself.inventory_percent>self.config["max_inventory_percent"]:
self.current_state=GameState.RETURNING
return
ifself.target_monster:
self.current_state=GameState.BATTLE
else:
self.current_state=GameState.PICKING
defexecute_action(selfaction_type:ActionTypetarget:Optional[Tuple[intint]]=None):
"""执行游戏动作"""
logger.info(f"执行动作:{action_type.name}")
self.last_action=action_type
self.last_action_time=time.time()
#根据不同动作类型执行不同操作
ifaction_type==ActionType.ATTACK:
self._perform_attack(target)
elifaction_type==ActionType.USE_SKILL:
self._use_skill(target)
elifaction_type==ActionType.PICK:
self._pick_item(target)
elifaction_type==ActionType.DRINK_HP:
self._drink_hp_potion()
elifaction_type==ActionType.DRINK_MP:
self._drink_mp_potion()
elifaction_type==ActionType.RETURN_TOWN:
self._return_to_town()
elifaction_type==ActionType.SELL_ITEMS:
self._sell_items()
elifaction_type==ActionType.REPAIR:
self._repair_equipment()
#添加随机延迟,模拟人类操作
delay=random.uniform(0.30.7)
time.sleep(delay)
def_perform_attack(selftarget:Tuple[intint]):
"""执行普通攻击"""
xy=target
screen_x=self.game_rect[0]+x
screen_y=self.game_rect[1]+y
pyautogui.moveTo(screen_xscreen_yduration=0.2+random.random()*0.3)
pyautogui.click()
def_use_skill(selftarget:Tuple[intint]):
"""使用技能"""
#根据怪物类型选择合适的技能
monster_type=self.target_monster["type"]
skills=self.combat_strategies.get(monster_type["basic_attack"])
skill_key=self.config["skill_key_mapping"].get(skills[0]"space")
xy=target
screen_x=self.game_rect[0]+x
screen_y=self.game_rect[1]+y
pyautogui.moveTo(screen_xscreen_yduration=0.2+random.random()*0.3)
pyautogui.press(skill_key)
def_pick_item(selftarget:Tuple[intint]):
"""拾取物品"""
xy=target
screen_x=self.game_rect[0]+x
screen_y=self.game_rect[1]+y
pyautogui.moveTo(screen_xscreen_yduration=0.2+random.random()*0.3)
pyautogui.press('space')
def_drink_hp_potion(self):
"""喝血药"""
pyautogui.press('f4')#假设F4是血药快捷键
def_drink_mp_potion(self):
"""喝蓝药"""
pyautogui.press('f5')#假设F5是蓝药快捷键
def_return_to_town(self):
"""回城"""
logger.info("正在返回城镇...")
pyautogui.press('f2')#假设F2是回城快捷键
time.sleep(8+random.random()*2)#等待回城动画
def_sell_items(self):
"""卖物品"""
logger.info("正在出售物品...")
#实现卖物品逻辑
time.sleep(5+random.random()*2)
def_repair_equipment(self):
"""修理装备"""
logger.info("正在修理装备...")
#实现修理装备逻辑
time.sleep(3+random.random()*1)
defcombat_loop(self):
"""战斗循环"""
whileTrue:
try:
#更新游戏状态
self.update_game_state()
#根据当前状态执行相应动作
ifself.current_state==GameState.BATTLE:
ifself.target_monster:
#选择合适的攻击方式
ifself.current_mp>50andrandom.random()<0.3:
self.execute_action(ActionType.USE_SKILLself.target_monster["location"])
else:
self.execute_action(ActionType.ATTACKself.target_monster["location"])
else:
#没有目标,移动寻找怪物
self._move_to_random_location()
elifself.current_state==GameState.PICKING:
items=self._detect_items()
ifitems:
#优先拾取价值高的物品
valuable_items=sorted(itemskey=lambdax:x[2]reverse=True)
self.execute_action(ActionType.PICKvaluable_items[0][0:2])
else:
#没有物品可拾取,继续寻找怪物
self.current_state=GameState.BATTLE
elifself.current_state==GameState.RETURNING:
self.execute_action(ActionType.RETURN_TOWN)
#回城后执行卖物品和修理装备
ifself.inventory_percent>self.config["max_inventory_percent"]:
self.execute_action(ActionType.SELL_ITEMS)
#检查装备耐久度
ifself._need_repair():
self.execute_action(ActionType.REPAIR)
#补充药水
self._buy_potions()
#回到战斗区域
self._move_to_combat_area()
self.current_state=GameState.BATTLE
elifself.current_state==GameState.RESTING:
#休息恢复状态
time.sleep(5)
self.current_state=GameState.BATTLE
elifself.current_state==GameState.ERROR:
#错误处理
logger.error("脚本遇到错误,尝试恢复...")
time.sleep(5)
self.current_state=GameState.BATTLE
#添加随机延迟,避免行为过于规律
time.sleep(random.uniform(0.51.5))
exceptExceptionase:
logger.error(f"发生异常:{str(e)}")
self.current_state=GameState.ERROR
time.sleep(5)
def_move_to_random_location(self):
"""移动到随机位置"""
ifnotself.game_rect:
return
lefttopwidthheight=self.game_rect
#计算安全移动区域
move_area=(int(width*0.3)int(height*0.3)
int(width*0.4)int(height*0.4))
#随机选择目标位置
x=left+move_area[0]+random.randint(0move_area[2])
y=top+move_area[1]+random.randint(0move_area[3])
#模拟鼠标移动并点击地面
pyautogui.moveTo(xyduration=0.5+random.random())
pyautogui.rightClick()
logger.info(f"移动到位置:({x}{y})")
#等待角色移动
move_time=random.uniform(2.05.0)
time.sleep(move_time)
def_detect_items(self)->List[Tuple[intintint]]:
"""检测地面物品"""
#实际实现中使用图像识别检测物品
#返回值格式:[(x坐标y坐标价值)...]
return[
(random.randint(100500)random.randint(100400)random.randint(1100))
for_inrange(random.randint(03))
]
def_need_repair(self)->bool:
"""检查装备是否需要修理"""
#实际实现中使用图像识别检查装备耐久度
#简化示例
returnrandom.random()<0.3
def_buy_potions(self):
"""购买药水"""
logger.info("正在购买药水...")
#实现购买药水逻辑
time.sleep(3+random.random()*2)
def_move_to_combat_area(self):
"""移动到战斗区域"""
logger.info("正在前往战斗区域...")
#实现移动到预设战斗区域的逻辑
time.sleep(5+random.random()*3)
#脚本入口
if__name__=="__main__":
script=LegendAutoScript()
ifscript.initialize():
script.combat_loop()
```
####二、高级功能实现:智能战斗系统
在上一版基础脚本的基础上,我们实现了更高级的战斗系统,具有以下特性:
1.**状态机设计**:使用状态机管理不同游戏状态(战斗、拾取、回城等)
2.**怪物分类与优先级**:区分普通怪物、精英怪物和首领,设置不同的攻击策略
3.**技能系统**:根据怪物类型和角色状态智能选择技能
4.**背包管理**:自动回城卖物品,保持背包空间
5.**装备维护**:检测装备耐久度,自动修理装备
战斗系统的核心是根据不同怪物类型应用不同的战斗策略:
```python
#战斗策略配置
self.combat_strategies={
MonsterType.NORMAL:["basic_attack"]
MonsterType.ELITE:["basic_attack""skill1"]
MonsterType.BOSS:["basic_attack""skill1""skill2"]
}
#根据怪物类型选择合适的技能
monster_type=self.target_monster["type"]
skills=self.combat_strategies.get(monster_type["basic_attack"])
skill_key=self.config["skill_key_mapping"].get(skills[0]"space")
```
####三、图像识别优化:提高准确性与性能
为了提高脚本的稳定性和可靠性,我们可以采用以下图像识别优化技术:
1.**多分辨率模板匹配**:支持不同分辨率的游戏窗口
2.**特征点匹配**:使用ORB或SIFT特征点匹配,提高复杂场景下的识别率
3.**图像预处理**:灰度化、二值化、降噪等预处理技术
4.**置信度阈值自适应**:根据场景复杂度自动调整匹配阈值
以下是一个优化后的图像识别函数:
```python
deffind_template_on_screen(selftemplatethreshold=0.8use_feature_matching=False)->Optional[Tuple[intintfloat]]:
"""在屏幕上查找模板图像,支持特征点匹配"""
screen=self.capture_game_screen()
ifscreenisNone:
returnNone
screen_gray=cv2.cvtColor(screencv2.COLOR_BGR2GRAY)
ifuse_feature_matching:
#使用特征点匹配
orb=cv2.ORB_create()
kp1des1=orb.detectAndCompute(templateNone)
kp2des2=orb.detectAndCompute(screen_grayNone)
bf=cv2.BFMatcher(cv2.NORM_HAMMINGcrossCheck=True)
matches=bf.match(des1des2)
matches=sorted(matchesby=lambdax:x.distance)
iflen(matches)>10:#至少需要10个匹配点
src_pts=np.float32([kp1[m.queryIdx].ptforminmatches]).reshape(-112)
dst_pts=np.float32([kp2[m.trainIdx].ptforminmatches]).reshape(-112)
Mmask=cv2.findHomography(src_ptsdst_ptscv2.RANSAC5.0)
ifMisnotNone:
hw=template.shape
pts=np.float32([[00][0h-1][w-1h-1][w-10]]).reshape(-112)
dst=cv2.perspectiveTransform(ptsM)
#计算中心点
center_x=int(np.mean(dst[::0]))
center_y=int(np.mean(dst[::1]))
#计算匹配置信度
confidence=len(matches)/max(len(kp1)len(kp2))
return(center_xcenter_yconfidence)
returnNone
else:
#使用模板匹配
result=cv2.matchTemplate(screen_graytemplatecv2.TM_CCOEFF_NORMED)
min_valmax_valmin_locmax_loc=cv2.minMaxLoc(result)
ifmax_val>=threshold:
hw=template.shape
center_x=max_loc[0]+w//2
center_y=max_loc[1]+h//2
return(center_xcenter_ymax_val)
returnNone
```
####四、任务系统设计:实现自动化游戏流程
为了实现更复杂的游戏自动化功能,我们可以设计一个任务系统,使脚本能够按照预设流程完成一系列任务:
```python
classTask:
def__init__(selftask_typetarget=Noneparams=None):
self.task_type=task_type#任务类型:打怪、采集、任务等
self.target=target#任务目标:怪物ID、NPC位置等
self.params=paramsor{}#任务参数
self.status="pending"#任务状态:pendingrunningcompletedfailed
self.progress=0#任务进度
self.start_time=0#任务开始时间
self.end_time=0#任务结束时间
defupdate(selfscript):
"""更新任务状态"""
ifself.status=="pending":
self._start(script)
elifself.status=="running":
self._execute(script)
def_start(selfscript):
"""开始任务"""
self.status="running"
self.start_time=time.time()
logger.info(f"开始任务:{self.task_type}目标:{self.target}")
def_execute(selfscript):
"""执行任务逻辑,由子类实现"""
pass
defcomplete(self):
"""完成任务"""
self.status="completed"
self.end_time=time.time()
logger.info(f"任务完成:{self.task_type}耗时:{self.end_time-self.start_time:.2f}秒")
deffail(selfreason="未知原因"):
"""任务失败"""
self.status="failed"
self.end_time=time.time()
logger.info(f"任务失败:{self.task_type}原因:{reason}耗时:{self.end_time-self.start_time:.2f}秒")
classKillMonsterTask(Task):
def__init__(selfmonster_typecount=1):
super().__init__("kill_monster"monster_type{"count":count})
self.killed_count=0
def_execute(selfscript):
#检查是否达到目标数量
ifself.killed_count>=self.params["count"]:
self.complete()
return
#如果没有目标,寻找目标
ifnotscript.target_monsterorscript.target_monster["type"]!=self.target:
script._find_specific_monster(self.target)
return
#攻击目标
script.execute_action(ActionType.ATTACKscript.target_monster["location"])
#模拟击杀逻辑
ifrandom.random()<0.3:#假设30%的攻击能击杀怪物
self.killed_count+=1
self.progress=self.killed_count/self.params["count"]*100
logger.info(f"击杀怪物{self.target.name}进度:{self.killed_count}/{self.params['count']}")
#在脚本中添加任务管理功能
classLegendAutoScript:
def__init__(self):
#...已有代码...
#任务系统
self.current_task=None
self.tasks_queue=[]
defadd_task(selftask):
"""添加任务到队列"""
self.tasks_queue.append(task)
logger.info(f"添加任务到队列:{task.task_type}目标:{task.target}")
defprocess_tasks(self):
"""处理任务队列"""
ifself.current_taskisNoneandself.tasks_queue:
self.current_task=self.tasks_queue.pop(0)
ifself.current_task:
self.current_task.update(self)
ifself.current_task.statusin["completed""failed"]:
self.current_task=Noneifnotself.tasks_queueelseself.tasks_queue.pop(0)
```
####五、反检测技术:保持脚本使用安全
使用游戏辅助脚本存在被游戏检测的风险,以下是一些常用的反检测技术:
1.**操作随机化**:在鼠标移动、点击间隔、按键时间等加入随机变化
2.**行为模式多样化**:模拟人类玩家的不规则行为,避免固定模式
3.**响应延迟**:添加随机思考时间,模拟人类决策过程
4.**异常处理**:添加意外情况处理机制,如游戏掉线、UI变化等
5.**使用频率控制**:不要长时间连续运行脚本,适当休息
在我们的脚本中,已经实现了部分反检测措施:
```python
#添加随机延迟,模拟人类操作
delay=random.uniform(0.30.7)
time.sleep(delay)
#随机选择目标位置
x=left+move_area[0]+random.randint(0move_area[2])
y=top+move_area[1]+random.randint(0move_area[3])
#模拟鼠标移动曲线,更像人类操作
pyautogui.moveTo(xyduration=0.5+random.random())
```
####六、脚本部署与调试指南
1.**环境准备**
-安装Python3.7+
-安装必要的库:`pipinstallpyautoguiopencv-pythonnumpypywin32`
-准备模板图片:在项目目录下创建`items`和`monsters`文件夹,放入对应的模板图片
2.**配置调整**
-修改脚本中的游戏窗口标题,确保能正确找到游戏窗口
-根据自己的快捷键设置,调整技能键位映射
-根据游戏界面,调整血条、魔法条的识别区域
3.**调试技巧**
-使用日志系统查看脚本运行状态
-先在卸围内测试脚本功能,确保各部分正常工作
-使用截图功能保存游戏画面,便于分析识别问题
-逐步增加功能复杂度,不要一次性添加太多功能
4.**常见问题解决**
-脚本无法找到游戏窗口:检查窗口标题是否正确,确保游戏已启动
-图像识别不准确:调整模板图片质量,尝试不同的匹配阈值
-脚本操作无响应:检查游戏窗口是否被遮挡,是否有焦点
通过这些技术,你可以开发出一个功能强大、稳定可靠的复古传奇自动化脚本,帮助你更轻松地体验游戏。记住合理使用脚本,避免过度依赖,保持游戏的乐趣。

