本文最后更新于2020年05月07日;如遇问题,请留言及时通知站长。

断断续续的在玩“梦想小镇”,大家都知道,绿钞在游戏里面绝对是硬通货,对于人民币玩家,完全可以通过购买绿钞实现快速升级。好吧,我是不会为游戏花钱的,除了我的最爱 Quake Live,花了RMB36元。

steampowered 网站居然被举报为诈骗网站。嗯,确实骗了我不少钱,害得我天天玩游戏。

最近游戏里面举行了一个农业大赛,也就是种庄稼就可以奖励积分,活动结束积分第一名可以奖励 50 张绿钞,哇,这可是千载难逢的好事,嗯,目前看来是。

梦想小镇 (Township) 是一款比较传统的农场类模拟经营游戏,将城市建设和农场管理进行了结合。
《梦想小镇》将城市建设和农场管理进行了独树一帜的结合!
收获农作物、在工厂进行加工,再将货物出售以发展您的小镇。与远处的岛屿进行交易。开设餐厅、电影院和其他社区建筑,让您的小镇别具风味充满生机。探索矿井获取能源并找出古董。运营您自己的动物园并收集世界各地的动物。
准备好筑造您的梦想了吗?我们开始吧!
Township

研究了一下积分情况,一个小麦1分,一个玉米2分,一个胡萝卜3分,基本上种植时间越长积分越高。不过仔细一算会发现时间和积分是不成比例的。比如,种一茬小麦需要2分钟,一茬玉米需要5分钟,也就是同样的时间,种小麦产生的积分更高,换算到其他作物也是一样,只有种小麦最划算,积分上升的也最快。

玩了一个多小时,发现不对劲,这样升级是很快,但是 2 分钟一茬,也就意味着我要一直这么盯着才行。
这怎么可以?我其他的事情都做不了了。
还有什么事情可以让程序员为难呢?!(BGM...)是时候展现我真正的实力啦,哈哈哈

【说明】

以下操作环境为 macOS Catalina,版本 10.15.4。

网上搜索了 Mac 上的鼠标自动化操作,发现 PyAutoGUI 完全满足“鼠标点击和拖动”的要求,就它了。

PyAutoGUI 官网:https://pyautogui.readthedocs.io/en/latest/
Windows 下面有按键精灵可以用,很早很早以前用过。

使用 PIP 安装好 PyAutoGUI ,就可以祭出我的 Python 大法,打开终端,输入:jupyter lab,开启python之旅!

BUT 编程切记不要一上来就写代码,要先思考流程,模块设计,划分功能。
不过,我一瞬间就明白了一切,开始直接动手写代码,嗯,就是这样的。

好吧,循环流程大致有这么几步:收麦子 -> 种麦子-> 卖麦子

收麦子:定位麦田位置,选中镰刀,在麦田上方挥舞镰刀收割
种麦子:定位麦田位子,选中小麦种子,在麦田上方挥洒种子
卖麦子:打开仓库,定位到小麦,修改销售数量,卖出小麦。

【移动与点击代码】

import pyautogui as pa
from datetime import datetime
import time

#多次点击 
def timesclick(x):
    for i in range(x):
        pa.click()
        time.sleep(0.1)

#田地范围        
def YiDong2():
    for i in range(5):      
        pa.moveTo(790-70*i, 255+45*i, duration=0.5) 
        pa.moveTo(980+75*i, 255+45*i, duration=0.5) 
    for i in range(5):      
        pa.moveTo(380+40*i, 450+45*i, duration=0.5) 
        pa.moveTo(1210-75*i, 450+45*i, duration=0.5)  

【代码说明】

不知道怎么回事,click()本身是支持多次点击的,修改clicks、interval就可以,但是 interval 不起作用,而如果点击快了,游戏里面是反应不过来的,因此只能自己写一个多次点击函数。
游戏里面的坐标不是正方形,而是菱形,一开始是获取田地左上和右下坐标,然后横扫整个长方形,这样有点费时。重写代码,扫描范围改成菱形了。

【收、种、卖代码】

#收 麦子
def ShouMaizi():
    pa.moveTo(820, 460, duration=0.25) 
    pa.click() #鼠标在麦田中心点击一次
    pa.moveTo(730, 820, duration=0.25) #镰刀位置
    pa.mouseDown(730, 820)#选中镰刀
    pa.moveTo(820, 460, duration=0.5)
    YiDong2()
    pa.mouseUp()
    
#种 麦子    
def Zhongmaizi():
    pa.moveTo(820, 460, duration=0.25) #选块地
    pa.click()
    pa.moveTo(400, 820, duration=0.25) #选小麦种子
    pa.mouseDown(400, 820)
    pa.moveTo(820, 460, duration=0.25) 
    YiDong2()
    pa.mouseUp()
    
#卖 麦子    
def Maimaizi():
    pa.moveTo(810, 150, duration=0.25) #打开仓库
    pa.click() 
    pa.moveTo(490, 350, duration=0.5) #点麦子
    pa.click() 
    pa.moveTo(640, 570, duration=0.25) #改数量
    timesclick(25)
    pa.moveTo(500, 695, duration=0.25) #卖麦子
    pa.click() 
    pa.moveTo(1150, 130, duration=0.5) #关闭仓库
    pa.click() 

【代码说明】

mouseDown()表示一直按着左键,然后通过moveTo()来回移动,实现收、种效果;
mouseUp()松开按键。

【循环代码】

dt=datetime.now() #创建一个datetime类对象
print('开始循环:',dt.year,'年',dt.month,'月',dt.day,'日',dt.hour,':',dt.minute,':',dt.second,'\n') 
time.sleep(20)
for i in range(300):   
    t0 = time.perf_counter()
    Zhongmaizi()
    print('种麦子耗时 Sec:',time.perf_counter()-t0)
    time.sleep(int(random.random()*8))
    Maimaizi()
    time.sleep(105) #等待麦子成熟  
    print('卖麦子耗时 Sec:',time.perf_counter()-t0)
    ShouMaizi()
    print('收麦子耗时 Sec:',time.perf_counter()-t0-105)
    time.sleep(int(random.random()*3)) 
    print('循环次数 No:',i+1,'  耗时 Sec:',time.perf_counter()-t0,'\n')

【代码说明】

做了每一项的计时,这么便于后期的改进,缩减时间;
每一项操作后面有个随机的等待时间,不知道游戏有没有外挂检测,先随机一下。
每次都把麦子卖光,不然仓库会满,影响后续操作。

【注意事项】

因为是按照坐标定位,进行操作,因此自动化开始后,不能移动地图。

【后记】

运行代码,利用等待时间切换到游戏界面,OK,观察一两个循环看看效果,还不错,终于解放了。
开了一晚上,积分上升嗖嗖滴,第二天毫无悬念的得了第一名,一晚上就收获 50 张绿钞 ,嗯,只有一晚上。
种麦子不花钱,没想到卖了一晚上麦子,金币也收获颇丰,哈哈。