您的位置:首页 > 编程语言 > C语言/C++

C++实现微信跳一跳辅助程序

2018-01-15 16:54 573 查看
     最近很火的微信小程序《跳一跳》,笔者我玩了一下,总是50以下得分,在好友圈里垫底,有点扎心,于是乎就发挥下程序员的力量。这款游戏,操作非常的简单,仅仅是按住屏幕一定时间后放开即可。
     也就是说,我们只要知道自己大概要按多长时间就好了,然后笔者本身是做Android开发,经常会用到adb进行调试机器。按压屏幕一定时间,我们在cmd中运行adb shell input swipe 1 1 1 1 1000就可以滑动屏幕1秒。实现按压屏幕1秒后弹起。
       现在我们的目标是计算按压时间t;
       先做一波测试,分别测试t1~tn的值时,能跳远距离,构造出时间与距离的方程。(距离用尺子量下就好了)
       来一组adb shell input swipe 1 1 1 1 tn,笔者发现时间与距离呈线性变化,于是笔者就简单的取了个比例,也可用回归方程计算出比较精确的比例系数。(笔者比较懒就算了)
        得出了一个方程 t = 189 * s/ 0.8   (笔者手机分辨率是1080*1920,红米2)
        接下来要测量s的值,那么s的值怎么来,自然就想到图像识别分析图像中心,想了下,还是算了。于是就采取屏幕采点的方式进行策略距离。
       


       根据我们初中学的勾股定理很容易计算出s = k * [(x1-x2)^2 + (y1-y2)^2] ^ 1/2,其中k是比例系数,那么坐标(x1,y1)和(x2,y2)怎么获得。很简单,鼠标左键点一下获得点(x1,y1),右键点一下获得(x2,y2)并开始运行。
         实际代码如何实现如下。
         预备工具:adb.exe,AdbWinApi.dll,AdbWinUsbApi.dll
         打开VS创建win32程序。
        新建头文件Jump.h
      
char const *const EXEC_HEAD = "adb shell input swipe 1 1 1 1 ";
char const *const SCREENCAP = "adb shell screencap -p /sdcard/jump_display.png";
char const *const PULL = "adb pull /sdcard/jump_display.png";
char const *const TAP = "adb shell input tap ";
class Jump
{
private:
int duration;
float distance;
int width;
int height;
public:
Jump();
~Jump();
void initPhysicalSize();
void exec();
void calculateDistance(float d);
void calculateDuration();
void screencap();
void loadimage();
int getWidth();
int getHeight();
void clickScreen(int w, int h);
}

       新建C++文件Jump.cpp

#define _CRT_SECURE_NO_WARNINGS

#include "Jump.h"
#include <iostream>
#include <string>
#include <cstdlib>
#include <sstream>
#include <fstream>

using namespace std;

Jump::Jump()
{
system("adb start-server");
distance = 3.0;
}

void Jump::initPhysicalSize()
{
system("adb shell wm size > size.txt");
ifstream iss("size.txt");
char size[10];
if(!iss.is_open()) return;
iss.seekg(15);
if(!iss.eof())
{
iss.get(size,10);
}
iss.close();
const char * split = "x";
char *p;

p = strtok(size,split);
int w_len = strle
4000
n(p);
width = 0;
for(int index = 0; index < w_len; index ++)
{
width = width + pow(10,w_len - index - 1) * (int)(p[index]-48);
}

p = strtok(NULL,split);
int h_len = strlen(p);
height = 0;
for(int index = 0; index < h_len; index ++)
{
height = height + pow(10,h_len-index - 1) * (int)(p[index]-48);
}
}

void Jump::calculateDistance(float d)
{
distance = d;
}

void Jump::calculateDuration()
{
duration = (int)(189 * 1.0 * distance / 0.8);
}

void Jump::exec()
{
ostringstream oss;
oss << EXEC_HEAD << duration;
system(oss.str().c_str());
}

void Jump::screencap()
{
system(SCREENCAP);
}

void Jump::loadimage()
{
system(PULL);
}

int Jump::getWidth()
{
return width;
}

int Jump::getHeight()
{
return height;
}

void Jump::clickScreen(int w, int h)
{
ostringstream oss;
oss << TAP << w << " " << h;
system(oss.str().c_str());
}

Jump::~Jump()
{
}


      接下来窗体主函数Main.cpp
 

#include <iostream>
#include <windows.h>
#include <gdiplus.h>
#pragma comment(lib,"Gdiplus.lib")
#include "Jump.h"

using namespace Gdiplus;
using namespace DllExports;
using namespace std;

LRESULT CALLBACK WinProc
{
HWND hwnd;
UINT uMsg;
WPARAM wParam;
LPARAM lParam;
};

HDC hdc;
HDC hdcmem;
HBITMAP hBm;
ULONG_PTR gdipid;
SIZE sBmp;
SIZE size_bmp;
GdiplusStartupInput gsi;
GdiplusStartupOutput gso;
GpBitmap *gbmp;
Bitmap *bmp;
Jump jump;

float x_po1, y_po1, x_po2, y_po2;
HANDLE execThread;

HWDN mhwnd;
int WIDTH_W;
int HEIGHT_W;

int WINAPI(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nShowCmd)
{
jump.initPhysicalSize();
WIDTH_W = jump.getWidth() / 4;
HEIGHT_W = jump.getHeight() / 4;

//init window
WNDCALSS wndclass;
wndclass.cbClsExtra = 0;
wndclass.cbWmdExtre = 0;
wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wndclass.hCursor = LoadCurosr(hInstance, MAKEINTRESOURCE(IDC_HELP));
wndclass.hIcon = LoadIcon(hInstance,MAKEINTRESOURCE(IDI_APPLICATION));
wndclass.hInstance = hInstance;
wndclass.lpfnWndProc = WinProc;
wndclass.lpszClassName = "跳一跳";
wndclass.lpszMenuName = NULL;
wndclass.style = CS_HREDRAM | CS_VREDRAW;

//register
RegisterClass(&wndclass);

//create window
mhwnd = CreateWindow("跳一跳","跳一跳",WS_OVERLAPPENDWINDOW | WS_MAXSIZE,
CW_USERDEFAULT,CW_USERDEFAULT,WIDTH_W + 17, HEIGHT + 40,NULL,NULL,hInstance,NULL);
ShowWindow(mhwnd,SW_SHOWNORMAL);
UpdateWindow(mhwnd);

//loop
MSG msg;
while(GetMessage(&ms, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}

DWORD WINAPI ExecThread(LPVOID lpParamter)
{
jump.calculateDistance(pow((x_po2 - x_po1)*(x_po2 - x_po1) + (y_po2 - y_po1)*(y_po2 - y_po1), 0.5) / 43.8);
jump.calculateDuration();
jump.exec();
Sleep(1000);  jump.screencap();
  jump.loadimage();
 
  bmp = Bitmap::FromFile(L"jump_display.png", 0);
  size_bmp.cx = bmp->GetWidth();
  size_bmp.cy = bmp->GetHeight();
  bmp->GetHBITMAP(0, &hBm);
  delete bmp;
  InvalidateRect(mhwnd, NULL, NULL);
return 0;
}

LRESULT CALLBACK WinProc(
HWND hwnd;
UINT uMsg;
WPARAM wParam;
LPARAM lParam;
)
{
PAINTSTRUCT ps;

switch(uMsg)
{
case WM_CREATE:
hdc = GetDC(hwnd);
hdcmem = CreateCompatibleDC(hdc);
ReleaseDC(hwnd,hdc);

jump.screencap();
jump.loadimage();

GdiplusStartup(&gdipid,&gsi,&gso);
GdipCreateBitmapFromFile(L"jump_display.png",&gbmp);
GdipGetImageWidth((GpImage*)gbmp,LPUINT(sBmp.cx));
GdipGetImageHeight((GpImage*)gbmp,LPUINT(sBmp.cy));
GdipCreateHBITMAPFromBitmap(gbmp,&hBm,0);
GdipDisposeImage((GpImage*)gbmp);
bmp = Bitmap::FromFile(L"jump_display.png",0);
size_bmp.cx = bmp->GetWidth();
size_bmp.cy = bmp->GetHeight();
bmp->GetHBITMAP(0,&hBm);
delete bmp;
break;

case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);
SelectObject(hdcmem,hBm);
SetStretchBltMode(hdc,HALFTONE);
StretchBlt(hdc,0,0,WIDTH_W,HEIGHT_W,hdcmem,0,0,size_bmp.cx,size_bmp.cy,SRCCOPY|SRCERASE);
EndPaint(hwnd,&ps);
DeleteObject(hBm);
break;

case WM_LBUTTONDOWN:
x_po1 = LOWORD(lParam);
y_po1 = HIWORD(lParam);
break;
case WM_RBUTTONDOWN:
x_po2 = LOWORD(lParam);
y_po2 = HIWORD(lParam);

execThread = CreateThread(NULL, 0, ExecThread, NULL, 0, NULL);
CloseHandle(execThread);
break;
case WM_CLOSE;
if(IDYES == MessageBox(hwnd,"不玩了吗?", "跳一跳",MB_YESNO))
{
DestroyWindow(hwnd);
}
break;
case WM_DESTORY:
GdiplusShutdonw(gdipid);
PostQuitMessage(0);
break;
default :
return DefWindowProc(hwnd,uMsg,wParam,lParam);
}
return 0;
}

     操作方式,打开跳一跳游戏--->点击开始游戏--->打开程序--->左键选择起点坐标--->右键选择终点坐标并运行,loop。
代码写的很随意,可能比例系数会不一样。

       
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: