微信跳一跳辅助Java代码实现

2025-05-27 0 90

微信跳一跳辅助的Java具体实现代码,供大家参考,具体内容如下

1.参考知乎教你用Python来玩微信跳一跳,鉴于本人Python一直都是半吊子水平,之前打算用python刷分,可无奈安装python环境各种模块缺失,报错不停,于是乎,使用Java重新实现了一下。

2.环境配置及相关说明:

1)、Windows系统,本人win10
2)、AVA环境安装,JDK7以上即可
3)、安卓手机一部、数据线一条
4)、电脑安装ADB驱动,连接安卓手机,同时打开USB调试模式
5)、打开微信小程序的跳一跳游戏,JAVA程序跑起来,具体代码往下看
6)、本人所用为魅蓝note2安卓手机,屏幕 分辨率1920×1080,不同型号的手机,可能需要调整相关参数,具体看代码注释
7)、增加了刷分失败后游戏自动重新开局功能
8)、娱乐而已,不要较真,据说微信官方已经关注,分数太高可能会被清零,哈哈

3、废话不多说,上代码:

?

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

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

264

265

266

267

268

269

270

271

272

273

274

275

276

277

278

279

280

281

282

283

284

285

286

287

288

289

290

291

292

293

294

295

296

297

298

299

300

301

302

303

304

305

306

307

308

309

310

311

312

313

314

315

316

317

318

319

320

321

322

323

324

325

326

327

328

329

330

331

332

333

334

335

336

337

338

339

340

341

342

343

344

345

346

347

348

349

350

351

352

353

354

355

356

357

358

359

360

361

362

363

364

365

366

367

368

369

370

371

372

373

374

375

376

377

378

379

380

381

382

383

384

385

386

387

388

389

390

391

392

393

394

395

396

397

398

399

400

401

402

403

404

405

406

407

408

409

410

411

412
package com.yihusitian.gamehelper;

import java.awt.image.BufferedImage;

import java.io.BufferedReader;

import java.io.File;

import java.io.IOException;

import java.io.InputStreamReader;

import java.util.Arrays;

import java.util.concurrent.TimeUnit;

import javax.imageio.ImageIO;

/**

* 参考知乎

*

* @link <a href="https://zhuanlan.zhihu.com/p/32452473" rel="external nofollow" rel="external nofollow" target="_blank">https://zhuanlan.zhihu.com/p/32452473</a>

*

* 跳一跳辅助

*

* @author LeeHo

*/

public class JumpJumpHelper

{

private static final String IMAGE_NAME = "current.png";

private static final String STORE_DIR = "d:/jump_screencapture";

//数量

private static final int imageLengthLength = 5;

//存放图片的大小

private static final long[] imageLength = new long[imageLengthLength];

private final RGBInfo rgbInfo = new RGBInfo();

private final String[] ADB_SCREEN_CAPTURE_CMDS =

{ "adb shell screencap -p /sdcard/" + IMAGE_NAME,

"adb pull /sdcard/current.png " + STORE_DIR };

//截屏中游戏分数显示区域最下方的Y坐标,300是 1920x1080的值,根据实际情况修改

private final int gameScoreBottomY = 300;

//按压的时间系数,可根据具体情况适当调节

private final double pressTimeCoefficient = 1.35;

//按压的起始点坐标,也是再来一局的起始点坐标

private final int swipeX = 550;

private final int swipeY = 1580;

//二分之一的棋子底座高度

private final int halfBaseBoardHeight = 20;

//棋子的宽度,从截屏中量取,自行调节

private final int halmaBodyWidth = 74;

//游戏截屏里的两个跳板的中点坐标,主要用来计算角度,可依据实际的截屏计算,计算XY的比例

private final int boardX1 = 813;

private final int boardY1 = 1122;

private final int boardX2 = 310;

private final int boardY2 = 813;

/**

* 获取跳棋以及下一块跳板的中心坐标

*

* @return

* @author LeeHo

* @throws IOException

* @update 2017年12月31日 下午12:18:22

*/

private int[] getHalmaAndBoardXYValue(File currentImage) throws IOException

{

BufferedImage bufferedImage = ImageIO.read(currentImage);

int width = bufferedImage.getWidth();

int height = bufferedImage.getHeight();

System.out.println("宽度:" + width + ",高度:" + height);

int halmaXSum = 0;

int halmaXCount = 0;

int halmaYMax = 0;

int boardX = 0;

int boardY = 0;

//从截屏从上往下逐行遍历像素点,以棋子颜色作为位置识别的依据,最终取出棋子颜色最低行所有像素点的平均值,即计算出棋子所在的坐标

for (int y = gameScoreBottomY; y < height; y++)

{

for (int x = 0; x < width; x++)

{

processRGBInfo(bufferedImage, x, y);

int rValue = this.rgbInfo.getRValue();

int gValue = this.rgbInfo.getGValue();

int bValue = this.rgbInfo.getBValue();

//根据RGB的颜色来识别棋子的位置,

if (rValue > 50 && rValue < 60 && gValue > 53 && gValue < 63 && bValue > 95 && bValue < 110)

{

halmaXSum += x;

halmaXCount++;

//棋子底行的Y坐标值

halmaYMax = y > halmaYMax ? y : halmaYMax;

}

}

}

if (halmaXSum != 0 && halmaXCount != 0)

{

//棋子底行的X坐标值

int halmaX = halmaXSum / halmaXCount;

//上移棋子底盘高度的一半

int halmaY = halmaYMax - halfBaseBoardHeight;

//从gameScoreBottomY开始

for (int y = gameScoreBottomY; y < height; y++)

{

processRGBInfo(bufferedImage, 0, y);

int lastPixelR = this.rgbInfo.getRValue();

int lastPixelG = this.rgbInfo.getGValue();

int lastPixelB = this.rgbInfo.getBValue();

//只要计算出来的boardX的值大于0,就表示下个跳板的中心坐标X值取到了。

if (boardX > 0)

{

break;

}

int boardXSum = 0;

int boardXCount = 0;

for (int x = 0; x < width; x++)

{

processRGBInfo(bufferedImage, x, y);

int pixelR = this.rgbInfo.getRValue();

int pixelG = this.rgbInfo.getGValue();

int pixelB = this.rgbInfo.getBValue();

//处理棋子头部比下一个跳板还高的情况

if (Math.abs(x - halmaX) < halmaBodyWidth)

{

continue;

}

//从上往下逐行扫描至下一个跳板的顶点位置,下个跳板可能为圆形,也可能为方框,取多个点,求平均值

if ((Math.abs(pixelR - lastPixelR) + Math.abs(pixelG - lastPixelG) + Math.abs(pixelB - lastPixelB)) > 10)

{

boardXSum += x;

boardXCount++;

}

}

if (boardXSum > 0)

{

boardX = boardXSum / boardXCount;

}

}

//按实际的角度来算,找到接近下一个 board 中心的坐标

boardY = (int) (halmaY - Math.abs(boardX - halmaX) * Math.abs(boardY1 - boardY2)

/ Math.abs(boardX1 - boardX2));

if (boardX > 0 && boardY > 0)

{

int[] result = new int[4];

//棋子的X坐标

result[0] = halmaX;

//棋子的Y坐标

result[1] = halmaY;

//下一块跳板的X坐标

result[2] = boardX;

//下一块跳板的Y坐标

result[3] = boardY;

return result;

}

}

return null;

}

/**

* 执行命令

*

* @param command

* @author LeeHo

* @update 2017年12月31日 下午12:13:39

*/

private void executeCommand(String command)

{

Process process = null;

try

{

process = Runtime.getRuntime().exec(command);

System.out.println("exec command start: " + command);

process.waitFor();

BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getErrorStream()));

String line = bufferedReader.readLine();

if (line != null)

{

System.out.println(line);

}

System.out.println("exec command end: " + command);

}

catch (Exception e)

{

e.printStackTrace();

}

finally

{

if (process != null)

{

process.destroy();

}

}

}

/**

* ADB获取安卓截屏

*

* @author LeeHo

* @update 2017年12月31日 下午12:11:42

*/

private void executeADBCaptureCommands()

{

for (String command : ADB_SCREEN_CAPTURE_CMDS)

{

executeCommand(command);

}

}

/**

* 跳一下

*

* @param distance

* @author LeeHo

* @update 2017年12月31日 下午12:23:19

*/

private void doJump(double distance)

{

System.out.println("distance: " + distance);

//计算按压时间,最小200毫秒

int pressTime = (int) Math.max(distance * pressTimeCoefficient, 200);

System.out.println("pressTime: " + pressTime);

//执行按压操作

String command = String.format("adb shell input swipe %s %s %s %s %s", swipeX, swipeY, swipeX, swipeY,

pressTime);

System.out.println(command);

executeCommand(command);

}

/**

* 再来一局

*

* @author LeeHo

* @update 2017年12月31日 下午12:47:06

*/

private void replayGame()

{

String command = String.format("adb shell input tap %s %s", swipeX, swipeY);

executeCommand(command);

}

/**

* 计算跳跃的距离,也即两个点之间的距离

*

* @param halmaX

* @param halmaY

* @param boardX

* @param boardY

* @return

* @author LeeHo

* @update 2017年12月31日 下午12:27:30

*/

private double computeJumpDistance(int halmaX, int halmaY, int boardX, int boardY)

{

return Math.sqrt(Math.pow(Math.abs(boardX - halmaX), 2) + Math.pow(Math.abs(boardY - halmaY), 2));

}

public static void main(String[] args)

{

try

{

File storeDir = new File(STORE_DIR);

if (!storeDir.exists()) {

boolean flag = storeDir.mkdir();

if (!flag) {

System.err.println("创建图片存储目录失败");

return;

}

}

JumpJumpHelper jumpjumpHelper = new JumpJumpHelper();

//执行次数

int executeCount = 0;

for (;;)

{

//执行ADB命令,获取安卓截屏

jumpjumpHelper.executeADBCaptureCommands();

File currentImage = new File(STORE_DIR, IMAGE_NAME);

if (!currentImage.exists())

{

System.out.println("图片不存在");

continue;

}

long length = currentImage.length();

imageLength[executeCount % imageLengthLength] = length;

//查看是否需要重新开局

jumpjumpHelper.checkDoReplay();

executeCount++;

System.out.println("当前第" + executeCount + "次执行!");

//获取跳棋和底板的中心坐标

int[] result = jumpjumpHelper.getHalmaAndBoardXYValue(currentImage);

if (result == null)

{

System.out.println("The result of method getHalmaAndBoardXYValue is null!");

continue;

}

int halmaX = result[0];

int halmaY = result[1];

int boardX = result[2];

int boardY = result[3];

System.out.println("halmaX: " + halmaX + ", halmaY: " + halmaY + ", boardX: " + boardX + ", boardY: "

+ boardY);

//计算跳跃的距离

double jumpDistance = jumpjumpHelper.computeJumpDistance(halmaX, halmaY, boardX, boardY);

jumpjumpHelper.doJump(jumpDistance);

//每次停留2.5秒

TimeUnit.MILLISECONDS.sleep(2500);

}

}

catch (Exception e)

{

e.printStackTrace();

}

}

/**

* 检查是否需要重新开局

*

* @author LeeHo

* @update 2017年12月31日 下午1:39:18

*/

private void checkDoReplay()

{

if (imageLength[0] > 0 && imageLength[0] == imageLength[1] && imageLength[1] == imageLength[2]

&& imageLength[2] == imageLength[3] && imageLength[3] == imageLength[4])

{

//此时表示已经连续5次图片大小一样了,可知当前屏幕处于再来一局

Arrays.fill(imageLength, 0);

//模拟点击再来一局按钮重新开局

replayGame();

}

}

/**

* 获取指定坐标的RGB值

*

* @param bufferedImage

* @param x

* @param y

* @author LeeHo

* @update 2017年12月31日 下午12:12:43

*/

private void processRGBInfo(BufferedImage bufferedImage, int x, int y)

{

this.rgbInfo.reset();

int pixel = bufferedImage.getRGB(x, y);

//转换为RGB数字

this.rgbInfo.setRValue((pixel & 0xff0000) >> 16);

this.rgbInfo.setGValue((pixel & 0xff00) >> 8);

this.rgbInfo.setBValue((pixel & 0xff));

}

class RGBInfo

{

private int RValue;

private int GValue;

private int BValue;

public int getRValue()

{

return RValue;

}

public void setRValue(int rValue)

{

RValue = rValue;

}

public int getGValue()

{

return GValue;

}

public void setGValue(int gValue)

{

GValue = gValue;

}

public int getBValue()

{

return BValue;

}

public void setBValue(int bValue)

{

BValue = bValue;

}

public void reset()

{

this.RValue = 0;

this.GValue = 0;

this.BValue = 0;

}

}

}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持快网idc。

原文链接:http://blog.csdn.net/lihushiwoa/article/details/78942322

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

快网idc优惠网 建站教程 微信跳一跳辅助Java代码实现 https://www.kuaiidc.com/76680.html

相关文章

发表评论
暂无评论