Java开发游戏脚本(第一卷)

开发前言

我以前热爱玩游戏,所以选了软件工程专业,现在是个大二学生,学Java有一年了,随着深入的学习,我已对编程有着独特的感情,已不是当初的单纯为做游戏而学编程,但是,我还是打算做一期与游戏有关的脚本开发博客,用来记录一个菜鸟的开发坎坷历程。

开发热身

我选择做阴阳师脚本,因为它是完全靠鼠标操作的游戏,在百度搜索了我需要的类与方法,发现有一个类:Robot,它可以模拟鼠标和键盘操作,我们还需要控制鼠标如何找到正确的位置,正确的时间点击游戏窗口。我的思路是先取你需要鼠标点击的区域的颜色,然后实时抓取那个点的颜色,进行颜色对比,如果颜色一致,我们就用Robot类操作鼠标对它点击。思路正确后本人开始开发之旅!

获取鼠标的坐标信息

     /**
	 * 本方法会在三秒后获取当前鼠标的坐标相关信息并且设置为判断点.
	 * 
	 * @throws Exception - 如果平台配置不允许使用Robot类则抛出异常
	 */
	public int[] setPoint() throws Exception {

		Robot robot = new Robot();
		robot.delay(3000);
		// 获取鼠标坐标
		PointerInfo pinfo = MouseInfo.getPointerInfo();
		Point p = pinfo.getLocation();
		int mouseX = (int) p.getX();
		int mouseY = (int) p.getY();
		// 获取鼠标坐标颜色
		Color mouseRGB = robot.getPixelColor(mouseX, mouseY);
		int R = mouseRGB.getRed();
		int G = mouseRGB.getGreen();
		int B = mouseRGB.getBlue();
		// 返回鼠标的坐标值
		int[] array = new int[] { mouseX, mouseY, R, G, B };
		return array;

	}

鼠标信息数据处理

// 将数据保存到磁盘中,可以持久保存数据
int[] Point = setPoint();
FileOutputStream File = new FileOutputStream("pointMessage.txt", true);
String pointMessage = "{" + Point[0] + "," + Point[1] + "," + Point[2] + "," + Point[3]        + "," + Point[4] + "}\n";
byte b[] = pointMessage.getBytes();
File.write(b);
File.close();

保存完后查看信息
信息

     /**
	 * 本方法会将文件信息提取并且返回此文件信息列表
	 * 
	 * @param FileURL - 指定的文件URL
	 * @return - 返回的文件信息列表
	 * @throws Exception - 如果发生 I/O 错误则抛出异常
	 */
	public ArrayList<int[]> FileToArrayList(String FileURL) throws Exception {

		String string = null;
		int[] Point = null;
		ArrayList<int[]> PointList = new ArrayList<int[]>();
        //本人采用正则表达式提取数据,
		Pattern p = Pattern.compile("\\{([^,]+),([^,]+),([^,]+),([^,]+),([^\\}]+)\\}");
		BufferedReader File = new BufferedReader(new InputStreamReader(new FileInputStream(FileURL)));

		while ((string = File.readLine()) != null) {
            //虽然有其他存数据办法,比如数据库,但是不可能让用户专门下载个数据库,这是一个正常的逻辑
			Matcher rule = p.matcher(string);

			while (rule.find()) {
				// 将每行的数据提取并且赋值,最后添加进容器中
				int X = Integer.parseInt(rule.group(1));
				int Y = Integer.parseInt(rule.group(2));
				int R = Integer.parseInt(rule.group(3));
				int G = Integer.parseInt(rule.group(4));
				int B = Integer.parseInt(rule.group(5));
				Point = new int[] { X, Y, R, G, B };
				PointList.add(Point);
			}
		}

		File.close();
		return PointList;

	}

颜色对比判断鼠标操作

     /**
	 * 本方法会根据设定的判断点与真实点进行对比,如果颜色一致则移动鼠标到该点进行单击操作
	 * 
	 * @param Point - 判断点的相关信息
	 * @throws Exception - 如果平台配置不允许使用Robot类则抛出异常
	 */
	public void MouseResponse(int[] Point) throws Exception {

		// 获取判断点的信息
		int decisionX = Point[0];
		int decisionY = Point[1];
		int decisionR = Point[2];
		int decisionG = Point[3];
		int decisionB = Point[4];
		// 获取真实点的颜色
		Robot robot = new Robot();
		Color decisionRGB = robot.getPixelColor(decisionX, decisionY);
		int mouseR = decisionRGB.getRed();
		int mouseG = decisionRGB.getGreen();
		int mouseB = decisionRGB.getBlue();
		// 如果真实点与判断点颜色一致,则执行以下操作
		if (Math.abs(mouseR - decisionR) < 5 && Math.abs(mouseG - decisionG) < 5 && Math.abs(mouseB - decisionB) < 5) {

			// 计算鼠标位置并且移动到该位置
			int mouseMoveX = (int) (Math.random() * 35 - 15) + decisionX;
			int mouseMoveY = (int) (Math.random() * 35 - 15) + decisionY;
			// 修复JDK8的移动不正确的BUG
			for (int i = 0; i < 6; i++) {
				robot.mouseMove(mouseMoveX, mouseMoveY);
			}
			// 模拟计算鼠标按下的间隔并且按下鼠标
			int moveTime = (int) (Math.random() * 500 + 200);
			int mousePressTime = (int) (Math.random() * 500 + 200);
			robot.delay(moveTime);
			robot.mousePress(InputEvent.BUTTON1_MASK);
			robot.delay(mousePressTime);
			robot.mouseRelease(InputEvent.BUTTON1_MASK);

		}

	}

这里解释一下:游戏是实时渲染的,不可能一点的颜色永远稳定在一个值,比如一点纯白色(255,255,255),游戏稳定时提取到这颜色,不稳定时可能会存在一点偏差,比如(254,255,255),
虽然肉眼看起来一致,但是电脑不这样认为,所以我加了个绝对值,偏差量为5,这样就稳了。至于
为什么又加个鼠标位置计算,因为人玩游戏的时候不可能一直点同一个位置,我计算了一点偏差,让脚本不容易被游戏公司识别到,后面的鼠标按下与释放的间隔也是同一个道理。

多线程启动脚本

public void run() {

		try {
			// 读取判断点信息
			ArrayList<int[]> PointList = FileToArrayList("pointMessage.txt");
			// 开始刷本
			while (true) {
                // 遍历每个设置判断点
				for (int i = 0; i < PointList.size(); i++) {
                    // 如果判断点与真实点颜色一致就移动到该点并且点击该点
					MouseResponse(PointList.get(i));

				}
                // 每次遍历完让程序休息一下,别太累了
				Thread.sleep(500);

			}

		} catch (Exception e) {
			
			e.printStackTrace();
			
		}

}

这样之后,一个简单的游戏脚本就开发完成了,现在只能控制台输出,如果你需要更好的视觉体验,可以尝试做一个Swing/Awt/JavaFX界面,因为此次为一个最简单的脚本,以后会添加更多的功能。
比如现在的脚本只是取一固定点,如果游戏窗口一移动,你的那个固定点已经固定了,如何能让脚本继续正常运行,此后,如果无法正常运行,是不是该发个通知给用户?这些问题,会在以后的博客推出解决方案。

发布了2 篇原创文章 · 获赞 1 · 访问量 754

猜你喜欢

转载自blog.csdn.net/weixin_44005360/article/details/105202607