-
Notifications
You must be signed in to change notification settings - Fork 38
小地图定位方式
DoctorReid edited this page Mar 22, 2024
·
10 revisions
整个脚本的基础能力,就是如何通过界面左上角的小地图,匹配大地图,获取角色当前所在的位置坐标,从而判断后续往哪个方向移动。
效果展示可以看 B站视频,目前整体定位方案(包含小地图处理)在充分缓存情况下,平均耗时 20ms
(AMD Ryzen 5 5600U + 16G内存)。
默认配置中 game_sample.yml 有一个截取小地图的定位配置 mini_map
。
用户可以进行重新校准,使用 calibrator._check_mini_map_pos
,可直接使用exe应用上的校准功能。
截取小地图后,我们需要在大地图上匹配小地图,了解小地图特征将有利于理解具体的定位算法。
- 基本格调为
黑白风
,在没有特殊点(传送点、商店等)的时候,整个图基本没有什么特征点可用。 - 道路颜色的RGB色值
接近
,例如当前楼层的道路颜色在(55,55,55)附近。 - 人物朝向是在小地图上加了一层
蓝色
的半透明雷达。 - 怪物的位置和朝向是在小地图上加了一个
红
点和一层红色
的半透明雷达。
经验证,人物在静止不动时,小地图的缩放比例是跟大地图的最小
缩放比例一样的;而人物在跑动时候,小地图会有一个渐变的缩小。
另外,大地图上,进行缩放后,传送点等的图标(特殊点)大小是不会改变的,而小地图因人物跑动而缩小时,传送点等的图标是会跟着缩小的。
因此,使用使用最小
缩放比例的大地图进行坐标判断是最方便的。
小地图部分,如果只是对大地图进行简单的截取展示,那匹配就简单很多了。可是事实上没这么简单,小地图上还有些其他元素:
- 中心代表人物的小箭头,以及代表人物朝向的浅蓝色扇型
- 非道路部分,使用透明的方式,展示了下面的游戏界面的图层
- 被怪物锁定时,小地图的红色色道有有所提高
了解上述小地图特征后,就可以理解怎么使用小地图匹配大地图了。
- 特征匹配 - 小地图有特殊点的情况,可以利用特殊点进行特征匹配。具体代码见
-
cal_pos.cal_character_pos_by_sp_result
- 根据特殊点在小地图和大地图上的位置,直接计算出人物坐标。
-
- 模板匹配 - 小地图没有特殊点的情况,可以使用模板匹配。具体代码见
-
cal_pos.cal_character_pos_by_road_mask
- 使用颜色扣取的道路掩码,使用黑白图所以匹配速度较快。 -
cal_pos.cal_character_pos_by_gray
- 使用小地图灰度图,在大地图上匹配,配合道路掩码,速度慢一点点,准确率会提高。 -
cal_pos.cal_character_pos_by_original
- 使用小地图原图直接在大地图上匹配,配合道路掩码,作为最后兜底。 -
mini_map.get_road_mask_for_world_patrol
- 道路掩码的获取代码。
-
两种匹配方式都会面临一个问题,就是大地图很大的时候,匹配效率会很慢,而且准确度会下降。
因此脚本中进行了如下的优化
- 假设所有指令都从某个传送点开始,且我们能事先知道传送点的落地坐标,即可记录第一个点(开始点)。
- 移动时,根据移动时间可以预估人物的移动距离,即可以预估当前坐标的一个范围。
- 使用预估的范围,进行大地图的截取,然后只在这一小部分的大地图上进行匹配,可以达到一个又快又准的效果。
- 移动途中持续记录坐标,保持使用小范围的大地图进行匹配。
- 人物朝向的蓝色雷达位置相对固定,可以通过与道路颜色的差值去除掉。
- 模板匹配时,需要使用多个缩放比例进行计算,这里可以并发进行。
- 匹配结果,可以用预估移动距离和人物朝向对结果校验,剔除一些偏移较远的结果。
- 匹配失败时,可以禁止人物疾跑,甚至停止人物移动,避免乱跑导致人物卡死。
模拟宇宙的地图有以下特征
- 没有普通的特殊点,只有事件的问号。
- 副本中地图都只是截取了大世界地图的一部分,且不会出现跨楼层。
基于以上特征,模拟宇宙中定位仅做了以下调整
- 模板匹配不能使用直接道路掩码匹配,因为这是不完整的,准确率很低。