抱歉,您的浏览器无法访问本站

本页面需要浏览器支持(启用)JavaScript


了解详情 >

最近玩了一个手机网游《刀塔传奇》,感觉画面很好看,而且技能挺丰富的,操作也比较简单。
但是玩游戏太浪费时间了,所以写了一段lua代码来自动刷副本。
请别误会,我玩游戏只是为了测试这款游戏的性能,而不是沉迷其中。

脚本测试环境:

  • 设备:iPod 4(没钱买iPod 5)
  • 系统:ios 6.1.6(越狱)
  • 屏幕分辨率:640 * 960
  • 游戏版本:1.8.2

首先设备需要越狱,然后在Cydia里面搜索“触动精灵”并安装。
触动精灵这个应用类似于电脑上的按键精灵,可以执行lua脚本,自带有丰富的函数库,可以很方便地实现各种功能。
但是未注册版只能执行5分钟,如果在5分钟内刷不完体力的话,再多执行几次。也可以配合烧饼加速器使用,这样一般5分钟内能刷完。

视频演示地址:
http://v.youku.com/v_show/id_XNzA3NzYyMzQ4.html

脚本实现方法:

一、操作步骤

脚本需要模拟玩家的操作,操作流程如下:
This is a picture without description

  1. 处于【关卡界面】,点击按钮进入【选择英雄界面】,若提示体力不足则结束。
  2. 处于【选择英雄界面】,点击按钮进入【战斗界面】。
  3. 处于【战斗界面】,点击自动战斗按钮。
  4. 处于【战斗结算界面】,点击继续战斗按钮进入【关卡界面】。
  5. 循环第一步操作。

网络游戏是需要联网的,假设你处于【选择英雄界面】,点击进入副本的按钮后游戏就会请求网络,客户端收到数据后才会跳转到战斗界面。
这个请求网络的响应时间和网速有关,网速慢的话可以要转一两秒的菊花才能进入战斗界面。
如果脚本点击了进入副本的按钮后就马上点击自动战斗按钮是不可以的,因为这时可能还没进入战斗界面。
所以脚本需要判断是否进入了战斗界面,可以通过判断界面某个坐标点是否出现了某个颜色来确定进入了战斗界面。

二、提取关键点颜色

下面以【关卡界面】为例子来说明怎么获取颜色的值:
首先要确定取哪个坐标的颜色,这个坐标的颜色值必须是固定的,而且该坐标在相邻两个界面的颜色不能相同。
因为【战斗结算界面】会跳转到【关卡界面】,所以要找出这两个界面不相同的颜色的坐标点,通过观察可发现左上角那个点(44, 55)符合条件:
This is a picture without description

那么怎么知道这个点的坐标呢,我的做法是把iPod通过usb连接到电脑,然后iPod截屏,电脑用图片处理软件打开截屏图片,就可以获取坐标了。
然后把下面的代码另存为lua文件:

1
2
3
4
5
6
7
8
9
10
--获取某个坐标的颜色
function get_color(x, y)
init("0", 2) --设置屏幕方向:home键在左边
mSleep(2000) --延迟2秒
color = getColor(x, y) --获取坐标上的颜色
hex_color = string.format("%x", color)
dialog(hex_color, 20) --显示颜色20秒
end

get_color(45, 55)

再通过PP助手或者iTools把lua文件复制到/var/mobile/Media/TouchSprite/lua/文件夹里,如下图所示:
This is a picture without description

在触动精灵里点击lua文件,设为启动脚本,再回到游戏按音量键运行脚本,就会弹出坐标(44, 55)处的颜色,如上上图所示。
为什么不在电脑的图片编辑软件里取色呢,因为截图的颜色有偏差,会导致代码判断出错,也可以用代码实现判断两个颜色是否相近来解决这个问题。

三、脚本源码

全部代码如下,目前只在iPod4测试过:

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
-- 保存游戏处于某个界面时,某个坐标点的颜色
local scenes = {
stage = { --关卡界面
pos = {x = 45, y = 55},
color = "f5d36a",
},
hero = { --选择英雄界面
pos = {x = 912, y = 538},
color = "f7da82",
},
battle = { --战斗界面
pos = {x = 53, y = 80},
color = "31241b",
},
reward = { --战斗结算界面
pos = {x = 890, y = 195},
color = "764f32",
},
msgbox = { --体力不足的提示框
pos = {x = 500, y = 210},
color = "b3a290",
},
timeout = { --网络连接超时提示框
pos = {x = 520, y = 330},
color = "694e36",
},
}

--保存要执行的动作,即要点击的坐标
local actions = {
enter_hero = {x = 906, y = 512},
enter_battle = {x = 912, y = 538},
auto_battle = {x = 924, y = 562},
exit_reward = {x = 850, y = 220},
timeout = {x = 520, y = 330},
}


--游戏类
Game = {
--实例化函数
new = function()
local property = {}
setmetatable(property, Game)
return property
end,

--函数入口
main = function(self)

self.init_game() --初始化游戏

while true do
--等待进入关卡界面
if self.wait_for(self, "stage") then
--点击进入选择英雄界面
self.do_action(self, "enter_hero")
--判断是否出现体力不足的提示框
if self.is_in_scene(self, "msgbox", 1000) then
lua_exit() --停止脚本
end
end

--等待出现选择英雄界面
if self.wait_for(self, "hero") then
mSleep(1000)
--点击进入战斗界面
self.do_action(self, "enter_battle")
end

--等待进入战斗界面
if self.wait_for(self, "battle") then
--点击自动战斗按钮
self.do_action(self, "auto_battle")
end

--等待出现战斗结算界面
if self.wait_for(self, "reward") then
--点击退出结算界面
self.do_action(self, "exit_reward")
end
end
end,

--初始化游戏
init_game = function()
init("0", 2) --设置屏幕方向:home键在左边
mSleep(1000) --延迟1秒
end,

--游戏循环等待出现某个场景
wait_for = function(self, scene)

for i = 1, 100 do

--等待1秒判断一次
mSleep(1000)

--如果游戏出现网络超时提示框,就把提示框点掉
if self.is_in_scene(self, "timeout") then
self.do_action(self, "timeout")
end

--如果在某个场景中就返回true
if self.is_in_scene(self, scene) then
return true
end
end

lua_exit() --超过100秒就停止脚本
end,

--点击某个场景
do_action = function(self, action)
local pos = actions[action]
self.click(pos.x, pos.y)
end,

--点击某个坐标
click = function(x, y)
touchDown(0, x, y)
mSleep(100)
touchUp(0, x, y)
end,

--判断游戏是否处于某个场景
is_in_scene = function(self, scene, delay)
mSleep(delay or 0)
local pos = scenes[scene].pos
local color = self.hex(getColor(pos.x, pos.y))
return self.is_similar_color(color, scenes[scene].color)
end,

--判断颜色是否相近
is_similar_color = function(color1, color2)
--这里直接判断颜色是否相等了
return (color1 == color2)
end,

--10进制转16进制
hex = function(number)
return string.format("%x", number)
end,
}
Game.__index = Game

game = Game.new()
game.main(game)

评论