开启辅助访问 切换到宽版

精易论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

用微信号发送消息登录论坛

新人指南 邀请好友注册 - 我关注人的新帖 教你赚取精币 - 每日签到


求职/招聘- 论坛接单- 开发者大厅

论坛版规 总版规 - 建议/投诉 - 应聘版主 - 精华帖总集 积分说明 - 禁言标准 - 有奖举报

查看: 9948|回复: 16
收起左侧

[技术专题] 复古传奇实现动态泉水采集 工作室单机300的项目

[复制链接]
发表于 2019-6-9 22:44:56 | 显示全部楼层 |阅读模式   福建省福州市
大家好,我是隔壁小王,初来精易论坛,没有什么礼物给大家,以帖会友吧,给大家分享一个利用模拟器在传奇手游中寻找动态图的思路以及C#代码实现。希望能帮到小白了解一点思路,大神无视就好。

    这个游戏叫复古传奇,是一款手游,玩的大多是老玩家了。如图:,这个是游戏图标。

   
   这个游戏中有好几个地图有会随机出现动态泉水,如图:。红色框起来的就是泉水,这个泉水是一个动态图,一共18帧,不断变化。人物站在上面每够10S会采集一滴泉水,150滴泉水是一罐,一罐泉水可以卖2个元宝,至于元宝和RMB的换算,就不说了,传奇一般很统一,都是1:1.所以学会这个项目,能挣多少钱,大家自己算一算。这里我会详细把每一步的思路和代码都公开,不为赚钱,只为大家能够简单应付一下这类动态图的思路。
    我们要解决的问题有2个,首先要找到图,然后人物走到泉水上面开始采集。下面我们一步一步来分析思路:

    1.找泉水,我们可以通过一些第三方工具,也可以通过代码,把这个动态图全部分解为静态图,然后利用大漠中FindPic函数来找。这个比较简单相信大家都会。
  
    2.人物移动到泉水上,开始采集。这一步比较麻烦,因为我们用大漠找图算出来的坐标是屏幕坐标,但是地图中人物寻路实际用的是地图坐标,所以我们还要相应转化一下。不知道同学们有没有发现,传奇地图中的人物总是在屏幕最中间?那这样思路不就来了吗,因为模拟器窗口的大小是固定的,人物在窗口中间,那么人物的屏幕坐标也可以确定,利用大漠找图找到的泉水坐标也可以知道。然后我们可以计算出人物和泉水的横纵坐标之差,然后把这个坐标转化为地图坐标。(这个游戏左下角有人物的当前地图坐标,右上角有小地图可以寻路。)我们把人物的地图坐标加上我们算出来的偏差坐标,在小地图里输入,不就可以找到泉水并且走上去了吗。 小伙伴们是不是豁然开朗啊。
     
     做过脚本的同学看完以上几点,肯定会说,大漠找图不一定准啊,况且你找的图有18个,返回的坐标也不一定相同,那么我们计算偏差的时候按照哪个为准呢?一旦
FindPic返回的图片坐标不一样,那
么我们后面计算的话该用哪个?难道一直循环找图,然后每次返回的图片我们都计算一次,再控制人物移动?不,不,这样做的话就太Low了,而且是性能的极大浪费,等你最后精准的移动到泉水上面,说不定人家手动玩家早采集完了。小伙伴们别着急,我来慢慢给大家分析。

   
     歌德曾经说过:“人不光是靠他生来就拥有一切,而是靠他从学习中所得到的一切来造就自己。”我们学习编程也一样,要活学活用,技术层面上来说,我们已经实现了需求。但是仍有小小的瑕疵,这时候我们就需要用思维的层面来解决这个问题。在开发软件中,很多人是上来就写,尤其是新手,因为这样能感受到成就感。但是当你写的多了,就会慢慢养成设计先行的原则。就比如文中这个问题,可能新手上来就一顿代码写完了,但是最后却发现找图不准,怎么办?如果提前分析一下,找到技术的难点,逐个去分析解决,那么写起来代码是不是就容易多了呢。

      好了,人老了就爱话多,下面我们来解决这个问题。我们可以先设定一个list,里面存储FindPic找到的坐标,或者为了简单,我们可以在List里面存储每个泉水的屏幕坐标转化为地图的坐标。当我们在跑图过程中遇到泉水的时候,人物立马停下来,然后FindPic开始工作了,找到一个图,利用人物的屏幕坐标计算后,转化为泉水的地图坐标,存储到List里面,然后继续循环FindPic,然后再把一个泉水的地图坐标存储进去。然后当list里面的坐标数量达到5个(一般FindPic不可能找到每个静态图,所以我们一般不设定List的数量为18,经过本人测试,list设定为5就很准确了,可能别的游戏会要求存储个数多一点)时候,我们返回List里面出现次数最多的一个坐标;如果5个坐标都不一样,就返回list里面的第一个坐标;如果list里面的数量不到5个,那么循环20次FindPic,人物继续跑图。最后利用List返回的地图偏差坐标和人物的地图坐标进行加减运算后开始控制人物移动。人物移动之后,我们再开始循环找图,这样人物移动几次后,就稳稳的站到了泉水上。经过本人测试,最终的准确率在百分之90以上,对于用图色解决这个需求来说,已经很高了。
看看,是不是几次移动之后就准确的找到了呢!
  下面给大家发一下我的代码实现:
private void TestThread()
        {

            //游戏分辨率 1280 * 720
            //人物在画面中心坐标 640 * 360
            //坐标转换  经过测试 游戏里XY方向 移动1个坐标长度等于50像素   

            bool flag = true; //flag作为控制人物停下的变量

            double playerX = 640;
            double playerY = 360;
            int ret = qdm.DM.BindWindow(132802, "normal", "normal", "normal", 0);
            qdm.DM.SetPath("attachment");

            //这里进地图大家自己写,这个相信大家都没问题
            LoginMap();
            //在出现泉水的地图随机生成跑图点,也可以提前找几个固定点,循环着跑
            RoundCoordinate();
            //i控制findpic的循环次数
             int i = 0;
           //设置图片路径
            string path = "q_1.bmp|q_2.bmp|q_3.bmp|q_4.bmp|q_5.bmp|q_6.bmp|q_7.bmp|q_8.bmp|q_9.bmp|q_10.bmp|q_11.bmp|q_x.bmp|q_x1.bmp|q_x2.bmp|q_x3.bmp|q_x4.bmp|q_x5.bmp";
          //存储地图坐标的List

          List<string> dic = new List<string>();
            if (ret == 1)
            {
                object outX = 0;
                object outY = 0;
                double waterX = 0;
                double waterY = 0;
                double Xdic = 0;//横坐标的偏移
                double Ydic = 0;//纵坐标的偏移
                tab1:
                while(true)
                {
                    Thread.Sleep(10);

                    //这里人物找图范围缩小一点,利于提高找图速度
                    qdm.DM.FindPic(277, 137, 1142, 507, path, "303030", 0.9, 1, out outX, out outY);
                    if ((int)outX > 0)
                    {
                        // 人物停下
                        StopRun(flag);
                         waterX = (int)outX * 1.0 + 15;
                        waterY = (int)outY * 1.0 + 20;

                        double Xcut = (waterX - playerX) / 50;
                        double Ycut = (waterY - playerY) / 50;

                        Xdic = Math.Round(Xcut, 0);
                        Ydic = Math.Round(Ycut, 0);
                        dic.Add(Xdic+","+Ydic);
                        i += 1;
                        if(dic.Count==5)
                        {
                            i = 0;
                            break;
                        }
                        if(i==20)
                        {
                            //继续移动
                            SendScreenXY(895, 420);
                            flag = true;
                            i = 0;
                            goto tab1;
                        }
                      //  Debug.WriteLine("找到泉水距离人物:" + Xdic + "," + Ydic + "  泉水坐标:" + waterX + "," + waterY + " 偏移:" + Xcut + " ," + Ycut);
                    }
                }
                if(dic!=null)
                {

                  //返回List里面出现次数最多的一个坐标,如果都不一样就返回第一个
                    var res = dic.GroupBy(m => m).Where(n => n.Count() > 1).OrderByDescending(n => n.Count()).FirstOrDefault();
                    Debug.WriteLine( " 偏移:" + res.Key.Split(',')[0] + " ," + res.Key.Split(',')[1]);
                    //人物小地图移动,移动后清空list,从0开始计算循环次数,返回到找图循环里去

                   GoMap(res.Key.Split(',')[0],res.Key.Split(',')[1]);
                    dic.Clear();
                    i = 0;
                    goto tab1;
                }      
            }
        }

     





结帖率:0% (0/2)
发表于 2020-8-22 12:26:00 | 显示全部楼层   北京市北京市
如果有重叠或者遮挡还能识图识字吗?这种怎么解决...
回复 支持 反对

使用道具 举报

结帖率:0% (0/1)
发表于 2019-11-28 23:14:30 | 显示全部楼层   吉林省延边朝鲜族自治州
现在开发的怎么样了?
回复 支持 反对

使用道具 举报

结帖率:67% (6/9)
发表于 2019-8-20 10:48:06 | 显示全部楼层   上海市上海市
给楼主加鸡腿
回复 支持 反对

使用道具 举报

发表于 2019-8-4 13:39:24 | 显示全部楼层   江苏省徐州市
楼主你用的什么写的 完全看不懂啊  不是易语言
回复 支持 反对

使用道具 举报

结帖率:67% (6/9)
发表于 2019-7-11 17:09:56 | 显示全部楼层   广东省深圳市
thank you very much friend
回复 支持 反对

使用道具 举报

发表于 2019-7-1 13:22:38 | 显示全部楼层   山东省青岛市

谢谢大神分享~我是真的没看懂.
回复 支持 反对

使用道具 举报

发表于 2019-6-18 15:05:51 | 显示全部楼层   广东省深圳市
谢谢大神分享~
回复 支持 反对

使用道具 举报

发表于 2019-6-15 16:14:32 | 显示全部楼层   江苏省徐州市
牛皮给你个赞
回复 支持 反对

使用道具 举报

发表于 2019-6-12 22:27:17 | 显示全部楼层   湖北省武汉市
不明觉厉,当故事看
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-6-11 00:41:45 | 显示全部楼层   福建省福州市
1002457754 发表于 2019-6-10 17:58
呵呵,你自己写个完整的去试试,就知道啥效果了

算了,估计你就没看懂。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则 致发广告者

发布主题 收藏帖子 返回列表

sitemap| 易语言源码| 易语言教程| 易语言论坛| 易语言模块| 手机版| 广告投放| 精易论坛
拒绝任何人以任何形式在本论坛发表与中华人民共和国法律相抵触的言论,本站内容均为会员发表,并不代表精易立场!
论坛帖子内容仅用于技术交流学习和研究的目的,严禁用于非法目的,否则造成一切后果自负!如帖子内容侵害到你的权益,请联系我们!
防范网络诈骗,远离网络犯罪 违法和不良信息举报电话0663-3422125,QQ: 793400750,邮箱:wp@125.la
Powered by Discuz! X3.4 揭阳市揭东区精易科技有限公司 ( 粤ICP备12094385号-1) 粤公网安备 44522102000125 增值电信业务经营许可证 粤B2-20192173

快速回复 返回顶部 返回列表