Auto js编写微信小游戏 《一笔画完》 辅助工具--开发篇

前言:

1.开发工具:Auto js

2.平台:安卓6.0以上

3.开发语言 :javascript

效果演示:

这里附上效果展示视频:

开发步骤:

1.建模,将游戏环境转化为数据

2.使用算法,寻找路径

3.模拟屏幕点击,完成自动闯关

建模过程:

这里只说下思路,具体实现有很多的方法,需要大家自己去写。

1.先截取当前屏幕,如图一

图一

2.所有有用的地图信息都在图二中我用红框框出来的区域里面,所以第一步先把框框里面的图先截取出来

图二

3.截取后的图片如下图三所示:

图三

4.去掉四周多余的空白区域后,也就是最终的处理后的图片如图四:

图四

 

5.把图片转化为二维数组,可以走的地方值为1(灰色方块),不能走的地方值为0(白色的位置)

例如上面这幅地图转化为数组就是:

1 0 1 1 1 1

1 1 1 1 1 1

1 1 1 1 0 1

1 1 1 1 1 1 

0 1 1 0 1 1 

1 1 1 1 0 1

1 1 1 1 1 1

其中有一个特殊的点就是起点,起点位置需要单独记录下来,后面需要用到,并且规定起点位置的值为1。

路径算法:

思路:DFS搜索算法,从起点开始,对当前点的上下左右进行遍历,看该位置是否能够走,如果能就把该位置作为当前点,继续进行搜索,如果不能走就接着遍历,直到地图上所有能够走的地方都被走过了,此时代表你找到了一条一笔画完的路径,记录下该路径。

剪枝:开始没有意识到剪枝的重要性,就直接写的暴力搜索,这样的算法在电脑上面搜索没什么问题,但是换到手机上在地图比较大的时候就会比较卡,有时候需要计算1分钟才能找到路径,后来我就加了一个剪枝,速度马上就提上来了,一般都在3秒之内就能找到路径。

路径算法 代码如下:

//回溯法寻找路径
function backtrack(x,y)
{
    //如果该点无效  超出界限或者该处的值为0
    if(isValid(x,y)==false)
        return false;
	//记录该点被走过 所以该处的值为0
    tem[x][y]=0;
    
    //剪枝  如果出现这种情况 代表不可能走完,直接return 
    if(condition1())
    {
        return true;
    }
    
    //如果所有的格子都已经走过  代表找到路径
    if(over())
    {
        toast ("找到路径");
        //sleep(1000);
        for(var i=0;i<nx;i++)
            for(var j=0;j<ny;j++)
                act[i][j]=action[i][j];
        goByAct();  
        toast ("finished");
        //sleep (1000);
        exit ();
        return true;
    }
	
	//action记录路径  1代表往上 2-下  3-左 4-右
	//往上寻找
    action[x][y]=1;	
	if(backtrack(x,y-1))
	{
		tem[x][y-1]=1;	
    }
    //往下寻找
	action[x][y]=2;	
	if(backtrack(x,y+1))
	{
		tem[x][y+1]=1;
	}
	//往左寻找
	action[x][y]=3;	
	if(backtrack(x-1,y))
	{
		tem[x-1][y]=1;
	}
	//往右寻找
	action[x][y]=4;	
	if(backtrack(x+1,y))
	{
		tem[x+1][y]=1;
    }
	
	action[x][y]=0;
    return true;
}

屏幕点击:

计算出每个方块中心的坐标,利用刚才保存下来的路径,编写函数进行屏幕点击 。

源码:

这里给出源码,由于没有做手机适配,所以这个代码不能直接拿来就用,仅供参考学习。

//一些常用的颜色我要记录下来,利用图片进行获取
var img1=images.read("/sdcard/2.jpg");
var gray=img1.pixel(50,50);
var white=img1.pixel(120,120);
//var black=img1.pixel(23,348);

//获取地图  大致截取
function getMap()
{
    requestScreenCapture();
    var img = captureScreen();
    var tar=images.clip(img,5,575,1045,1120);
    x0p+=5;
    y0p+=575;
    return tar;
}
//消除空白边缘
function removeBack(tar)
{
    //转化图 片为数据
    var w=tar.getWidth();
    var h=tar.getHeight();
    var x1,x2,y1,y2;
    x1=y1=0;
    x2=w,y2=h;
    //上 y1改变
    while(1)
    {
        //灰色
        var point=findColor(tar,gray,{
            region:[0,y1,w,2],
            threshold:1
        });
        y1+=2;
        if(point)
            break;
    }
    //左 x1
    while(1)
    {
        var point=findColor(tar,gray,{
            region:[x1,0,2,h],
            threshold:1
        });
        x1+=2;
        if(point)
            break;
    }
    //右 x1
    while(1)
    {
        var point=findColor(tar,gray,{
            region:[x2-2,0,2,h],
            threshold:1
        });
        x2-=2;
        if(point)
            break;
    }
    //下 y2
    while(1)
    {
        var point=findColor(tar,gray,{
            region:[0,y2-2,w,2],
            threshold:1
        });
        y2-=2;
        if(point)
            break;
    }  
    x0p+=x1;
    y0p+=y1;
    return images.clip(tar,x1,y1,x2-x1,y2-y1);
}
//得到二维数组
function getData(img)
{
    //img 是边缘剪裁完毕后的图像
    var x=0,y=0;
    var w=img.getWidth();
    var h=img.getHeight();
    while(1)
    {
        //找灰色的点
        var point=findColor(img,gray,{
            region:[0,y,w,1],
            threshold:1
        });
        //如果没找到了
        if(!point)
            break;
        y+=1;
    }
    while(1)
    {
        //找灰色的点
        var point=findColor(img,gray,{
            region:[x,0,1,h],
            threshold:1
        });
        //如果没找到了 
        if(!point)
            break;
        x+=1;
    }
    dx=x;
    dy=y;
    //var space=0;
    while(1)
    {
        //找灰色的点
        var point=findColor(img,gray,{
            region:[x,0,1,h],
            threshold:1
        });
        //如果找到了
        if(point)
            break;
        x+=1;
    }
    space=x-dx;
    nx=parseInt(w/(dx+space))+1;
    ny=parseInt(h/(dy+space))+1;
    toast(nx+","+ny);
    sleep(1000);
    //画地图
    var arr=new Array();
    for(var i=0;i<nx;i++)
    {
        arr[i]=new Array();
        for(var j=0;j<ny;j++)
        {
            if(img.pixel(dx/2+i*(dx+space),dy/2+j*(dy+space))==gray)
            {
                arr[i][j]=1;
                //toast(dx/2+i*(dx+space)+","+(dy/2+j*(dy+space)));
            }
            else
            {
                //找起点
                if(img.pixel(dx/2+i*(dx+space),dy/2+j*(dy+space))==white)
                {
                    arr[i][j]=0;
                }
                else
                {
                    arr[i][j]=-1;
                    bx=i;
                    by=j;
                    //toast ("找到起点"+i+","+j);
                    //sleep (1000);
                }
                //toast(i+","+j);
            }   
            //sleep(1000);
        }
    }
    return arr;
}

function over()
{
    for(var i=0;i<nx;i++)
        for(var j=0;j<ny;j++)
            if(tem[i][j]==0)
                continue;
            else return false;
    return true;
}

function isValid(x,y)
{
    if(x<0||x>=nx||y<0||y>=ny)
        return false;
    if(tem[x][y]==0)
        return false;
    return true;
}

//如果这种情况出现就返回true   如果没出现就返回false
function condition1()
{
    var tarn=0;
    var n0=0;
    for(var i=0;i<nx;i++)
    {
       
        for(var j=0;j<ny;j++)
        {
            n0=0;
            if(tem[i][j]!=0)
            {
                if(!isValid(i-1,j))
                    n0++;
                if(!isValid(i+1,j))
                    n0++;
                if(!isValid(i,j-1))
                    n0++;
                if(!isValid(i,j+1))
                    n0++;
            }
            if(n0>=3)
                tarn++;
            if(tarn>=3)
                return true;
        }
        
    }
    return false;
}

function backtrack(x,y)
{

    //console.log("(%d,%d):%d",x,y,tem[x][y]);
    //sleep(1000);
    /*
    if(x<0||x>=nx||y<0||y>=ny)
        return false;

    if(tem[x][y]==0)
        return false;
    */
    //如果该点无效
    
    if(isValid(x,y)==false)
        return false;
    tem[x][y]=0;
    
    
    //如果这种情况出现 代表不可能走完,直接return
    if(condition1())
    {
        return true;
    }
    
    if(over())
    {
        toast ("找到路径");
        //sleep(1000);
        for(var i=0;i<nx;i++)
            for(var j=0;j<ny;j++)
                act[i][j]=action[i][j];
        
        goByAct();  
        toast ("end");
        //sleep (1000);
        exit ();
        return true;
    }
    //console.log("%d",tem[x][y]);
    action[x][y]=1;	
	if(backtrack(x,y-1))
	{
		tem[x][y-1]=1;	
	}
	action[x][y]=2;	
	if(backtrack(x,y+1))
	{
		tem[x][y+1]=1;
	}
	
	action[x][y]=3;	
	if(backtrack(x-1,y))
	{
		tem[x-1][y]=1;
	}
	action[x][y]=4;	
	if(backtrack(x+1,y))
	{
		tem[x+1][y]=1;
	}
	action[x][y]=0;
    return true;
}

function myclick(x,y)
{
    //console.log("点击:%d,%d",x,y);
    click(x0p+dx/2+x*(dx+space),y0p+dy/2+y*(dy+space));
    sleep(50);
}
function goByAct()
{
   //toast(act[bx][by]);
   var x=bx,y=by;
   while(act[x][y]!=0)
   {
       switch(act[x][y])
       {
            case 1:
            {
                y--;
                myclick(x,y);
            };break;
            case 2:
            {
                y++;
                myclick(x,y);
            };break;
            case 3:
            {
                x--;
                myclick(x,y);
            };break;
            case 4:
            {
                x++;
                myclick(x,y);
            };break;
            default:break;
       }
   }
}

//记录数组的宽度和开始坐标
var nx,ny,bx,by;
//记录左上角坐标
var x0p=0,y0p=0;
//记录格子的宽度和高度,以及中间的间隙
var dx,xy,space;
var img0=getMap();
var img=removeBack(img0);
var arr=getData(img);

var tem=new Array;//临时数组
var action=new Array;//行动路线
var act=new Array;

//init
for(var i=0;i<nx;i++)
{
	tem[i]=new Array;
	action[i]=new Array;
	act[i]=new Array;
	for(var j=0;j<ny;j++)
	{
		tem[i][j]=arr[i][j];
		action[i][j]=0;
		act[i][j]=0;
	}
}
//console.show();
toast ("找到起点("+bx+","+by+") 1秒后开始寻找路径");
sleep (1000);

backtrack(bx,by);
toast ("没找到");



写在最后:

至此,一笔画完的游戏辅助就写好了 。刚开始写博客,有不足的地方还请大家包涵,也请大家多给我提点意见,谢谢大家。

  • 5
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值