作者:admin,发布日期:2019-01-02
阅读:4604;评论:2

(开头GIF太大,请打开https://s2.ax1x.com/2019/01/02/FIYQJS.gif 观看 )

QQ截图20190102192731.jpg

游戏地址

https://tbot.xyz/lumber/

写在开头

        应tg群组里大佬的邀请,体验了@gamebot 的一款砍树小游戏,但是由于作者本人太菜,分数很低,遂想出了用Python玩这个小游戏的思路,这篇文章我们将对破解这一游戏的思路进行详解。

环境配置

        我们这边需要用到selenium来控制浏览器,同时使用pillow来识别处理图像,我们使用pip来安装来安装这两个库

pip install selenium
pip install pillow

QQ截图20190102193309.jpg

(这里使用了pipenv来安装,实际环境请根据环境来选择pip或者pipenv)

安装完成,我们需要安装chrome浏览器,同时下载chromedriver来让selenium支持chrome(这里可以参考文章https://www.cnblogs.com/technologylife/p/5829944.html )。

初步考察

打开游戏网页https://tbot.xyz/lumber/ ,点击开始图标,我们发现这是一个很简单的小游戏,但是对操作有很大要求,如果走错了方向或者速度慢了都会被树砸死,显示分数,同时经过测试,我们发现使用方向键操控玩家也是没有问题的。

QQ截图20190102193658.jpg

通过这张图,我们可以发现,每次要砍的枝干的位置是固定的,而且两边不会同时出现(废话2333),且枝干和背景有明显的区别,同时每次砍树需要砍两次,需要先把树干砍掉,再把枝干砍掉。

由此我们可以直接得出思路:

  1. 首先截取游戏的大图

  2. 然后对大图进行切割,把左右枝干的位置切割出来

  3. 查找颜色,查找是否有枝干的颜色,以此来确定要走的方向,如果两边都没有找到枝干的颜色,那就往一个固定方向走

得到了思路,我们就先要确定要查找的颜色,和枝干位置的坐标,我们这里就先用selenium截一张图片,然后再确定下一步的坐标

browser = webdriver.Chrome()
# 打开游戏页面,加载完之后才会执行下面的代码
browser.get('https://tbot.xyz/lumber/')
# 加载完后开始游戏
browser.find_element(By.TAG_NAME, 'body').send_keys(Keys.SPACE)
# 截图
browser.save_screenshot('screen.png')

然后我们打开运行目录下的"screen.png",直接使用ps的取色工具选取枝干的颜色,获得RGB值,同时我们使用PS的信息面板,确定枝干的位置(应该是比玩家的头高一点点的位置)

QQ截图20190102195117.jpg

下一步我们将根据思路编写代码

最终代码

from PIL import Image
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys


# 这里直接把查找颜色封装成一个枝干,程序需要遍历截取到的图片的所有像素,查找是否有指定的颜色,以此判断枝干的位置
def find_color(image: Image.Image, r: int, g: int, b: int):
    """
    匹配图片颜色,匹配成功返回True
    :param image: 匹配的图片
    :param r: r值
    :param g: g值
    :param b: b值
    :return: True或False,代表是否匹配到
    """
    # 遍历图片x轴
    for i in range(image.width):
        for j in range(image.height):
            # 遍历图片y轴,获取图片颜色信息,进行比对,如果匹配成功,直接跳出循环,返回True
            img_r, img_g, img_b, img_alpha = image.getpixel((i, j))
            if img_r == r and img_g == g and img_b == b:
                return True
    # 没有匹配成功,返回False
    return False


def main():
    # 创建browser对象,用于控制浏览器
    browser = webdriver.Chrome()
    # 打开游戏页面,加载完之后才会执行下面的代码
    browser.get('https://tbot.xyz/lumber/')
    # 加载完后开始游戏
    browser.find_element(By.TAG_NAME, 'body').send_keys(Keys.SPACE)

    # 初始化枝干的颜色
    r, g, b = 161, 116, 56

    # 循环判断
    while True:
        # 判断游戏是否结束,结束了则不执行里面代码
        class_text: str = browser.find_element(By.ID, 'page_wrap').get_attribute('class')
        if class_text.find('in_result') >= 0:
            continue
            # 下面代码表示结束之后自动开始下一局
            # browser.find_element(By.TAG_NAME, 'body').send_keys(Keys.SPACE)

        # 对网页进行截图
        browser.save_screenshot('screen.png')
        # 使用pillow库打开图片
        im: Image.Image = Image.open('screen.png')
        # 切割图片,获取到左右枝干的图片
        region_left = im.crop((410, 480, 420, 500))
        region_right = im.crop((510, 480, 520, 500))

        # 从图片里找颜色,判断要走的方向,然后模拟按键
        if find_color(region_left, r, g, b):
            browser.find_element(By.TAG_NAME, 'body').send_keys(Keys.RIGHT)
            browser.find_element(By.TAG_NAME, 'body').send_keys(Keys.RIGHT)
        elif find_color(region_right, r, g, b):
            browser.find_element(By.TAG_NAME, 'body').send_keys(Keys.LEFT)
            browser.find_element(By.TAG_NAME, 'body').send_keys(Keys.LEFT)
        else:
            # 两边都不是枝干,那就随便走一边右边了
            browser.find_element(By.TAG_NAME, 'body').send_keys(Keys.RIGHT)


if __name__ == '__main__':
    main()