跳一跳自动跳跃C#代码实现

2019-12-30 19:07:23于海丽

四、删除文件,指令:


adb -s 设备号 shell rm /sdcard/temp.png 

五、获取小蓝人脚底像素坐标和目标平台中心像素坐标,下面详细说说里面的步骤

1、通过Bitmap类读取图片,再用unsafe代码利用指针把RGB数据直接从内存拷出来存放到byte数组中(这步其实不用也可以但不知道直接通过Bitmap获取像素效率会不会很低,大家可以测了分享一下结果)
2、用两层循环y从max->0,遍历x轴像素,通过对比找出小蓝人位置,本例通过两个rgb像素的标准差不超过3作为置信偏差判断两个像素是否为同一元素。再稍微处理一下就可得出当前坐标。
3、利用上面得到的坐标P以及一开始准备工作中提到的分数底行y坐标(取大于该y作为startY即可)再进行对目标坐标的搜索:用两层循环y从startY->Py,遍历x轴像素(利用P的x坐标缩小搜索的x坐标范围:若x位于左半屏则搜索Px+40->Xmax,反之搜索0->Px-40,注:不缩小范围会出错,原因大家想想)。(这个40可取大于小蓝人头宽度一半的值即可)
4、那就用我们的勾三股四弦五定理再开根求出距离。距离除以速度得出时间。

六、发送触摸指令实现定时跳跃,指令:


adb shell input touchscreen swipe x y x y延时(ms) 

       这里不得不说一下,当时找半天找不到定时触摸的指令,网上有个用6个指令组合实现定时触摸屏幕的方法,但实测无效,而且也怕指令这么多,延时还是分开控制,肯定会对跳跃结果有很大影响。后面看到一条利用swipe指令实现的评论,真是醒目。swipe虽然是滑动指令,但如果设置起止坐标都是同一个坐标不就相当于实现了定点定时触摸了吗。

七、七就是一直重复二~六的步骤就是了。

       本次测试很东西都是急着做,没仔细研究,例如获取跳跃速度这个就是傻瓜式的通过手动发送跳跃指令、截图用ps手动计算出来的。大家可以用代码实现一下。希望大家指正可以改进的地方。

C#源码如下

Cmd类,实现cmd执行命令


class Cmd 
{ 
 private System.Diagnostics.Process process; 
 private bool isExecuted; // 是否执行过命令 
 private string command; // 上次执行命令 
 private int result;  // 上次执行命令结果 
 private string resultContent; // 上次执行命令返回结果 
 public Cmd() 
 { 
 process = new System.Diagnostics.Process(); 
 process.StartInfo.FileName = "cmd.exe"; 
 process.StartInfo.UseShellExecute = false; //是否使用操作系统shell启动 
 process.StartInfo.RedirectStandardInput = true;//接受来自调用程序的输入信息 
 process.StartInfo.RedirectStandardOutput = true;//由调用程序获取输出信息 
 process.StartInfo.RedirectStandardError = true;//重定向标准错误输出 
 process.StartInfo.CreateNoWindow = true;//不显示程序窗口 
 
 isExecuted = false; 
 } 
 public int ExecuteCmd(string cmd) 
 { 
 command = cmd; 
 try 
 { 
  process.Start(); 
  process.StandardInput.WriteLine(cmd + "&exit"); 
  process.StandardInput.AutoFlush = true; 
  string content = process.StandardOutput.ReadToEnd(); 
  process.WaitForExit();//等待程序执行完退出进程 
  process.Close(); 
 
  result = 0; 
  resultContent = content.Split(new string[] { "&exit" }, StringSplitOptions.None)[1].Replace("n", ""); 
 } 
 catch (Exception ex) 
 { 
  result = -1; 
  resultContent = ex.Message; 
 } 
 
 if (!isExecuted) isExecuted = true; 
 
 return result; 
 } 
 private int ExecuteCmd(string adbPath, string cmd) 
 { 
 command = $""{adbPath}" {cmd}"; 
 try 
 { 
  process.Start(); 
  process.StandardInput.WriteLine(command + "&exit"); 
  process.StandardInput.AutoFlush = true; 
  string content = process.StandardOutput.ReadToEnd(); 
  process.WaitForExit();//等待程序执行完退出进程 
  process.Close(); 
 
  result = 0; 
  resultContent = content.Split(new string[] { "&exit" }, StringSplitOptions.None)[1].Replace("n", ""); 
 } 
 catch (Exception ex) 
 { 
  result = -1; 
  resultContent = ex.Message; 
 } 
 
 if (!isExecuted) isExecuted = true; 
 
 return result; 
 } 
 public string GetExcResult() 
 { 
 if (isExecuted) 
 { 
  if (result == 0) 
  { 
  return resultContent; 
  } 
  else 
  { 
  return $"Execute Failed! Command:{command}n{resultContent}"; 
  } 
 } 
 else 
 { 
  return "从未执行过命令"; 
 } 
 } 
 public void DisposeProcess() 
 { 
 process.Dispose(); 
 } 
} 
 
class Pixel 
{ 
 public byte[] pixel = new byte[3]; 
 public Pixel() 
 { 
 
 } 
}