windows下C语言实现自动版跳一跳详细教程

 最近的微信小游戏跳一跳很火热,朋友圈很多人都上千分,自己也想着搞个辅助玩一玩,然后看了网上的很多辅助教程,但是大都是python写的代码,python好处很多,但是要下载很多依赖库,很多库又是国外的,无法下载,要运行起来就有很多困难,于是就想写一个C语言版本的辅助,这里参考了wangshub大神的python代码,链接:https://github.com/wangshub/wechat_jump_game。

一、实现原理:

 跳一跳通过控制触摸屏幕的时间来控制棋子的跳跃距离,我们想让它自动跳,第一个需要解决的问题就是如何用电脑控制手机,adb工具就可以用于控制安卓手机,http://adbdriver.com/downloads/,(adb驱动)下载安装好后,将手机插上电脑,打开usb调试,打开电脑设备管理器如下图所示即安装完成。


安装完成后,需要下载adb工具才行,下载链接http://download.csdn.net/download/u014783685/10238837,下载后解压
,将解压后的文件夹目录加入到环境变量path中,打开cmd窗口,输入adb devices查看手机设备,如下图所示:

 这个时候就可以通过命令来控制手机了,比如截图命令adb shell screencap -p /sdcard/screen.png,将截图上传到电脑:adb pull /sdcard/screen.png,点击屏幕的命令adb shell input swipe start_x start_y end_x end_y time_ms,还有很多adb命令,网上有,这里就不一一例举了。 第二个需要解决的问题是如何计算棋子跳到下一个棋盘需要的时间,这个时间和棋子到下一个棋盘的距离有一定的关系,t = s * x,x就是这个系数,范围大概在1.3到1.4,可根据实际情况调节,现在的问题就是计算棋子到下一个棋盘的距离,也就是下图黑线段的距离(像素):

































计算这个距离需要知道两个端点的坐标,通过直角三角形算出黑线的长度,如何计算两点坐标呢,棋子的坐标
是最容易计算的,通过RGB比较颜色来判断是否是棋子,因为其它任何地方的颜色不会和棋子颜色一致,从底部
往上扫描,如果遇到棋子颜色,那么记录改点,然后从该行最右边开始扫描,扫描到棋子颜色记录改点,这两个
点的中点就是棋子的X坐标,Y坐标再向上移动20(分辨率1920*1080)即可得到棋子的Y坐标,计算下一个棋盘
的中点可以直接从上开始往下扫描,扫描到的第一个不同于背景色的点即为棋盘的左顶点,然后从该行的最右边
开始扫描得到第一个不同于背景色的点即为右顶点,这两个点的x坐标值的中点即为棋盘中点的x坐标,y值记录下来
然后从y-273的地方开始向上扫描,扫描到的第一个和顶点颜色值相同的点,改点和记录的y值的中点坐标即为最终
的棋盘Y坐标,这时即可通过勾股定理来计算距离。

二、代码实现:
#include <atlimage.h>
#include <math.h>
#include <stdio.h>
#include <graphics.h>


#define FILE_SIZE 1024*1024*8
unsigned char buff[FILE_SIZE];//bmp图片数据
DWORD* pMem; //绘图内存 easyx
int z_x=10, z_y=10, q_x=10, q_y=10;/*终点x,y,起点(棋子)x,y*/


typedef struct color //32位位图 BGRA A:亮度
{
unsigned char B;
unsigned char G;
unsigned char R;
unsigned char A;
}COLOR;
COLOR back;


void getcolorbypoint(int x, int y, COLOR *color)
{
//printf("%d %d\n",x,y);
if(x<0 || y<0)
{
x = y = 0;
}
int lable = 54 + 1080 * 4 * y + x * 4;
//printf("lable=%d\n",lable);
color->B = buff[lable];
color->G = buff[lable+1];
color->R = buff[lable+2];
color->A = buff[lable+3];
}


void setpoint(int x, int y, unsigned char R, unsigned char G, unsigned char B)
{
int lable = 54 + 1080 * 4 * y + x * 4;
buff[lable] = B;
buff[lable+1] = G;
buff[lable+2] = R;
}


//画像素点
void putpoint(int x,int y,unsigned char R,unsigned char G,unsigned char B)
{
int _x = 360 - x;
int _y = 640 - y;
if(x<0 || y<0 || _x<0 || _y<0)
{
_x = 0;
_y = 0;
}
//printf("%d %d %d %d\n",x,y,_x,_y);
pMem[360*_y-_x] = BGR(RGB(R,G,B));
}


int getdistance()/*获取起点到终点的距离,单位为像素*/
{
COLOR color1,color2;
/*查找起点(棋子)坐标*/
/*直接通过RGB颜色比较来确定棋子的位置*/
int x1=0,x2=0;
for (int x = 0, y = 500; ; x++)
{
getcolorbypoint(x, y, &color2);
int t = 10;
if ((abs(color2.R - 54)<t) && (abs(color2.G - 58)<t) && (abs(color2.B - 99)<t))
{
x1 = x;
for (int i = 1079; ; i--)
{
getcolorbypoint(i, y, &color2);
if ((abs(color2.R - 54)<t) && (abs(color2.G - 58)<t) && (abs(color2.B - 99)<t))
{
x2 = i;
break;
}
}
q_x = (x1 + x2) / 2; /*起点坐标*/
q_y = y + 20;
break;
}
if ((x % 1080) == 0)
{
x = 0;
y++;
}
}


/*查找终点X坐标*/
/*从上到下第一个不同于背景色的像素点就是终点的x坐标*/
int y1=0;
getcolorbypoint(0, 1440, &color1);
int start_x,end_x,start_y,end_y;
start_x = (q_x < 540) ? q_x+35 : 1;
end_x = (q_x < 540) ? 1000 : q_x-35;
start_y = q_y;
end_y = 1440;


for(int i=start_x;i<end_x;i++)
putpoint(i/3,start_y/3,0,0,0);
for(int i=start_x;i<end_x;i++)
putpoint(i/3,end_y/3,0,0,0);


for(int i=start_y;i<end_y;i++)
putpoint(start_x/3,i/3,0,0,0);
for(int i=start_y;i<end_y;i++)
putpoint(end_x/3,i/3,0,0,0);


for(int y=1440; y>q_y; y--)
{
/*解决棋子高于下一个棋盘的问题*/
for (int x = (q_x < 540) ? q_x+35 : 1; x<((q_x < 540) ? 1000 : q_x-35); x++)
{
getcolorbypoint(x, y, &color2);
int t = 10;
if ((abs(color2.R - color1.R)>t) || (abs(color2.G - color1.G)>t) || (abs(color2.B - color1.B)>t))
{
x1 = x;
for (int i = end_x; ; i--)
{
getcolorbypoint(i, y, &color2);
if ((abs(color2.R - color1.R)>t) || (abs(color2.G - color1.G)>t) || (abs(color2.B - color1.B)>t))
{
x2 = i;
break;
}
}
y1 = y;
goto yy;
}
}
}


yy:
z_x = ((x1 + x2) / 2);


for(int i=0;i<10;i++)
putpoint(x1/3,y1/3-5+i,0,0,0);
for(int i=0;i<10;i++)
putpoint(x2/3,y1/3-5+i,0,0,0);


/*查找终点Y坐标*/
/*从最高点-274往上查找与最高点颜色接近的点,两点的中点即为终点y坐标*/
getcolorbypoint(z_x, y1, &color1);
int y2 = y1;
int y=0;
for (y=y1-274; y<y1 ; y++)
{
getcolorbypoint(z_x, y, &color2);
int t = 10;

if ((abs(color2.R - color1.R)<t) && (abs(color2.G - color1.G)<t) && (abs(color2.B - color1.B)<t))
{
break;
}
}
z_y = (y + y2) / 2;


int distance = (int)sqrt((double)(abs(z_x - q_x)*abs(z_x - q_x) + abs(z_y - q_y)*abs(z_y - q_y)));/*勾股定理*/


return distance;
}


int main()
{
FILE *fimage;
CImage Image;
COLOR color;


initgraph(360, 640);


RECT r = {0, 0, 360, 640};
drawtext(_T("开始"), &r, DT_CENTER | DT_VCENTER | DT_SINGLELINE);


/*等待鼠标点击*/
MOUSEMSG m;
while(!MouseHit())
{
m = GetMouseMsg();
if(m.uMsg == WM_LBUTTONDOWN)
break;
}
drawtext(_T("初始化....."), &r, DT_CENTER | DT_VCENTER | DT_SINGLELINE);


/*获取显存指针*/
pMem = GetImageBuffer();


while (1)
{
system("adb shell screencap -p /sdcard/screen.png");
system("adb pull /sdcard/screen.png");


Image.Load(L"screen.png");
Image.Save(L"screen.bmp");
Image.Destroy();


fimage = fopen("screen.bmp", "rb+");//二进制打开
int n = fread(buff, 1, FILE_SIZE, fimage);
fclose(fimage);
getcolorbypoint(0, 1440, &back);


/*将图片的横纵坐标缩小三倍放入显存*/
for(int y=0,y1=639;y<1920;y+=3,y1--)
{
for(int x=0,x1=0;x<1080;x+=3,x1++)
{
getcolorbypoint(x,y,&color);
pMem[y1*360+x1] = BGR(RGB(color.R,color.G,color.B));
}
}


/*获取起点和终点的距离*/
int distance = getdistance();


/*画出起点和终点的坐标 十字形状*/
for(int i=0;i<20;i++)
putpoint(z_x/3-10+i,z_y/3,0,0,0);
for(int i=0;i<20;i++)
putpoint(z_x/3,z_y/3-10+i,0,0,0);
for(int i=0;i<20;i++)
putpoint(q_x/3-10+i,q_y/3,0,0,0);
for(int i=0;i<20;i++)
putpoint(q_x/3,q_y/3-10+i,0,0,0);


/*更新pMem显存*/
FlushBatchDraw();
//while(1);
/*点击屏幕 点击位置随机*/
char cmd[100];
int touchX = rand() % 80 + 200; // 200-279
         int touchY = rand() % 85 + 300; // 300-384
sprintf(cmd, "adb shell input swipe %d %d %d %d %d", touchX,touchY,touchX+5,touchY,(int)(distance*1.392));
system(cmd);
Sleep(1200);
}
return 0;
}

代码中使用了easyx图形库,关于该库的资料请访问easyx官网:http://www.easyx.cn/

编译好的exe文件:http://download.csdn.net/download/u014783685/10238901

使用方法,安装好adb驱动,设置环境变量,打开跳一跳游戏界面,打开tiaoyitiao.exe,点击开始即可自动运行。

 























  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值