Java 独门绝技 用Java玩谷歌小恐龙游戏 (有源码)

目录

1、Swing成品演示

2、简介

3、Java的Robot类

4、实战开发例子

1、Swing成品演示

2、简介

Java有一个很厉害的类Robot类,这个类可以模仿人的手去操作电脑,鼠标移动,鼠标点击,按下键盘的按键,获取屏幕的某个坐标的像素等等。本次例子是用Java玩谷歌小恐龙,听起来很简单,但是里面存在着很多优化。因为小恐龙的移动速度会不断加快,检测屏幕像素时耗费的时间比较长,如何优化就成了大问题,但是也与电脑的配置有关系。

3、Java的Robot类

Java的Robot类的一些常用方法:

实例化对象就可以调用Robot类的方法了

Robot robot = new Robot();//实例化对象

Robot类的所有方法如下图:

Java 独门绝技 用Java玩谷歌小恐龙游戏 (有源码)_第1张图片

获取屏幕指定的颜色方法:

Color getPixelColor(int x, int y)

  • 参数列表x代表屏幕的x轴坐标  y代表屏幕的y轴坐标 返回值是Color类里面包含个该像素点的颜色信息。

  • 但是该方法的效率是非常慢的,他的执行原理是截取整个屏幕,再从截取到的图片中获取像素点的信息。

以下是优化获取指定屏幕颜色的方法:

原理是我们自己截取指定大小的图片,然后存放在BufferedImage中,代码如下:

import java.awt.*;
import java.awt.image.*;
public class Main {
  public static void main(String[] args) throws AWTException {
    Robot robot = new Robot();
    //参数是 x轴坐标、y轴坐标、截取的宽度、截取的高度
    Rectangle rtl = new Rectangle(10, 10, 10, 10);
    BufferedImage bufferedImage = robot.createScreenCapture(rtl);//指定大小截取屏幕
    Color color = new Color( bufferedImage.getRGB(5, 5) );//获取颜色
  }
}

控制延时触发:

void delay(int ms)

该方法其实就是Thread.sleep()方法,作用是休眠本线程,参数即线程休眠的毫秒数。

按钮的触发:

  • 按下按钮  void keyPress(int keycode)

  • 抬起按钮  void keyRelease(int keycode)

模仿人手按钮触发代码如下:

import java.awt.*;
import java.awt.event.KeyEvent;
import java.util.Random;
public class Main {
  public static void main(String[] args) throws AWTException {
    Robot robot = new Robot();
    robot.keyPress(KeyEvent.VK_UP);
    robot.delay(50+new Random().nextInt(50));//随机数延迟按钮的抬起 真正的模仿人手
    robot.keyRelease(KeyEvent.VK_UP);
  }
}

鼠标的触发:

  • 移动鼠标 void mouseMove(int x, int y)

  • 按下鼠标 void mousePress(int buttons)

  • 抬起鼠标 void mouseRelease(int buttons)

  • 鼠标滚轮 void mouseWheel(int wheelAmt)

这些方法可以模拟人手操作电脑,完成一些重复的操作。

4、实战开发例子

实战开发 用Java玩谷歌小恐龙:

核心代码如下

public static void Control(){
    
    try {
      Robot robot = new Robot();
      //控制跳
      new Thread(new Runnable() {
        @Override
        public void run() {
          int[] TempDinosaurColor = {DinosaurColor, DinosaurColor2};//恐龙颜色两次变换
          int[] TempBGColor = {BGColor, BGColor2};//背景颜色两次变换
          
          DinosaurColor = TempDinosaurColor[0];
          BGColor = TempBGColor[0];
          
          long start = System.currentTimeMillis();
          
          System.out.println("初始化属性---》"+Arrays.toString(TempDinosaurColor)+"   "+Arrays.toString(TempBGColor));
          Rectangle BgRtl = new Rectangle(DinosaurEye.x, DinosaurEye.y-90, 130, 123);
          while(state){
            
            BufferedImage bufferedImage=robot.createScreenCapture(BgRtl);
            
            //判断背景是否变化
            boolean BgChange = false;
            int BgRed = 0;
            for(int i=1;i<=2;i++){
              BgRed = ((bufferedImage.getRGB(50, i) >> 16) & 0xFF);//获取背景颜色
              if(Math.abs(BGColor-BgRed)>20){
                BgChange = true;
                break;
              }
            }
            
            if(BgChange){
              //标记后背景变换
              if( (System.currentTimeMillis()-start) >= 3500 ){//
                if(TempDinosaurColor[0]==DinosaurColor){
                  DinosaurColor = TempDinosaurColor[1];
                  BGColor = TempBGColor[1];
                }else{
                  DinosaurColor = TempDinosaurColor[0];
                  BGColor = TempBGColor[0];
                }
                
                System.out.println("BGColor -> "+BGColor+"  DinosaurColor -> "+DinosaurColor);
                start = System.currentTimeMillis();
                continue;
              }
            }
            
            boolean up = false;//跳
            to:
            for(int i=1;i<5;i++){
              for(int j=1;j<5;j++){
                int red = ((bufferedImage.getRGB(i+Tree.x, j+Tree.y) >> 16) & 0xFF);
                if(Math.abs(red-DinosaurColor)<20){//当仙人掌的颜色与恐龙的颜色差值为小于20 的时候需要跳
                  up = true;
                  break to;
                }
              }
            }
              
            if(up){//判断是否需要跳
              robot.keyPress(KeyEvent.VK_UP);
              robot.delay(120);
              robot.keyRelease(KeyEvent.VK_UP);
            }
            
            boolean down = false;//蹲
            to:
            for(int i=1;i<10;i++){
              for(int j=1;j<10;j++){
                int red = ((bufferedImage.getRGB(i+Tree.x, j+Tree.y-40) >> 16) & 0xFF);
                if(Math.abs(red-DinosaurColor)<20){//当飞鸟的颜色与恐龙的颜色差值为小于20 的时候需要跳
                  down = true;
                  break to;
                }
              }
            }
            
            if(up==false&&down==true){//判断是否需要蹲下
              robot.keyPress(KeyEvent.VK_DOWN);
              robot.delay(500);
              robot.keyRelease(KeyEvent.VK_DOWN);
            }
          }
        }
      }).start();
    } catch (Exception e) {
      e.printStackTrace();
    }

看完上面的核心代码你会发现,我们不能只获取一个像素点去判断物体是否已经到达指定位置,因为障碍物的移动会逐渐加快。我们只需要截图一次,扫描多次是否有指定的颜色近似值。

Swing的成品图片:

Java 独门绝技 用Java玩谷歌小恐龙游戏 (有源码)_第2张图片

该小工具使用的方法是:

打开谷歌浏览器输入 chrome://dino/ 即可在不断网的情况下进入小恐龙游戏。

需要将浏览器调节到宽度最小,高度紧贴着游戏的路面。设置如下图:

Java 独门绝技 用Java玩谷歌小恐龙游戏 (有源码)_第3张图片

然后点击软件的“展示坐标与颜色”按钮即可获取屏幕中任意一点的坐标值与RGB中的R。因为这个游戏是纯颜色的,RBG的值都是相同的。将鼠标移动到小恐龙的眼睛获取坐标值填写即可。

还有一个需要填写的是“黑色背景时恐龙的颜色RGB->R:”这个值需要先跑一边 大概到达700多分的时候背景会变黑,小恐龙的身体颜色会发生改变,点击软件的“展示坐标与颜色”按钮移动到小恐龙的身体获取颜色,并填写到黑色背景时恐龙的颜色RGB->R:的文本框中,重新开始游戏即可。

注意:我的电脑扫描一遍障碍物的时间是40毫秒,不同的电脑时间不同,所以不能100%成功跳过障碍物。目前我最高跑了1900分。

回复获取资源

关注后回复 小恐龙 

获取用Java玩谷歌小恐龙游戏的源码

你可能感兴趣的:(Java 独门绝技 用Java玩谷歌小恐龙游戏 (有源码))