国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - C# - C#實現微信跳一跳小游戲的自動跳躍助手開發實戰

C#實現微信跳一跳小游戲的自動跳躍助手開發實戰

2022-02-17 16:11Kingthy C#

前段時間微信更新了新版本后,帶來的一款H5小游戲“跳一跳”在各朋友圈里又火了起來,類似以前的“打飛機”游戲,這游戲玩法簡單,但加上了積分排名功能后,卻成了“裝逼”的地方,于是很多人花錢花時間的刷積分搶排名

一、前言:

前段時間微信更新了新版本后,帶來的一款h5小游戲“跳一跳”在各朋友圈里又火了起來,類似以前的“打飛機”游戲,這游戲玩法簡單,但加上了積分排名功能后,卻成了“裝逼”的地方,于是很多人花錢花時間的刷積分搶排名。后來越來越多的聰明的“程序哥們”弄出了不同方式不同花樣的跳一跳助手(外掛?),有用js實現的、有java實現的、有python實現的,有直接物理模式的、有機械化的、有量尺子的等等,簡直是百花齊放啊……

趕一下潮流,剛好有點時間,于是花了一個下午時間,我也弄了一個c#版本的簡單實現。

C#實現微信跳一跳小游戲的自動跳躍助手開發實戰

二、實現:

簡單的實現流程: 連接手機 -> 獲取跳一跳游戲界面 -> 獲取位置(棋子位置和要跳躍的落腳點位置) -> 點擊棋子跳躍

1、連接手機

電腦要連接并操作安卓手機,一般是通過adb協議連接手機并進行操作。連接手機前要求手機已開啟usb調試模式,可通過usb線或者tcp方式連接手機。正常只要電腦安裝了adb sdk tools之類的工具包,就會自帶有adb命令,所以c#要能操作手機,簡單實現就是直接利用現成的adb命令。

手機通過usb線接入電腦后,在cmd窗口輸入以下adb devices命令,如果顯示有device列表則表示手機已連接成功可以對手機進行操作了。

?
1
2
3
c:\users\k>adb devices
list of devices attached
e832acb device

2、獲取游戲界面

獲取手機界面的截圖可通過以下adb命令獲取:

?
1
adb shell screencap -p [filename]

參數 :

- p 表示截圖保存格式為png圖像格式。

filename: 截圖保存的路徑地址(手機路徑),如果不輸入則將截圖數據直接輸出到當前控制臺會話,否則會將截圖保存到相關路徑地址(必須有寫權限)

為避免文件保存到手機后還要再執行adb pull(拉文件到本地電腦)的操作,所以選擇不帶filename參數的命令。在c#代碼里通過process這個類進行adb命令的調用執行,實現代碼如下:

?
1
2
3
4
5
6
7
8
9
var startinfo = new processstartinfo("adb", "shell screencap -p");
startinfo.createnowindow = true;
startinfo.errordialog = true;
startinfo.redirectstandardoutput = true;
startinfo.useshellexecute = false;
var process = process.start(startinfo);
process.start();
var memostream = new memorystream();
process.standardoutput.basestream.copyto(memostream);

但由于adb client的原因,在它輸出的截圖數據流中會對'\n'(0a)這個字符替換為''\r\n'(0d0a)這兩個字符,并且在測試中還發現不同的手機替換次數還不相同的,有可能替換一次,也有可能替換二次!所以為解決這個問題,先計算在最開始的10字節里的數據出現了多少次'\r'(0d)字符后再出現‘\n'(0a)字符,因為正常的png文件,在文件頭的第4,第5個字節位置里會有'\r\n'(0d0a)標志,所以檢查出來的出現次數就表示'\n'(0a)被adb client替換了多少次,之后再對整個接收到的數據流進行'\n'(0a)還原(刪除無用的'\r'(0d)字符)。

>>統計'\n'被替換了次

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
private static int find0dcount(memorystream stream)
{
int count = 0;
stream.position = 0;
while(stream.position < 10 && stream.position < stream.length)
{
int b = stream.readbyte();
if(b == '\r')
{
 count++;
}
else if(b == '\n')
{
 return count;
}else if(count > 0)
{
 count = 0;
}
}
return 0;
}

>>對接受到的截圖數據流進行'\n'字符還原            

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
var count = find0dcount(memostream);
var newstream = new memorystream();
memostream.position = 0;
while (memostream.position != memostream.length)
{
 var b = memostream.readbyte();
 if (b == '\r')
 {
 int c = 1;
 var b1 = memostream.readbyte();
 while(b1 == '\r' && memostream.position != memostream.length)
 {
 c++;
 b1 = memostream.readbyte();
 }
 if(b1 == '\n')
 {
 if(c == count)
 {
 newstream.writebyte((byte)'\r');
 }
 newstream.writebyte((byte)b1);
 }
 else
 {
 for(int i=0; i<c; i++) newstream.writebyte((byte)'\r');
 newstream.writebyte((byte)b1);
 }
 }
 else {
 newstream.writebyte((byte)b);
 }
}
return new bitmap(newstream);

3、獲取棋子與跳躍落腳點位置

將獲取到的手機界面截圖顯示到軟件窗體上的picturebox控件上,可用鼠標的左右鍵分別點擊圖片位置標示棋子位置和需要跳的落腳點位置,鼠標點擊的坐標位置即表示手機界面的坐標位置。由于手機界面截圖在picturebox控件顯示時為了能一屏全圖顯示,對圖片做了縮放處理,且圖片縮放后如果圖片的寬度小于picturebox控件的寬度,picturebox會將圖片居中后顯示。所以鼠標點擊的坐標位置還需要進行坐標轉換才可以映射為手機界面里的絕對坐標位置。

轉換計算方法:先計算picturebox控件的圖片縮放值和圖片顯示的左邊距,然后再對鼠標點擊坐標進行縮放計算。代碼如下:      

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
private point calpoint(point p)
 {
 if (this.cbzoom.checked && this.picturebox1.image != null)
 {
 var zoom = (double)this.picturebox1.height / this.picturebox1.image.height;
 var width = (int)(this.picturebox1.image.width * zoom);
 var left = this.picturebox1.width / 2 - width / 2;
 return new point((int)((p.x - left) / zoom), (int)(p.y / zoom));
 }
 else
 {
 return p;
 }
 }

如全靠手動鼠標點擊坐標位置來玩游戲,這和直接在手機里手動玩游戲是沒有什么區別的,區別只在于能夠跳躍精準些(跳躍力度能自動計算出,下面會講),所以程序還要能夠實現自動化,就是要能夠自動找出棋子與跳躍落腳點的位置。

a、找棋子的坐標位置

棋子的位置非常的好找,對游戲界面里的棋子(圖2黃色塊)進行放大可以發現棋子底部有一塊區域(圖3白色塊)的顏色值是固定的r(54)g(60)b(102)顏色,如下兩圖:

C#實現微信跳一跳小游戲的自動跳躍助手開發實戰

(圖2)

C#實現微信跳一跳小游戲的自動跳躍助手開發實戰

(圖3)

根據棋子的這一顏色特點在獲取到手機界面截圖時,對圖片象素進行掃描,查找r(54)g(60)b(102)這一顏色,找到的坐標位置就是棋子的位置。為了能快速掃描圖片,不采用效率較低下的getpixel方法獲取顏色值,而采用lockbits方法鎖定圖片數據到內存,再采用指針移動獲取象素顏色,由于采用了指針,代碼需要開啟unsafe定義。且棋子正常情況下不會在最頂部和最底部出現,所以不需要對整張界面圖片掃描,只掃描20%-63%區域的數據,并且從底部開始找起。

b、找跳躍的落腳點位置

寫此助手只是無聊時的產出物,所以我只是簡單實現。游戲中如果連續跳到了目標物的中間位置時,新目標物的中間部分會出現一個白色圈(如上圖2的紅色塊),如果再跳中此位置,會進行加分。根據這一特點,程序找出那一白色圈圈的位置即可做為落腳點位置,白色圈的顏色值為r(254)g(254)b(254),如果沒有此白色圈位置,則手動鼠標選擇落腳點位置。實現此功能后,程序基本上也能實現90%左右的自動化跳躍了。

查找代碼實現如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
private static point findpointimpl(bitmap bitmap, out point combopoint)
 {
 var standpcolor = color.fromargb(54, 60, 102);
 var combopcolor = color.fromargb(245, 245, 245);
 
 point standpoint = point.empty;
 combopoint = point.empty;
 
 int y1 = (int)(bitmap.height * 0.2);
 int y2 = (int)(bitmap.height * 0.63);
 
 pixelformat pf = pixelformat.format24bpprgb;
 
 bitmapdata bitmapdata = bitmap.lockbits(new rectangle(0, y1, bitmap.width, y2), imagelockmode.readonly, pf);
 try
 {
 unsafe
 {
  int w = 0;
  while (y2 > y1)
  {
  byte* p = (byte*)bitmapdata.scan0 + (y2 - y1 - 1) * bitmapdata.stride;
  w = bitmap.width;
  int endcolorcount = 0;
  while (w > 40)
  {
  iccolor* pc = (iccolor*)(p + w * 3);
  if (standpoint == point.empty &&
  pc->r == standpcolor.r && pc->g == standpcolor.g && pc->b == standpcolor.b)
  {
  standpoint = new point(w - 3, y2);
  if (combopoint != point.empty) break;
  }
  else if (combopoint == point.empty)
  {
  if (pc->r == combopcolor.r && pc->g == combopcolor.g && pc->b == combopcolor.b)
  {
   endcolorcount++;
  }
  else
  {
   if (endcolorcount > 0)
   {
   combopoint = new point(w + 5, y2 - 1);
   if (standpoint != point.empty) break;
   }
   endcolorcount = 0;
  }
  }
  w--;
  }
  if (combopoint == point.empty)
  {
  if (endcolorcount > 10)
  {
  combopoint = new point(w + 5, y2 - 1);
  }
  }
  if (standpoint != point.empty && combopoint != point.empty) break;
  y2--;
  }
 }
 return standpoint;
 }
 finally
 {
 bitmap.unlockbits(bitmapdata);
 }
 }

4、棋子跳躍

要能跳躍,首先需要知道一個蓄力時間,就是按住棋子多久的時間,此蓄力時間的計算公式如下:

蓄力時間 = 距離 * 力度系數

“距離”就是棋子位置與跳躍落腳點位置的距離,根據上面的方法得出這兩個位置的坐標點后,根據直角三角形的勾股定理即可求出,代碼如下:      

?
1
2
3
4
5
6
7
8
9
10
public double distance
{
get
{
if (!this.cando) return -1;
int w = math.abs(this.p2.x - this.p1.x);
int h = math.abs(this.p2.y - this.p1.y);
return math.sqrt((double)(w * w) + (h * h));
}
}

“力度系數”  是一個常量值,具體怎么定義沒去細查,我采用的計算公式是: “力度系數 = 1495 / 手機分辨率的寬度值”, 如我的手機分辨率是1080*1920,則力度系數就是 1495 / 1080 = 1.3842....

算出了蓄力時間后通過以下adb命令發送到手機即可模擬點擊操作。

?
1
adb shell input swipe <x1> <y1> <x2> <y2> [duration(ms)]

x1, y1 就是棋子的坐標位置

x2, y2 還是棋子的坐標位置

duration 蓄力時間值,由距離*力度系數得出。

代碼如下:   

?
1
2
3
4
5
6
7
8
9
10
public bool do()
{
if (!this.cando) return false;
var startinfo = new processstartinfo("adb", string.format("shell input swipe {0} {1} {0} {1} {2}", this.p1.x, this.p1.y, this.time));
startinfo.createnowindow = true;
startinfo.errordialog = true;
startinfo.useshellexecute = false;
var process = process.start(startinfo);
return process.start();
}

三、結束語

程序實現很簡單,都是通過adb命令與手機進行交互操作。如果你認為對你有幫助麻煩贊下即可:)積分別玩太過哦。

C#實現微信跳一跳小游戲的自動跳躍助手開發實戰

可執行文件下載地址:jumperhelper.rar

代碼倉庫:https://github.com/kingthy/jumperhelper

總結

以上所述是小編給大家介紹的c#實現微信跳一跳小游戲的自動跳躍助手開發實戰,希望對大家有所幫助,如果大家有任何疑問歡迎給我留言,小編會及時回復大家的!

原文鏈接:https://www.cnblogs.com/kingthy/p/jumperhelper.html

延伸 · 閱讀

精彩推薦
  • C#C#實現XML文件讀取

    C#實現XML文件讀取

    這篇文章主要為大家詳細介紹了C#實現XML文件讀取的相關代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    Just_for_Myself6702022-02-22
  • C#C# 實現對PPT文檔加密、解密及重置密碼的操作方法

    C# 實現對PPT文檔加密、解密及重置密碼的操作方法

    這篇文章主要介紹了C# 實現對PPT文檔加密、解密及重置密碼的操作方法,非常不錯,具有參考借鑒價值,需要的朋友可以參考下...

    E-iceblue5012022-02-12
  • C#Unity3D實現虛擬按鈕控制人物移動效果

    Unity3D實現虛擬按鈕控制人物移動效果

    這篇文章主要為大家詳細介紹了Unity3D實現虛擬按鈕控制人物移動效果,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一...

    shenqingyu060520232410972022-03-11
  • C#WPF 自定義雷達圖開發實例教程

    WPF 自定義雷達圖開發實例教程

    這篇文章主要介紹了WPF 自定義雷達圖開發實例教程,本文介紹的非常詳細,具有參考借鑒價值,需要的朋友可以參考下...

    WinterFish13112021-12-06
  • C#深入解析C#中的交錯數組與隱式類型的數組

    深入解析C#中的交錯數組與隱式類型的數組

    這篇文章主要介紹了深入解析C#中的交錯數組與隱式類型的數組,隱式類型的數組通常與匿名類型以及對象初始值設定項和集合初始值設定項一起使用,需要的...

    C#教程網6172021-11-09
  • C#C#通過KD樹進行距離最近點的查找

    C#通過KD樹進行距離最近點的查找

    這篇文章主要為大家詳細介紹了C#通過KD樹進行距離最近點的查找,具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    帆帆帆6112022-01-22
  • C#C#設計模式之Visitor訪問者模式解決長隆歡樂世界問題實例

    C#設計模式之Visitor訪問者模式解決長隆歡樂世界問題實例

    這篇文章主要介紹了C#設計模式之Visitor訪問者模式解決長隆歡樂世界問題,簡單描述了訪問者模式的定義并結合具體實例形式分析了C#使用訪問者模式解決長...

    GhostRider9502022-01-21
  • C#C#裁剪,縮放,清晰度,水印處理操作示例

    C#裁剪,縮放,清晰度,水印處理操作示例

    這篇文章主要為大家詳細介紹了C#裁剪,縮放,清晰度,水印處理操作示例,具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    吳 劍8332021-12-08
主站蜘蛛池模板: 国产成人在线视频 | 日日夜夜添 | 老妇女av | 日韩成人免费中文字幕 | 亚洲国产成人精品女人久久久 | 一级片在线观看 | 国产精品毛片无码 | 久久爱综合 | 成人av在线播放 | 日本高清无卡码一区二区久久 | 亚洲精品毛片一区二区 | 国产精品美女久久久久久久网站 | 亚洲一区二区av | 亚洲 欧美 精品 | 欧美国产在线观看 | 久久久久久久久99精品 | av免费在线观看网站 | 久久精品国产清自在天天线 | 丁香久久 | 精品久久影院 | av黄色在线免费观看 | 国产精品视频免费看 | 亚洲 欧美 日韩 在线 | 久久精品二区 | 91视频免费看片 | 精品欧美乱码久久久久久 | 韩国三级午夜理伦三级三 | 成人免费乱码大片a毛片软件 | 成a人片在线观看 | 亚洲免费网站 | 狠狠艹 | 久久久精品综合 | 欧美日韩三级 | 天堂在线www | 激情五月激情综合网 | 成人影院av | 精品一区二区三区四区 | 亚洲高清视频在线 | 国产精品久久久久久婷婷天堂 | 最新电影在线高清免费完整观看视频 | 久久久亚洲精品视频 |