开启辅助访问 切换到宽版

精易论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

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

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


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

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

查看: 43020|回复: 11
收起左侧

[C#图文教程] C#实现传奇复古手游之采集泉水 工作室单机日赚300项目 全面开源 只为大家学习

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

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

   
   这个游戏中有好几个地图有会随机出现动态泉水,如图: bb.png 。红色框起来的就是泉水,这个泉水是一个动态图,一共18帧,不断变化。人物站在上面每够10S会采集一滴泉水,150滴泉水是一罐,一罐泉水可以卖2个元宝,至于元宝和RMB的换算,就不说了,传奇一般很统一,都是1:1.所以学会这个项目,能挣多少钱,大家自己算一算。这里我会详细把每一步的思路和代码都公开,不为赚钱,只为大家能够简单应付一下这类动态图的思路。 dd.png
    我们要解决的问题有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以上,对于用图色解决这个需求来说,已经很高了。
ww.jpg 看看,是不是几次移动之后就准确的找到了呢!
  下面给大家发一下我的代码实现:
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;
                }      
            }
        }

     


-8f161d05d248dde.jpg
ww.png
ww.png

评分

参与人数 1好评 +1 精币 +2 收起 理由
陌小北 + 1 + 2 感谢分享,很给力!~

查看全部评分

发表于 2022-6-25 14:09:00 | 显示全部楼层   江苏省泰州市
感谢分享,很给力!~
回复 支持 反对

使用道具 举报

发表于 2022-6-25 13:53:39 | 显示全部楼层   山西省太原市
感谢分享
回复 支持 反对

使用道具 举报

结帖率:88% (14/16)

签到天数: 1 天

发表于 2022-6-25 02:42:03 | 显示全部楼层   北京市北京市
学习一下
回复 支持 反对

使用道具 举报

发表于 2022-6-19 11:05:25 | 显示全部楼层   广东省清远市
好复杂的样子
回复 支持 反对

使用道具 举报

发表于 2022-3-15 00:55:47 | 显示全部楼层   湖北省武汉市
思路很清晰哈
回复 支持 反对

使用道具 举报

发表于 2021-1-15 15:42:31 | 显示全部楼层   山东省淄博市
莫名其妙哈
回复 支持 反对

使用道具 举报

发表于 2019-9-26 22:44:32 | 显示全部楼层   江苏省无锡市
传奇定制版能做吗
回复 支持 反对

使用道具 举报

发表于 2019-8-22 23:55:43 | 显示全部楼层   河北省石家庄市
非常棒,学习一下,好东西
回复 支持 反对

使用道具 举报

结帖率:100% (2/2)
发表于 2019-6-9 10:59:43 高大上手机用户 | 显示全部楼层   广东省广州市
我也玩类似的传奇,不过我那个不能输入坐标自动寻路,完全是复活的,移动都要用摇杆移动,怪物也没名字,我到现在都不知道该怎么去实现自动打怪,又没有自动换怪,要鼠标点到怪或者点击一下技能才会随机显示一个最近的怪出来
回复 支持 反对

使用道具 举报

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

本版积分规则 致发广告者

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

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

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