用戶可以通過在腳本中定義一個全局變量UI來實現定義腳本的配置界面, 該界面會在腳本運行前顯示給用戶, 用於讓用戶設置一些腳本的參數, 這些參數的值會賦值給指定的變量, 腳本運行時可以通過訪問這些變量來獲取用戶的配置。下面是一個完整的例子:
UI = {
{ 'TextView{-請如實填寫哦-}' },
{ 'InputBox{}', 'name', '姓名:' },
{ 'DropList{帥哥|美女}', 'sex', '性別:' },
{ 'InputBox{18}', 'age', '年齡:' },
{ 'DropList{是|否}', 'married', '婚否:' },
};
function main()
notifyMessage(string.format("姓名:%s\n性別:%s\n年齡:%s\n婚否:%s", name, sex, age, married));
end
上述腳本播放前會顯示一個如下界面:
全局變量UI是一個Table類型的變量, 其中包含若干個子Table, 每一個子Table都是一個界面上的控件, 控件按照順序自上而下排列, 目前支持3中類型的控件:
1. TextView (靜態文本)
1.1 控件說明
該類型的控件只用來顯示一行文字, 不需要用戶操作
1.2 控件定義
{ 'TextView{顯示的內容}' }
這個Table只有一個字符串成員, 即'TextView{顯示的內容}'
其中的TextView是指定此控件的類型爲靜態文本, {}中的內容即爲該靜態文本顯示的內容
2. InputBox (輸入框)
2.1 控件說明
該類型的控件可以用於讓用戶輸入一些內容, 並可以指定一個變量名, 腳本開始後通過該變量就可以訪問到用戶輸入的內容
2.2 控件定義
{ 'InputBox{默認值}', 'var', '註釋' }
這個Table中有3個字符串成員:
'InputBox{默認值}', 其中的InputBox是指定此控件的類型爲輸入框, {}中的內容是該輸入框中的默認值
'var', 定義一個變量的名字, 腳本開始後可以通過訪問這個變量來獲取用戶輸入的內容
'註釋', 顯示在輸入框上方, 用於說明該輸入框的用途
'InputBox{默認值}', 其中的InputBox是指定此控件的類型爲輸入框, {}中的內容是該輸入框中的默認值
2.3 使用提示
需要注意的是獲取到的變量的值是默認是字符串類型, 你可以使用tonumber()函數來轉換成數字類型來使用。例如
var = tonumber(var);
3. DropList (下拉列表)
3.1 控件說明
該類型的控件可以用於讓用戶在指定的若干個值中選擇其中一個, 並可以指定一個變量名, 腳本開始後通過該變量就可以訪問到用戶選擇的內容
3.2 控件定義
{ 'DropList{選項1|選項2|選項3|...}', 'var', '註釋' }
這個Table中有3個字符串成員:
'DropList{選項1|選項2|選項3|...}', 其中的DropList是指定此控件的類型爲下拉列表, {}中的內容是指定的若干個選項, 每個選項間用|分隔
'var', 定義一個變量的名字, 腳本開始後可以通過訪問這個變量來獲取用戶選擇的內容
'註釋', 顯示在下拉列表上方, 用於說明該下拉列表的用途
使用注意:
全局代碼塊(不包含在任何函數內的代碼塊)會在腳本的main()函數之前被調用, 所以可以在全局代碼塊中對UI變量進行動態的設置, UI變量是一個Table類型的變量, 可以使用Lua的Table庫函數操作, 下面是一個操作UI變量的例子:
file = io.open("/mnt/sdcard/conf.txt"); -- 打開配置文件
data = file:read("*a"); -- 讀取全部內容
file:close(); -- 關閉文件
UI = {
{ 'InputBox{'.. data .. '}', 'demo', '演示:' },
}
function main()
notifyMessage(string.format("%s", demo));
end
擴展函數
函數:logDebug() 系統日誌
函數說明 : 輸出調試信息到系統日誌
函數方法 : logDebug(文本型 contents);
返回值 : 無
參數 | 類型 | 說明 |
---|---|---|
contents | 文本型 | 輸出到日誌文件的內容 |
示例:
logDebug("hello"); -- 輸出"hello"到系統日誌
注意事項:
1.日誌文件所在目錄目錄:
1.1 安卓 android:/mnt/sdcard/touchelf/log/log.txt
1.2 蘋果 ios:/var/touchelf/log/log.txt
2.可以在“觸摸精靈->設置->查看日誌”中查看
函數:mSleep() 延時
函數說明 : 進行毫秒級別延遲
函數方法 : mSleep(整數型 interval);
返回值 : 無
參數 | 類型 | 說明 |
---|---|---|
interval | 整數型 | 腳本暫停執行的時間,單位爲毫秒 |
示例:
mSleep(1000); -- 延遲1秒
mSleep(60*1000); -- 延遲1分鐘
mSleep(60*60*1000); -- 延遲1小時
mSleep(24*60*60*1000); -- 延遲1天
mSleep(365*24*60*60*1000); -- 延遲1年
用在點擊函數中可實現長按不放的效果
touchDown(0,100,200); --按下座標爲100,200的點
mSleep(2000); --延時 2 秒
touchUp(0); --擡起
注意事項:
毫秒與秒換算方式爲 1 秒 (s) = 1000 毫秒 (ms)
函數:notifyMessage() 提示,通知
函數說明 : 以文字提示框的方式通知用戶
函數方法 : notifyMessage(文本型 text, 整數型 interval);
返回值 : 無
參數 | 類型 | 說明 |
---|---|---|
text | 文本型 | 在屏幕上顯示的提示文字 |
interval | 整數型 | 提示多長時間,單位:毫秒,默認值1000 |
示例:
notifyMessage("Hello World"); -- -- 在屏幕上顯示"hello"顯示1秒
notifyMessage("Hello World",3000); -- -- 在屏幕上顯示"hello"顯示3秒
notifyMessage("Hello World \n"..os.date("%M/%D/%Y-%H:%M:%S"),5000); -- -- 在屏幕上顯示"hello"顯示5秒,並換行顯示當前時間
注意事項:
1,當提示框顯示時會影響當前屏幕取色,請合理使用該函數
2,示例裏面使用的 "\n" 爲換行,".."爲字符串連接符號,"os.date()" 爲時間函數,時間函數內的"%M/%D/%Y-%H:%M:%S"爲時間顯示的格式。
函數:notifyVibrate() 震動
函數說明 : 以震動方式通知用戶
函數方法 : notifyVibrate(整數型 interval);
返回值 : 無
參數 | 類型 | 說明 |
---|---|---|
interval | 整數型 | 震動時間,單位:毫秒 |
示例:
notifyVibrate(1000); -- 讓設備震動1秒
注意事項:
使用此函數需在移動設備設置裏打開震動選項。
函數:notifyVoice() 播放音頻
函數說明 : 以播放音頻的方式通知用戶
函數方法 : notifyVoice(文本型 file);
返回值 : 無
參數 | 類型 | 說明 |
---|---|---|
filen | 文本型 | 音頻文件路徑及名字 |
示例:
notifyVoice("/mnt/sdcard/a.mp3"); -- 播放路徑爲"/mnt/sdcard/a.mp3"的音頻
mSleep(5000);
注意事項:
使用此函數需在後面加上延時函數,延時5000即播放音頻5秒鐘。
函數:touchDown() 按下
函數說明 : 發送手指按下事件
函數方法 : touchDown(整數型 ID,整數型 x,整數型 y);
返回值 : 無
參數 | 類型 | 說明 |
---|---|---|
ID | 整數型 | 手指ID, 範圍0~128, 用於標識一個手指 |
X | 整數型 | X座標 |
Y | 整數型 | Y座標 |
示例:
touchDown(0, 100, 100); -- ID爲0的手指在座標爲(100, 100)的點按下
mSleep(100); --延時100毫秒
touchUp(0); -- ID爲0的手指擡起
示例:封裝一個點擊函數
function click(x, y)
touchDown(0, x, y);
mSleep(200);
touchUp(0);
end
--------------調用方法------------
click(100,100);--點擊座標爲100,100的點
示例:封裝一個可控制按下時間的點擊函數
function click(x,y,n)
touchDown(0, x, y);
mSleep(n);
touchUp(0);
end
--------------調用方法------------
click(100,100,1000);--按下座標爲100,100的點延時1秒後擡起
注意事項:
使用 touchDown、touchUp 函數時,中間要插入一定的延時,建議大於 20毫秒,否則可能會出現點擊無效等異常情況。
函數:touchMove() 移動
函數說明 : 發送手指移動事件
函數方法 : touchMove(整數型 ID,整數型 x,整數型 y);
返回值 : 無
參數 | 類型 | 說明 |
---|---|---|
ID | 整數型 | touchDown()時傳入的手指ID |
X | 整數型 | X座標 |
Y | 整數型 | Y座標 |
示例:
touchDown(0, 100, 100); -- ID爲0的手指在座標爲(100, 100)的點按下
mSleep(100); --延時100毫秒
touchMove(0, 200, 100); -- ID爲0的手指滑動到座標爲(200, 100)的點
mSleep(100); --延時100毫秒
touchUp(0); -- ID爲0的手指擡起
示例: 連續移動到指定位置
function clickMove(x1,y1,x2,y2,n)
local w = math.abs(x2-x1);
local h = math.abs(y2-y1);
touchDown(0,x1,y1);
mSleep(50);
if x1 < x2 then
w1 = n;
else
w1 = -n;
end
if y1 < y2 then
h1 = n;
else
h1 = -n;
end
if w >= h then
for i = 1 , w,n do
x1 = x1 + w1;
if y1 == y2 then
else
y1 = y1 + math.ceil(h*h1/w);
end
touchMove(0,x1,y1);
mSleep(10);
end
else
for i = 1 ,h,n do
y1 = y1 + h1;
if x1 ==x2 then
else
x1 = x1 + math.ceil(w*w1/h);
end
touchMove(0,x1,y1);
mSleep(10);
end
end
mSleep(50);
touchUp(0);
end
--------------調用方法----------------
clickMove(100,100,200,200,5);--x1,y1爲起始位置座標,x2、y2爲終點位置座標,n是每次移動多少個像素
函數:touchUp() 擡起
函數說明 : 發送手指擡起事件
函數方法 : touchUp(整數型 ID);
返回值 : 無
參數 | 類型 | 說明 |
---|---|---|
ID | 整數型 | touchDown()時傳入的手指ID |
示例:
touchDown(0, 100, 100); -- ID爲0的手指在座標爲(100, 100)的點按下
mSleep(100); --延時100毫秒
touchUp(0); -- ID爲0的手指擡起
函數:keyDown() 按下物理按鍵
函數說明 : 發送物理按鍵按下事件
函數方法 : keyDown(文本型 string);
返回值 : 無
參數 | 類型 | 說明 |
---|---|---|
string | 文本型 | 物理鍵名稱 |
示例:單擊一次HOME按鍵
keyDown('HOME'); -- HOME鍵按下
mSleep(100); --延時100毫秒
keyUp('HOME'); -- HOME鍵擡起
注意事項:
1,Android觸摸精靈現在支持的有'HOME'、'BACK'、'MENU',
2,IOS觸摸精靈現在支持的有'HOME'
3,其他按鍵可參照【附錄】觸摸精靈模擬物理按鍵的方法
函數:keyUp() 擡起物理按鍵
函數說明 : 發送物理按鍵擡起事件
函數方法 : keyUp(文本型 string);
返回值 : 無
參數 | 類型 | 說明 |
---|---|---|
string | 文本型 | 物理鍵名稱 |
示例:單擊一次HOME按鍵
keyDown('HOME'); -- HOME鍵按下
mSleep(100); --延時100毫秒
keyUp('HOME'); -- HOME鍵擡起
注意事項:
1,Android觸摸精靈現在支持的有'HOME'、'BACK'、'MENU',
2,IOS觸摸精靈現在支持的有'HOME'
3,其他按鍵可參照【附錄】觸摸精靈模擬物理按鍵的方法
函數:getColor() 獲取指定像素的顏色
函數說明 : 獲取指定像素的顏色
函數方法 : getColor(整數型x, 整數型y);
返回值 : 整型 color
參數 | 類型 | 說明 |
---|---|---|
X | 整數型 | 將獲取顏色值的X座標 |
Y | 整數型 | 將獲取顏色值的y座標 |
返回值 | 類型 | 說明 |
---|---|---|
color | 整數型 | x,y座標點的十進制顏色值 |
示例:
c = getColor(100, 100); -- 將座標爲(100,100)的點的顏色保存在變量c中
if c == 0x0000ff then -- 如果該點顏色爲0x0000ff(純藍色)
touchDown(0, 100, 100); -- 那麼點擊該座標
touchUp(0);
end
---------------也可以寫成-------------
if getColor(100, 100) == 0x0000ff then -- 如果該點顏色爲0x0000ff(純藍色)
touchDown(0, 100, 100); -- 那麼點擊該座標
touchUp(0);
end
注意事項:
1,getColor()返回的是十進制顏色值,如純白色獲取到的數值是16777215。十進制數值和十六進制顏色對比時,十六進制前面需加"0x"即"0xFFFFFF"。
2,在十六進制顏色值"0xAABBCC"中,"AA"對應的是紅(R,Red),"BB"對應的是綠(G,Green),"CC"對應的是藍(B,Blue)。
語法說明:
c = getColor(100, 100); 中"="的作用是賦值,將getColor(100, 100)獲得的值賦值給c這個變量。
if getColor(100, 100) == 0x0000ff then 中的"=="是關係運算符中等於的意思。
翻譯成中文就是:如果 100,100這個座標的顏色等於 0x0000ff 那麼執行下面的語句。不等於的寫法是"~="
函數:getColorRGB() 獲取指定像素顏色的R、G、B三個值
函數說明 : 獲取指定像素顏色的R、G、B三個值
函數方法 : getColorRGB(整數型x, 整數型y);
返回值 : 整型 R,G,B
參數 | 類型 | 說明 |
---|---|---|
X | 整數型 | 將獲取顏色值的X座標 |
Y | 整數型 | 將獲取顏色值的y座標 |
返回值 | 類型 | 說明 |
---|---|---|
R | 整數型 | x,y座標點的顏色R(紅色)值 |
G | 整數型 | x,y座標點的顏色G(綠色)值 |
B | 整數型 | x,y座標點的顏色B(藍色)值 |
示例:
r, g, b = getColorRGB(100, 100); -- 將座標爲(100,100)的點的顏色的R、G、B分別保存在變量r、g、b中
if r == 0x00 and b == 0x00 and g == 0xff then -- 如果該點顏色爲0x0000ff(純藍色)
touchDown(0, 100, 100); -- 那麼點擊該座標
touchUp(0);
end
示例:封裝一個單點模糊比對函數
function compare_color_point(x,y,r,g,b,sim)
local lr,lg,lb;
lr,lg,lb = getColorRGB(x,y);
if math.abs(lr-r) > sim then
return false;
end
if math.abs(lg-g) > sim then
return false;
end
if math.abs(lb-b) > sim then
return false;
end
return true;
end
-----調用方法
if compare_color_point(100,100,255,255,255,30) then
touchDown(0, 100, 100);
mSleep(50)
touchUp(0);
end
--sim值越小精確度越高,範圍是 0-255
函數:findColor() 全屏找色
函數說明 : 全屏尋找符合指定顏色的座標,不支持模糊查找。
函數方法 : findColor(整型 color);
返回值 : 整數型 x, y
參數 | 類型 | 說明 |
---|---|---|
color | 整數型 | 將要找的十六進制顏色值 |
返回值 | 類型 | 說明 |
---|---|---|
x | 整數型 | 找到的座標X值,未找到返回 -1 |
y | 整數型 | 找到的座標Y值,未找到返回 -1 |
示例
x, y = findColor(0x0000ff); -- 在全屏範圍找到第一個顏色爲0x0000ff的點, 將其座標保存到變量x和y中
if x ~= -1 and y ~= -1 then -- 如果找到了
touchDown(0, x, y); -- 點擊那個點
touchUp(0);
end
注意事項:
1,未找到時返回 (-1,-1),示例中使用的"~=" 爲關係運算符"不等於"的意思。 "and"爲邏輯運算符 "和"的意思。
2,儘量不要使用這個函數,全屏找色耗費資源,而且由於顏色可能會產生肉眼不可見的變化導致找色失敗,建議使用區域模糊找色。
LUA邏輯運算符:
and or not
邏輯運算符認爲false和nil是假(false),其他爲真,0也是true.
and和or的運算結果不是true和false,而是和它的兩個操作數相關。
a and b -- 如果a爲false,則返回a,否則返回b
a or b -- 如果a爲true,則返回a,否則返回b
例如:
print(4 and 5) --> 5
print(nil and 13) --> nil
print(false and 13) --> false
print(4 or 5) --> 4
print(false or 5) --> 5
函數:findColorFuzzy() 全屏模糊找色
函數說明 : 全屏尋找符合指定顏色的座標,支持模糊查找。
函數方法 : findColorFuzzy(整型 color,整數型 degree);
返回值 : 整數型 x, y
參數 | 類型 | 說明 |
---|---|---|
color | 整數型 | 將要找的十六進制顏色值 |
degree | 整數型 | 精度,範圍:1 ~ 100,數值越大精度越高,100爲完全比配 |
返回值 | 類型 | 說明 |
---|---|---|
x | 整數型 | 找到的座標X值,未找到返回 -1 |
y | 整數型 | 找到的座標Y值,未找到返回 -1 |
示例
x, y = findColorFuzzy(0x0000ff, 90); -- 在全屏範圍找到第一個顏色爲0x0000ff的點, 精確度爲90%, 將其座標保存到變量x和y中
if x ~= -1 and y ~= -1 then -- 如果找到了
touchDown(0, x, y); -- 點擊那個點
touchUp(0);
end
注意事項:
1,未找到時返回 (-1,-1),示例中使用的"~=" 爲關係運算符"不等於"的意思。 "and"爲邏輯運算符 "和"的意思。
2,全屏找色耗費資源,儘量不要使用這個函數。
函數:findColorInRegion() 區域找色
函數說明 : 區域尋找符合指定顏色的座標,不支持模糊查找。
函數方法 : findColorInRegion(整型 color,整數型 x1, 整數型 y1, 整數型 x2, 整數型 y2);
返回值 : 整數型 x, y
參數 | 類型 | 說明 |
---|---|---|
color | 整數型 | 將要找的十六進制顏色值 |
x1 | 整數型 | 欲尋找的區域左上角的X座標 |
y1 | 整數型 | 欲尋找的區域左上角的y座標 |
x2 | 整數型 | 欲尋找的區域右下角的X座標 |
y2 | 整數型 | 欲尋找的區域右下角的X座標 |
返回值 | 類型 | 說明 |
---|---|---|
x | 整數型 | 找到的座標X值,未找到返回 -1 |
y | 整數型 | 找到的座標Y值,未找到返回 -1 |
示例
x, y = findColorInRegion(0x0000ff, 100, 100, 200, 200); -- 在區域[(100,100)(200,200)]範圍找到第一個顏色爲0x0000ff的點, 將其座標保存到變量x和y中
if x ~= -1 and y ~= -1 then -- 如果找到了
touchDown(0, x, y); -- 點擊那個點
touchUp(0);
end
注意事項:
1,未找到時返回 (-1,-1),示例中使用的"~=" 爲關係運算符"不等於"的意思。 "and"爲邏輯運算符 "和"的意思。
2,而且由於顏色可能會產生肉眼不可見的變化導致找色失敗,建議使用區域模糊找色。
函數:findColorInRegionFuzzy() 區域模糊找色
函數說明 : 區域尋找符合指定顏色的座標,支持模糊查找。
函數方法 : findColorInRegionFuzzy(整型 color, 整數型 degree,整數型 x1, 整數型 y1, 整數型 x2, 整數型 y2);
返回值 : 整數型 x, y
參數 | 類型 | 說明 |
---|---|---|
color | 整數型 | 將要找的十六進制顏色值 |
degree | 整數型 | 精度,範圍:1 ~ 100,數值越大精度越高,100爲完全比配 |
x1 | 整數型 | 欲尋找的區域左上角的X座標 |
y1 | 整數型 | 欲尋找的區域左上角的y座標 |
x2 | 整數型 | 欲尋找的區域右下角的X座標 |
y2 | 整數型 | 欲尋找的區域右下角的X座標 |
返回值 | 類型 | 說明 |
---|---|---|
x | 整數型 | 找到的座標X值,未找到返回 -1 |
y | 整數型 | 找到的座標Y值,未找到返回 -1 |
示例
x, y = findColorInRegionFuzzy(0x0000ff, 90, 100, 100, 200, 200); -- 在區域[(100,100)(200,200)]範圍找到第一個顏色爲0x0000ff的點, 精確度爲90%, 將其座標保存到變量x和y中
if x ~= -1 and y ~= -1 then -- 如果找到了
touchDown(0, x, y); -- 點擊那個點
touchUp(0);
end
示例:此函數單點模糊找色使用方法
x, y = findColorInRegionFuzzy(0x0000ff, 90, 100, 100, 100, 100); -- 將左上角和右下角兩個座標寫成一樣,作用就是判斷(100,100)這個座標顏色是否爲0x0000ff, 精確度爲90%, 將其座標保存到變量x和y中
if x ~= -1 and y ~= -1 then -- 如果找到了
touchDown(0, x, y); -- 點擊那個點
touchUp(0);
end
示例:不斷降低精確度的寫法
for sim = 100, 50, -1 do --使用 for 循環不斷降低精確度(建議精確度不低於50%)
x, y = findColorInRegionFuzzy(0x0000ff, sim, 100, 100, 100, 100);
if x ~= -1 and y ~= -1 then --如果在指定區域找到某點符合條件
touchDown(0, x, y); --那麼單擊該點
touchUp(0);
break; --並跳出循環
end
end
注意事項:
1,未找到時返回 (-1,-1),示例中使用的"~=" 爲關係運算符"不等於"的意思。 "and"爲邏輯運算符 "和"的意思。
函數:findMultiColorInRegionFuzzy() 多點區域模糊找色
函數說明 : 區域內尋找多個符合條件的點,支持模糊查找。
函數方法 : findMultiColorInRegionFuzzy(數組 table, 整數型 degree,整數型 x1, 整數型 y1, 整數型 x2, 整數型 y2);
返回值 : 整數型 x, y
參數 | 類型 | 說明 |
---|---|---|
table | 數組 | 要找的顏色數組 |
degree | 整數型 | 精度,範圍:1 ~ 100,數值越大精度越高,100爲完全比配 |
x1 | 整數型 | 欲尋找的區域左上角的X座標 |
y1 | 整數型 | 欲尋找的區域左上角的y座標 |
x2 | 整數型 | 欲尋找的區域右下角的X座標 |
y2 | 整數型 | 欲尋找的區域右下角的X座標 |
返回值 | 類型 | 說明 |
---|---|---|
x | 整數型 | 找到的座標X值,未找到返回 -1 |
y | 整數型 | 找到的座標Y值,未找到返回 -1 |
示例
-- 在區域[(10,10)(200,200)]範圍內以90%的精確度找一個滿足以下條件的點:
-- 1. 其顏色爲0x0000ff
-- 2. 其X座標+10,Y座標+20的座標上的點顏色爲0x00ff00
-- 3. 其X座標-10,Y座標-20的座標上的點顏色爲0xff0000
x, y = findMultiColorInRegionFuzzy({0x0000ff, 10, 20, 0x00ff00, -10, -20, 0xff0000 }, 90, 10, 10, 200, 200);
if x ~= -1 and y ~= -1 then -- 如果找到了
touchDown(0, x, y); -- 點擊那個點
touchUp(0);
end
指導:
此函數作用是先找到第一個基準點後,在這個點周圍按照數組格式來查找其他的點,數組內所有點都符合要求即爲找到。
通過多點我們可以建立一個大概的模型,比如一個關閉窗口的叉圖標
假如下面是一個5*5的像素的圖片
10001
01010
00100
01010
10001
通過取1位置的顏色用9個像素點就可以建立一個叉的模型,甚至用5個座標點就可以建立一個大致的模型
10001
00000
00100
00000
10001
假設第一個1座標是100,100,所有1的顏色爲0x123456
那麼第二個點座標就爲104,100,相對第一個座標的偏移值爲(4,0);
那麼第三個點座標就爲102,102,相對第一個座標的偏移值爲(2,2);
那麼第四個點座標就爲100,104,相對第一個座標的偏移值爲(0,4);
那麼第五個點座標就爲104,104,相對第一個座標的偏移值爲(4,4);
把以上5個座標點變成多點找色的數組格式爲:
{0x123456, 4,0, 0x123456, 2,2, 0x123456, 0,4, 0x123456, 4,4, 0x123456 }
找色代碼爲:
x, y = findMultiColorInRegionFuzzy({0x123456, 4,0, 0x123456, 2,2, 0x123456, 0,4, 0x123456, 4,4, 0x123456 }, 90, 50, 50 150, 150);
返回的座標爲(100,100),即使這個圖標在(50, 50 150, 150)這個範圍內進行了偏移也可準確的找到該圖標並點擊。
用5個點建立的模型從效率上來說就比25個點效率要高很多。
甚至我們可以把數字,字母,文字建立成數組模型來實現找字,判斷金幣數量等操作。
注意事項:
1,數組內的座標爲第一個座標的相對值。
2,多點找色代碼和數組可以通過觸摸精靈腳本編輯器的找色工具生成。
3,精確度設置的越低就會增大誤判的可能性,建議設置60~90之間。
4,善用此函數可完全替代找圖,並提高腳本效率。
函數:findImage() 全屏找圖
函數說明 : 全屏尋找符合指定圖案,返回左上角座標,不支持模糊查找。
函數方法 : findImage(文本型 picpath, 整型 alpha);
返回值 : 整數型 x, y
參數 | 類型 | 說明 |
---|---|---|
picpath | 文本型 | 要找的圖片的路徑, 只支持BMP格式 |
alpha | 整數型 | 指定圖片中透明顏色(可不寫) |
返回值 | 類型 | 說明 |
---|---|---|
x | 整數型 | 找到的座標X值,未找到返回 -1 |
y | 整數型 | 找到的座標Y值,未找到返回 -1 |
示例
x, y = findImage("/mnt/sdcard/a.bmp"); -- 在全屏範圍找到第一個路徑爲"/mnt/sdcar/a.bmp"的圖片, 將其左上角座標保存到變量x和y中
if x ~= -1 and y ~= -1 then -- 如果找到了
touchDown(0, x, y); -- 點擊那個點
touchUp(0);
end
示例:忽略圖片中的黑色
x, y = findImage("a.bmp", 0x000000); -- 在全屏範圍找到第一個路徑爲"/mnt/sdcar/a.bmp"的圖片, 忽略圖片中顏色爲0x000000(黑色)的點, 將其左上角座標保存到變量x和y中
if x ~= -1 and y ~= -1 then -- 如果找到了
touchDown(0, x, y); -- 點擊那個點
touchUp(0);
end
教程:透明找圖時圖片的處理
在找圖時,如果需要忽略掉一部分會變動的背景,這時候可以使用透明找圖,將要找的圖片中不參與比較的顏色填充成一個固定的顏色,然後在找圖時指定該顏色爲透明色,這樣在找圖時,即使那部分畫面變了,也一樣可以找到圖片。
如下圖是原圖,除文字以外的部分背景是變化的,用其他找圖時會因爲變化的背景導致圖片找不到:
那麼可以將圖片處理成下圖這樣,然後在找圖時指定黑色(0x000000)爲透明色,那麼就算是背景變化,也可以找到了。
注意事項:
1,全屏找圖耗費資源,速度慢,不推薦使用。
2,圖片路徑不寫爲默認res目錄,其他目錄請填寫絕對路徑。
3,圖片只支持BMP格式。
函數:findImageFuzzy() 全屏模糊找圖
函數說明 : 全屏尋找符合指定圖案,返回左上角座標,支持模糊查找。
函數方法 : findImageFuzzy(文本型 picpath, 整數型 degree,整型 alpha);
返回值 : 整數型 x, y
參數 | 類型 | 說明 |
---|---|---|
picpath | 文本型 | 要找的圖片的路徑, 只支持BMP格式 |
degree | 整數型 | 精度,範圍:1 ~ 100,數值越大精度越高,100爲完全比配 |
alpha | 整數型 | 指定圖片中透明顏色(可不寫) |
返回值 | 類型 | 說明 |
---|---|---|
x | 整數型 | 找到的座標X值,未找到返回 -1 |
y | 整數型 | 找到的座標Y值,未找到返回 -1 |
示例
x, y = findImageFuzzy("/mnt/sdcard/a.bmp", 90, 0x000000); -- 在全屏範圍找到第一個路徑爲"/mnt/sdcar/a.bmp"的圖片, 精確度爲90, 忽略圖片中顏色爲0x000000(黑色)的點, 將其左上角座標保存到變量x和y中
if x ~= -1 and y ~= -1 then -- 如果找到了
touchDown(0, x, y); -- 點擊那個點
touchUp(0);
end
注意事項:
1,全屏找圖耗費資源,速度慢,不推薦使用。
2,圖片路徑不寫爲默認res目錄,其他目錄請填寫絕對路徑。
3,圖片只支持BMP格式。
函數:findImageInRegion() 區域找圖
函數說明 : 在指定區域中尋找符合指定圖案,返回左上角座標,不支持模糊查找。
函數方法 : findImageInRegion(文本型 picpath, 整數型 x1, 整數型 y1, 整數型 x2, 整數型 y2,整型 alpha);
返回值 : 整數型 x, y
參數 | 類型 | 說明 |
---|---|---|
picpath | 文本型 | 要找的圖片的路徑, 只支持BMP格式 |
x1 | 整數型 | 欲尋找的區域左上角的X座標 |
y1 | 整數型 | 欲尋找的區域左上角的y座標 |
x2 | 整數型 | 欲尋找的區域右下角的X座標 |
y2 | 整數型 | 欲尋找的區域右下角的X座標 |
alpha | 整數型 | 指定圖片中透明顏色(可不寫) |
返回值 | 類型 | 說明 |
---|---|---|
x | 整數型 | 找到的座標X值,未找到返回 -1 |
y | 整數型 | 找到的座標Y值,未找到返回 -1 |
示例
x, y = findImageInRegion("/mnt/sdcard/a.bmp", 100, 100, 200, 200, 0x000000); -- 在區域[(100,100)(200,200)]範圍找到第一個路徑爲"/mnt/sdcar/a.bmp"的圖片, 忽略圖片中顏色爲0x000000(黑色)的點, 將其左上角座標保存到變量x和y中
if x ~= -1 and y ~= -1 then -- 如果找到了
touchDown(0, x, y); -- 點擊那個點
touchUp(0);
end
注意事項:
1,由於顏色可能會產生肉眼不可見的變化導致找圖失敗,建議使用區域模糊找圖。
2,圖片路徑不寫爲默認res目錄,其他目錄請填寫絕對路徑。
3,圖片只支持BMP格式。
函數:findImageInRegionFuzzy() 區域模糊找圖
函數說明 : 在指定區域中尋找符合指定圖案,返回左上角座標,支持模糊查找。
函數方法 : findImageInRegionFuzzy(文本型 picpath, 整數型 degree, 整數型 x1, 整數型 y1, 整數型 x2, 整數型 y2,整型 alpha);
返回值 : 整數型 x, y
參數 | 類型 | 說明 |
---|---|---|
picpath | 文本型 | 要找的圖片的路徑, 只支持BMP格式 |
degree | 整數型 | 精度,範圍:1 ~ 100,數值越大精度越高,100爲完全比配 |
x1 | 整數型 | 欲尋找的區域左上角的X座標 |
y1 | 整數型 | 欲尋找的區域左上角的y座標 |
x2 | 整數型 | 欲尋找的區域右下角的X座標 |
y2 | 整數型 | 欲尋找的區域右下角的X座標 |
alpha | 整數型 | 指定圖片中透明顏色(可不寫) |
返回值 | 類型 | 說明 |
---|---|---|
x | 整數型 | 找到的座標X值,未找到返回 -1 |
y | 整數型 | 找到的座標Y值,未找到返回 -1 |
示例
x, y = findImageInRegionFuzzy("/mnt/sdcard/a.bmp", 90, 100, 100, 200, 200, 0x000000); -- 在區域[(100,100)(200,200)]範圍找到第一個路徑爲"/mnt/sdcar/a.bmp"的圖片, 精確度爲90, 忽略圖片中顏色爲0x000000(黑色)的點, 將其左上角座標保存到變量x和y中
if x ~= -1 and y ~= -1 then -- 如果找到了
touchDown(0, x, y); -- 點擊那個點
touchUp(0);
end
注意事項:
1,圖片路徑不寫爲默認res目錄,其他目錄請填寫絕對路徑。
2,圖片只支持BMP格式。
函數:snapshotScreen() 全屏截圖
函數說明 : 截取屏幕並生成指定格式的圖片文件。
函數方法 : snapshotScreen(文本型 picpath, 數字型 quality);
返回值 : 無
參數 | 類型 | 說明 |
---|---|---|
picpath | 文本型 | 保存截圖的路徑, 支持BMP格式和JPG格式, 根據文件名後綴智能判斷 |
quality | 數字型 | 圖片尺寸縮放百分比, 有效範圍爲10~100, 默認爲100(可選) |
示例
snapshotScreen("/mnt/sdcard/a.bmp"); -- 將全屏截圖保存到路徑爲"/mnt/sdcard/a.bmp"的圖片中, 格式爲BMP
snapshotScreen("/mnt/sdcard/a.jpg, 50"); -- 將全屏截圖保存到路徑爲"/mnt/sdcard/a.jpg"的圖片中, 格式爲JPG, 並且尺寸縮小爲原始尺寸的50%
snapshotScreen(string.format( "/mnt/sdcard/%s.bmp",os.time())); -- 以時間戳命名進行截圖,防止截圖重名被覆蓋
注意事項:
1,圖片路徑不寫爲默認res目錄,其他目錄請填寫絕對路徑。
2,保存圖片的格式可爲 bmp, jpg。
3,當截圖爲JPG可使用quality參數對圖片進行片尺寸縮放。
4,os.time()爲 Lua 操作系統庫函數。string.format()爲String庫函數。
函數:snapshotRegion() 區域截圖
函數說明 : 截取屏幕中指定區域的圖像並生成指定格式的圖片文件。
函數方法 : snapshotRegion(文本型 picpath,整數型 x1,整數型y1, 整數型 x2, 整數型 y2, 數字型 quality);
返回值 : 無
參數 | 類型 | 說明 |
---|---|---|
picpath | 文本型 | 保存截圖的路徑, 支持BMP格式和JPG格式, 根據文件名後綴智能判斷 |
x1 | 整數型 | 截圖區域左上角的X座標 |
y1 | 整數型 | 截圖區域左上角的y座標 |
x2 | 整數型 | 截圖區域右下角的X座標 |
y2 | 整數型 | 截圖區域右下角的X座標 |
quality | 數字型 | 圖片尺寸縮放百分比, 有效範圍爲10~100, 默認爲100(可選) |
示例
snapshotRegion("/mnt/sdcard/a.bmp", 100, 100, 200, 200); -- 將區域[(100,100)(200,200)]的截圖保存到路徑爲/mnt/sdcard/a.bmp的圖片中, 格式爲BMP
snapshotRegion("/mnt/sdcard/a.jpg", 100, 100, 200, 200, 50); -- 將區域[(100,100)(200,200)]的截圖保存到路徑爲/mnt/sdcard/a.jpg的圖片中, 格式爲JPG, 並且尺寸縮小爲原始尺寸的50%
snapshotScreen(string.format( "/mnt/sdcard/%s.bmp",os.time()), 100, 100, 200, 200); -- 以時間戳命名進行截圖,防止截圖重名被覆蓋
注意事項:
1,圖片路徑不寫爲默認res目錄,其他目錄請填寫絕對路徑。
2,保存圖片的格式可爲 bmp, jpg。
3,當截圖爲JPG可使用quality參數對圖片進行片尺寸縮放。
4,os.time()爲 Lua 操作系統庫函數。string.format()爲String庫函數。
函數:localOcrText() 本地圖片識別
函數說明 : 將指定區域的圖像識別成文字。
函數方法 : localOcrText(文本型 ocrpath,文本型 language,整數型 x1,整數型y1, 整數型 x2, 整數型 y2, 文本型 list);
返回值 : 文本型 text
說明:使用該函數需要ocr語言包。
下載地址:http://pan.baidu.com/s/1kXYMb
下載後, 將解壓後的tessdata目錄複製到設備中
參數 | 類型 | 說明 |
---|---|---|
ocrpath | 文本型 | 語言包tessdata目錄的路徑 |
language | 文本型 | 語言類型 'eng' : 英文語言類型 'chi_sim' : 中文語言類型 |
x1 | 整數型 | 待識別圖片區域的左上角X座標 |
y1 | 整數型 | 待識別圖片區域的左上角Y座標 |
x2 | 整數型 | 待識別圖片區域的右下角X座標 |
y2 | 整數型 | 待識別圖片區域的右下角Y座標 |
list | 文本型 | 設置白名單, 只有白名單中的字符纔會被識別(可選) |
返回值 | 類型 | 說明 |
---|---|---|
text | 文本型 | 圖片識別後得到的答案, 失敗的話返回空字符串 |
示例:識別中文
code = localOcrText("/mnt/sdcard/touchelf/tessdata", -- 語言包tessdata目錄在設備中的路徑
"chi_sim", -- 語言類型爲中文
100, -- 圖片左上角X座標爲100
100, -- 圖片左上角Y座標爲100
200, -- 圖片右下角X座標爲200
200); -- 圖片右下角Y座標爲200
if code == "" then
notifyMessage("識別失敗");
else
notifyMessage(string.format("識別成功: %s", code));
end
示例:識別英文和數字
code = localOcrText("/mnt/sdcard/touchelf/tessdata", -- 語言包tessdata目錄在設備中的路徑
"eng", -- 語言類型爲英文
100, -- 圖片左上角X座標爲100
100, -- 圖片左上角Y座標爲100
200, -- 圖片右下角X座標爲200
200); -- 圖片右下角Y座標爲200
if code == "" then
notifyMessage("識別失敗");
else
notifyMessage(string.format("識別成功: %s", code));
end
示例:只識別數字
code = localOcrText("/mnt/sdcard/touchelf/tessdata", -- 語言包tessdata目錄在設備中的路徑
"eng", -- 語言類型爲中文
100, -- 圖片左上角X座標爲100
100, -- 圖片左上角Y座標爲100
200, -- 圖片右下角X座標爲200
200, -- 圖片右下角Y座標爲200
"0123456789"); -- 設置白名單字符串, 只識別數字
if code == "" then
notifyMessage("識別失敗");
else
notifyMessage(string.format("識別成功: %s", code));
end
注意事項:
1,該函數對非正規字體識別欠佳,建議識別一些背景無雜色的英文和數字。
2,需要下載ocr語言包。
函數:cloudOcrInit() 選擇遠程代答平臺
函數說明 : 選擇遠程代答平臺。
函數方法 : cloudOcrInit(整數型 platform);
返回值 : 無
參數 | 類型 | 說明 |
---|---|---|
platform | 整數型 | 遠程代答平臺ID, 默認爲0 |
0 : 好愛答題 http://www.haoi23.net
1 : 打碼兔答題 http://www.dama2.com
示例
cloudOcrInit(1); -- 設置遠程代答平臺爲打碼兔
注意事項:
1,使用好愛答題時可不寫此函數。
2,由於好愛經常出問題,建議使用打碼兔平臺。
3,第一次使用打碼兔請去打碼兔後臺設置觸摸精靈爲白名單。否則會默認爲黑名單不能返回答案。
函數:cloudOcrText() 遠程代答
函數說明 : 連接cloudOcrInit()選擇的答題平臺進行圖片識別。
函數方法 : cloudOcrText(文本型 key,文本型 type,整數型 x1,整數型y1, 整數型 x2, 整數型 y2, 整數型 timeout);
返回值 : 文本型 code
參數 | 類型 | 說明 |
---|---|---|
key | 文本型 | 用戶名及密碼, 根據不同平臺分別設置 |
type | 文本型 | 題目類型, 請前往選擇的代答平臺的官網查詢 |
x1 | 整數型 | 待識別圖片區域的左上角X座標 |
y1 | 整數型 | 待識別圖片區域的左上角Y座標 |
x2 | 整數型 | 待識別圖片區域的右下角X座標 |
y2 | 整數型 | 待識別圖片區域的右下角Y座標 |
timeout | 整數型 | 超時時間, 範圍爲20-600秒 |
好愛答題key : 密碼串(http://www.haoi23.net註冊並登陸後, 在會員中心獲取), 如username|9CF16235AD9EFBD3F233265DF9400E6A
打碼兔答題key : 用戶名|密碼, 如username|password
返回值 | 類型 | 說明 |
---|---|---|
code | 文本型 | 圖片識別後得到的答案, 失敗的話返回空字符串 |
示例
cloudOcrInit(0); -- 選擇代答平臺爲好愛答題
code = cloudOcrText("username|PASSWORDAD9EFBD3F233265DF9400E6A", -- 好愛答題參數1爲密碼串(http://www.haoi23.net註冊並登陸後, 在會員中心獲取)
"1004", -- 題目類型爲"1004"(4位數字字母)
100, -- 圖片左上角X座標爲100
100, -- 圖片左上角Y座標爲100
200, -- 圖片右下角X座標爲200
200, -- 圖片右下角Y座標爲200
600); -- 超時時間爲600秒
if code == "" then
notifyMessage("識別失敗");
else
notifyMessage(string.format("識別成功: %s", code));
end
函數:cloudOcrTextEx() 遠程合併圖片代答
函數說明 : 將參數中指定的任意個數的圖片合併成一個圖片後, 連接cloudOcrInit()選擇的遠程答題平臺進行圖片識別。
函數方法 : cloudOcrTextEx(文本型 key,文本型 type, 整數型 timeout,文本型 picpath1,文本型 picpath2,...,文本型 picpathn,);
返回值 : 文本型 code
參數 | 類型 | 說明 |
---|---|---|
key | 文本型 | 用戶名及密碼, 根據不同平臺分別設置 |
type | 文本型 | 題目類型, 請前往選擇的代答平臺的官網查詢 |
timeout | 整數型 | 超時時間, 範圍爲20-600秒 |
picpath1 | 文本型 | 待合併的第一個圖片的路徑 |
picpath2 | 文本型 | 待合併的第二個圖片的路徑 |
picpath... | 文本型 | 待合併的第...個圖片的路徑 |
picpathn | 文本型 | 待合併的第n個圖片的路徑 |
好愛答題key : 密碼串(http://www.haoi23.net註冊並登陸後, 在會員中心獲取), 如username|9CF16235AD9EFBD3F233265DF9400E6A
打碼兔答題key : 用戶名|密碼, 如username|password
返回值 | 類型 | 說明 |
---|---|---|
code | 文本型 | 圖片識別後得到的答案, 失敗的話返回空字符串 |
示例:合併三張圖片進行遠程識別
snapshotScreen("/var/touchelf/1.bmp"); -- 將屏幕截圖爲/var/touchelf/1.bmp圖片
snapshotScreen("/var/touchelf/2.bmp"); -- 將屏幕截圖爲/var/touchelf/2.bmp圖片
snapshotScreen("/var/touchelf/3.bmp"); -- 將屏幕截圖爲/var/touchelf/3.bmp圖片
-------------------------------------------
-- 下面的代碼將1.bmp、2.bmp和3.bmp合併成一個圖片後
-- 發送到打碼兔遠程代答平臺進行圖片識別
-------------------------------------------
cloudOcrInit(1); -- 選擇代答平臺爲打碼兔答題
code = cloudOcrTextEx("username|password", -- 打碼兔答題參數1爲"用戶名|密碼"
"1004", -- 題目類型爲"1004"(4位數字字母)
600, -- 超時時間爲600秒
"/var/touchelf/1.bmp", -- 待合併的第一個圖片
"/var/touchelf/2.bmp", -- 待合併的第二個圖片
"/var/touchelf/3.bmp"); -- 待合併的第三個圖片
if code == "" then
notifyMessage("識別失敗");
else
notifyMessage(string.format("識別成功: %s", code));
end
函數:keepScreen() 屏幕保持 緩存屏幕數據
函數說明 : 開啓/關閉屏幕保持。
函數方法 : keepScreen(邏輯型 flag);
返回值 : 無
參數 | 類型 | 說明 |
---|---|---|
flag | 邏輯型 | 開啓/關閉屏幕保持 |
示例
keepScreen(true); -- 開啓屏幕保持
if getColor(100, 100) == 0x000000 or getColor(200, 200) == 0x000000 then -- 進行2次取色, 由於啓用了屏幕保持, 這2次取色不會重新獲取2次屏幕圖像, 這樣可以提高性能
notifyMessage("yes"); --如果(100,100)和(200,200)座標有一個顏色爲黑色, 輸出"yes"
else -- 否則
notifyMessage("no"); -- 輸出"no"
end
keepScreen(false); -- 關閉屏幕保持
注意事項:
1,當使用keepScreen(true);開啓屏幕保持時, 後續的找圖、找色等函數不會重新獲取屏幕圖像, 而是使用開啓屏幕保持之前的屏幕圖像,否則每次使用找圖找色等函數都將截取一次屏幕內容。
2,當使用 keepScreen(false);關閉屏幕保持時, 後續的找圖、找色等函數會每次都重新獲取屏幕圖像。
3,安卓版支持性能模式的設備不需要使用此函數。
4,蘋果版和安卓兼容模式下使用此函數可顯著提升找色速度。
流程圖:
函數:rotateScreen() 旋轉屏幕的座標體系
函數說明 : 旋轉屏幕的座標體系, 後續的找圖、找色、截圖、觸摸動作都會使用新的座標體系
函數方法 : rotateScreen(整數型 Angle);
返回值 : 無
參數 | 類型 | 說明 |
---|---|---|
Angle | 整數型 | 旋轉角度 |
0: 保持原本的座標體系。對於IOS設備來說, 此時HOME鍵在下方時的屏幕左上角爲原點
90: 座標系統向右轉90度。對於IOS設備來說, 此時HOME鍵在右方時的屏幕左上角爲原點
-90: 座標系統向左轉90度。對於IOS設備來說, 此時HOME鍵在左方時的屏幕左上角爲原點
180: 座標系統倒立。對於IOS設備來說, 此時HOME鍵在下方時的屏幕左上角爲原點
示例
rotateScreen(90); -- 旋轉座標體系向右90度, 大多數橫屏遊戲使用此座標體系.
touchDown(0, 100, 100); -- 發送觸摸動作, 此時點擊的點使用新的座標體系.
touchUp(0);
示例 臨時旋轉後恢復原始座標系
rotateScreen(90); -- 旋轉座標體系向右90度
snapshotRegion("/mnt/sdcard/a.bmp", 100, 100, 200, 200);--截一張新的座標體系下的圖
rotateScreen(0); -- 恢復座標體系
函數:copyText() 複製文字到系統剪貼板
函數說明 : 複製文字到系統剪貼板, 以便後續粘貼。
函數方法 : copyText(文本型 text);
返回值 : 無
參數 | 類型 | 說明 |
---|---|---|
text | 文本型 | 要粘貼的文字, 中英文都支持 |
示例
copyText("你好") -- 複製字符串“你好”到系統剪貼板
注意事項:
複製文字到系統剪貼板會覆蓋以前複製的內容。
函數:clipText() 獲取系統剪貼板內容
函數說明 : 獲取系統剪貼板中之前複製或剪貼的文字內容。
函數方法 : clipText();
返回值 : 文本型 text
返回值 | 類型 | 說明 |
---|---|---|
text | 文本型 | 剪貼板內的文字 |
示例
text = clipText() -- 將之前複製或剪貼的文字讀取到變量text中
inputText(text) --在輸入框中輸入獲取到的字符串
函數:inputText() 輸入字符串
函數說明 : 在文本框內輸入文本。
函數方法 : inputText(文本型 string);
返回值 : 無
參數 | 類型 | 說明 |
---|---|---|
string | 文本型 | 要輸入的字符串, 其中\b字符可用於退格刪除 |
示例
inputText("你好Hello"); -- 在當前選中的文字輸入框中輸入字符串"你好Hello"
inputText("\b\b\b\b\b"); -- 退格刪除5個字符
注意事項:
1,使用該函數前,先點擊輸入框,例如點擊用戶名,再執行該函數。
2,建議切換到系統輸入法再使用該函數。
3,\b字符可用於刪除一個字符。
函數:appRun() 打開,運行指定軟件
函數說明 : 打開,運行指定軟件。
函數方法 : appRun(文本型 string);
返回值 : 無
參數 | 類型 | 說明 |
---|---|---|
string | 文本型 | 想要打開的軟件的包名 |
示例
appRun("com.android.browser"); -- 打開系統自帶瀏覽器
注意事項:
應用包名可以觸摸精靈設置--查詢已安裝應用包名中查看。
函數:appRunning() 判斷指定應用是否正在運行
函數說明 : 判斷指定應用是否正在運行。
函數方法 : appRunning(文本型 string);
返回值 : 布爾值 flag
參數 | 類型 | 說明 |
---|---|---|
string | 文本型 | 想要檢測的軟件的包名 |
參數 | 類型 | 說明 |
---|---|---|
flag | 布爾值 | 返回true或者false |
示例
if appRunning("com.android.browser") then
notifyMessage("yes");
else
notifyMessage("no");
end
注意事項:
應用包名可以觸摸精靈設置--查詢已安裝應用包名中查看。
函數:appKill() 關閉指定軟件
函數說明 : 關閉指定軟件。
函數方法 : appKill(文本型 string);
返回值 : 無
參數 | 類型 | 說明 |
---|---|---|
string | 文本型 | 想要關閉的軟件的包名 |
示例
appKill("com.android.browser"); -- 關閉系統自帶瀏覽器
示例
--遇到某些應用一次關不掉的話可用下面的方法
function kill_app(app_package)
while true do
if appRunning(app_package) then
appKill(app_package);
mSleep(1000);
else
return true;
end
end
end
---調用方法
kill_app("com.android.browser"); -- 關閉系統自帶瀏覽器
注意事項:
應用包名可以觸摸精靈設置--查詢已安裝應用包名中查看。
函數:httpGet() HTTP協議訪問
函數說明 : HTTP協議訪問。
函數方法 : httpGet(文本型 string);
返回值 : 文本型 data
參數 | 類型 | 說明 |
---|---|---|
string | 文本型 | 網址URL |
返回值 | 類型 | 說明 |
---|---|---|
data | 文本型 | 網址的內容, 失敗的話返回空字符串 |
示例
data = httpGet('www.google.com'); -- 獲取www.google.com的內容
notifyMessage(data); -- 顯示www.google.com的內容
-----登陸愛碼
sms_user_name = "user";
sms_user_password = "pass";
sms_user_info= httpGet("http://api.f02.cn:8888/http.do?action=loginIn&uid"..sms_user_name.."&pwd="..sms_user_password);--使用 用戶名爲user密碼爲pass的用戶登陸愛碼取回用戶信息
if sms_user_info ~= "" then
notifyMessage(sms_user_info); -- 顯示返回的內容
else
notifyMessage("獲取失敗");
end
函數:ftpGet() ftp下載
函數說明 : ftp下載。
函數方法 : ftpGet(文本型 url,文本型 file,文本型 ftpuser,文本型 ftppass);
返回值 : 布爾值 flag
參數 | 類型 | 說明 |
---|---|---|
url | 文本型 | 遠程文件地址 |
file | 文本型 | 本地文件路徑 |
ftpuser | 文本型 | FTP服務器用戶名 |
ftppass | 文本型 | FTP服務器密碼 |
返回值 | 類型 | 說明 |
---|---|---|
flag | 布爾值 | 返回true或者false |
示例
flag = ftpGet("ftp://192.168.1.100:/a.txt", "/var/touchelf/a.txt", "user", "pass") -- 將FTP服務器192.168.1.100上路徑爲/a.txt的文件下載到/var/touchelf/a.txt
if flag then
notifyMessage("下載成功")
else
notifyMessage("下載失敗")
end
函數:ftpPut() ftp上傳
函數說明 : ftp上傳。
函數方法 : ftpPut(文本型 url,文本型 file,文本型 ftpuser,文本型 ftppass);
返回值 : 布爾值 flag
參數 | 類型 | 說明 |
---|---|---|
url | 文本型 | 遠程文件地址 |
file | 文本型 | 本地文件路徑 |
ftpuser | 文本型 | FTP服務器用戶名 |
ftppass | 文本型 | FTP服務器密碼 |
返回值 | 類型 | 說明 |
---|---|---|
flag | 布爾值 | 返回true或者false |
示例
flag = ftpPut("ftp://192.168.1.100:/a.txt", "/var/touchelf/a.txt", "user", "pass") -- 將本地文件/var/touchelf/a.txt上傳爲FTP服務器192.168.1.100上路徑爲/a.txt的文件
if flag then
notifyMessage("下載成功")
else
notifyMessage("下載失敗")
end
函數:memoryRead() 讀取指定應用的內存
函數說明 : 讀取指定應用的內存。
函數方法 : memoryRead(文本型 package,整數型 address,文本型 type);
返回值 : 布爾值 flag ,整數型 data
參數 | 類型 | 說明 |
---|---|---|
package | 文本型 | 想要讀取的軟件的包名 |
address | 整數型 | 想要讀取的內存地址 |
type | 文本型 | 想要讀取內存的類型,支持的類型如下 |
I8: 有符號的8位整數
I16: 有符號的16位整數
I32: 有符號的32位整數
I64: 有符號的64位整數
U8: 無符號的8位整數
U16: 無符號的16位整數
U32: 無符號的32位整數
U64: 無符號的64位整數
F32: 有符號的32位浮點數
F64: 有符號的64位浮點數
返回值 | 類型 | 說明 |
---|---|---|
flag | 布爾值 | 返回true或者false |
data | 整數型 | 讀取到的數據, 僅當返回值1爲真時有效 |
示例
flag, data = memoryRead("com.test.test", 0x1000000, "U32"); -- 讀取包名爲com.test.test的應用中, 內存地址爲0x1000000處的無符號的32位整數
if flag then
notifyMessage(string.format("%s", tostring(data)));
else
notifyMessage("fail");
end
注意事項:
應用包名可以觸摸精靈設置--查詢已安裝應用包名中查看。
函數:memoryWrite() 寫入指定應用的內存
函數說明 : 寫入指定應用的內存。
函數方法 : memoryWrite(文本型 package,整數型 address,文本型 type,整數型 data);
返回值 : 布爾值 flag
參數 | 類型 | 說明 |
---|---|---|
package | 文本型 | 想要寫入的軟件的包名 |
address | 整數型 | 想要寫入的內存地址 |
type | 文本型 | 想要寫入內存的類型,支持的類型如下 |
I8: 有符號的8位整數
I16: 有符號的16位整數
I32: 有符號的32位整數
I64: 有符號的64位整數
U8: 無符號的8位整數
U16: 無符號的16位整數
U32: 無符號的32位整數
U64: 無符號的64位整數
F32: 有符號的32位浮點數
F64: 有符號的64位浮點數
返回值 | 類型 | 說明 |
---|---|---|
flag | 布爾值 | 返回true或者false |
示例
flag = memoryWrite("com.test.test", 0x1000000, "U32", 0x12345678); -- 將無符號32位整數0x12345678寫入到包名爲com.test.test的應用內存地址爲0x1000000處
if flag then
notifyMessage("寫入成功")
end
注意事項:
應用包名可以觸摸精靈設置--查詢已安裝應用包名中查看。
函數:memorySearch() 搜索指定應用的內存
函數說明 : 搜索指定應用的內存,支持聯合搜素,支持在上一次的搜索結果上再次搜索過濾。
函數方法 : memorySearch(文本型 package,布爾值 flag,數組 data);
返回值 : 數組 array
參數 | 類型 | 說明 |
---|---|---|
package | 文本型 | 想要搜索的軟件的包名 |
flag | 布爾值 | true表示進行新的搜索,false表示再上一次搜索的結果上再次進行搜索過濾 |
data | 數組 | 想要搜索的內容,數組長度最多支持128個,格式爲: { 數據1, 數據2相對於數據1的位置, 數據2, 數據3相對於數據1的位置, 數據3, ... } |
返回值 | 類型 | 說明 |
---|---|---|
array | 數組 | 搜索到內存地址數組, 地址爲數據1的地址,最多返回128個 |
示例
array = memorySearch("com.test.test", true, { 0x100, 4, 0x200 }) -- 搜索過程爲先搜素0x100,如果該內存地址+4的位置爲0x200,則爲一個有效地址
logDebug("找到"..#array.."個地址")
for i=1,#array do
logDebug(string.format("第%d個地址爲: 0x%x", i, array[i]))
end
注意事項:
應用包名可以觸摸精靈設置--查詢已安裝應用包名中查看。
函數:getScreenResolution() 獲取當前屏幕分辨率
函數說明 : 獲取當前屏幕分辨率。
函數方法 : getScreenResolution();
返回值 : 整數型 width,height
返回值 | 類型 | 說明 |
---|---|---|
width | 整數型 | 獲取到的當前屏幕寬度 |
height | 整數型 | 獲取到的當前屏幕高度 |
示例
width, height = getScreenResolution(); -- 將屏幕寬度和高度分別保存在變量w、h中
notifyMessage(string.format("%d,%d\n", width, height)); -- 將寬度和高度用提示框顯示到屏幕上
--腳本判斷使用的機器是否是iphone5
if width == 640 and height == 1136 then
notifyMessage("當前設備爲iphone5")
else
notifyMessage("請在iphone5上使用本程序")
end
函數:getScreenColorBits() 獲取當前屏幕色彩位數
函數說明 : 獲取當前屏幕色彩位數。
函數方法 : getScreenColorBits();
返回值 : 整數型 color
返回值 | 類型 | 說明 |
---|---|---|
color | 整數型 | 色彩位數 |
示例
color = getScreenColorBits(); -- 將屏幕色彩位數保存在變量color中
notifyMessage(string.format("%d\n", color)); -- 將色彩位數用提示框顯示到屏幕上
函數:getDeviceID() 獲取設備串號
函數說明 : 獲取設備串號。
函數方法 : getDeviceID();
返回值 : 文本型 deviceID
返回值 | 類型 | 說明 |
---|---|---|
deviceID | 文本型 | 返回的設備串號 |
示例
deviceID = getDeviceID(); -- 將設備ID保存到deviceID變量中
-------------------------授權一臺設備-------------------------
if deviceID == "Fd452dg2421" then
notifyMessage("當前設備已授權");
else
notifyMessage("當前設備未授權");
os.exit() --結束腳本
end
-------------------------授權多臺設備---------------------------------
local deviceID_flag = false; --定義當前設備未授權
deviceID_arr = {"F123456","F1234567","F12345678"};--可使用設備數組
for i = 1,#deviceID_arr do --循環數組長度
if deviceID == deviceID_arr[i] then--判斷當前設備序列號是否和設備數組中的相同
deviceID_flag = true;--定義當前設備已授權
break; --跳出循環
end
end
if deviceID_flag then
notifyMessage("當前設備已授權");
else
notifyMessage("當前設備未授權");
os.exit(); --結束腳本
end
注意事項:
1,使用該函數 蘋果設備返回的是序列號,安卓設備返回的是mac 。
2,os.exit() 爲結束腳本函數。
函數:getNetTime() 獲取網絡時間
函數說明 : 獲取網絡時間。
函數方法 : getNetTime();
返回值 : 整數型 time
返回值 | 類型 | 說明 |
---|---|---|
time | 整數型 | 時間戳 |
示例
time = getNetTime();
if time ~= -1 then
tt = os.date("*t", time);
if tt.year > 2014 and tt.month > 2 and tt.day > 15 and tt.hour > 12 and tt.min > 30 then
notifyMessage("當前時間超過了2013年2月15日12點30分");
end
else
notifyMessage("請連接網絡");
end
示例:獲取網絡時間判斷腳本是否到期
endtime = os.time{year=2016, month=1, day=1, hour=0, min=0, sec=0};--到期時間2016年1月1日0點0分0秒
if endtime > getNetTime() then --結束日期大於現在日期
notifyMessage("腳本未到期");
else
notifyMessage("腳本已到期");
end
注意事項:
該時間與lua的os.time()函數一樣, 返回的是UTC時間1970年1月1日0時0分0秒到現在流逝的秒數, 可以配合os.date()轉換成方便閱讀的格式。返回-1表示不能連接網絡時間服務器
函數:getVersion() 獲取當前觸摸精靈版本號
函數說明 : 獲取當前觸摸精靈版本號。
函數方法 : getVersion();
返回值 : 文本型 version
返回值 | 類型 | 說明 |
---|---|---|
version | 文本型 | 觸摸精靈版本號如3.3.2 |
示例
version = getVersion(); -- 將觸摸精靈版本號保存在變量version中
notifyMessage(version); -- 顯示版本號
-----判斷版本號
if tonumber(string.sub(version, 1, 1)..string.sub(version, 3,3)..string.sub(version, 5,5)) < 332 then
notifyMessage("請使用332版本以上的觸摸精靈");
os.exit();
end
注意事項:
返回的版本號是字符串,對比的時候需轉換成數字對比。
函數:fakeGPS() 修改GPS地理位置(蘋果專用)
函數說明 : 爲指定程序僞裝GPS地理位置。
函數方法 : fakeGPS(文本型 package,浮點型 x,浮點型 y);
返回值 : 無
參數 | 類型 | 說明 |
---|---|---|
package | 文本型 | 要僞裝GPS地理位置的軟件的包名 |
x | 浮點型 | 緯度,和第三個參數同時爲0的時候表示取消該應用的僞裝 |
y | 浮點型 | 經度,和第二個參數同時爲0的時候表示取消該應用的僞裝 |
示例
fakeGPS("com.baidu.map", 40.0234512958, 116.2185668045); -- 將百度地圖的GPS地理位置僞裝爲指定緯度和經度
fakeGPS("com.tencent.xin", 0, 0); -- 取消對百度地圖的GPS地理位置僞裝
注意事項:
調用該函數僞裝地理位置以後,腳本停止以後僞裝不會取消,直到使用該函數取消指定 應用的僞裝,或執行『觸摸精靈-設置-清除GPS僞裝』清除設備所有僞裝
函數:appBundlePath() 獲取指定應用的主程序目錄的路徑(蘋果專用)
函數說明 : 獲取指定應用的主程序目錄的路徑。
函數方法 : appBundlePath(文本型 package);
返回值 : 文本型 path
參數 | 類型 | 說明 |
---|---|---|
package | 文本型 | 應用的包名 |
返回值 | 類型 | 說明 |
---|---|---|
path | 文本型 | 主程序目錄的路徑 |
示例
path = appBundlePath("com.tencent.xin")
if path ~= "" then
notifyMessage(path);
else
notifyMessage("no");
end
注意事項:
應用包名可以觸摸精靈設置--查詢已安裝應用包名中查看。
函數:appDataPath() 獲取指定應用的數據目錄的路徑(蘋果專用)
函數說明 : 獲取指定應用的數據目錄的路徑。
函數方法 : appDataPath(文本型 package);
返回值 : 文本型 path
參數 | 類型 | 說明 |
---|---|---|
package | 文本型 | 應用的包名 |
返回值 | 類型 | 說明 |
---|---|---|
path | 文本型 | 數據目錄的路徑 |
示例
path = appDataPath("com.tencent.xin")
if path ~= "" then
notifyMessage(path);
else
notifyMessage("no");
end
注意事項:
應用包名可以觸摸精靈設置--查詢已安裝應用包名中查看。
函數:setControlBarPosition() 設置播放控制條位置(安卓專用)
函數說明 : 獲取指定應用的數據目錄的路徑。
函數方法 : setControlBarPosition(整數型 x,整數型 y);
返回值 : 無
參數 | 類型 | 說明 |
---|---|---|
x | 整數型 | 播放控制條X座標 |
y | 整數型 | 播放控制條Y座標 |
示例
setControlBarPosition(100, 100) -- 將播放控制條移動到座標(100, 100)處
教程
觸摸精靈找圖腳本的詳細製作過程
1.截取全屏圖片
- 將電腦和手機連接到同一個路由器下,使2者處於同一個子網中,假設電腦的IP爲192.168.1.6,手機的IP爲192.168.1.7
- 在電腦上運行『觸摸精靈編輯器』 執行『菜單-圖像-觸摸抓抓』 點擊『遠程截圖』,輸入手機的IP:192.168.1.7(見圖1)
- 等待處理完成便獲取到了手機的當前屏幕截圖(見圖2)
圖1:
圖2:
2.扣取要找的圖片
- 點擊『圖片裁剪』
- 按下鼠標左鍵並拖動來選取要扣取的圖片(見圖3)
- 將扣取的圖片保存到電腦,起名爲phone.bmp(見圖4)
圖3:
圖4:
3.編寫腳本
- 將截取的圖片phone.bmp上傳到手機中的某個目錄中(例如:IOS設備可以存放到/var/touchelf目錄下,安卓設備可以存放到/mnt/sdcard/目錄下)
- 假如我們想要執行的動作爲:如果播放腳本時屏幕上存在電話圖標,那麼點擊該圖標,並顯示yes;如果不存在該圖標,那麼就顯示no
function main() -- main函數,腳本播放時會執行該函數
mSleep(2000) -- 等待2秒後執行,爲了避免播放開始的提示影響找圖
x, y = findImage("/var/touchelf/phone.bmp") -- 參數爲圖片的絕對路徑,請修改爲你上傳的圖片路徑
if x ~= -1 and y ~= -1 then -- 如果x和y不等與-1,說明找到了
touchDown(0, x+5, y+5) -- 手指按下圖片所在的位置,由於x和y是左上角座標,爲了點中圖片,x和y都加了5個像素的偏移
touchUp(0) -- 手指擡起
notifyMessage("yes") -- 顯示yes
else -- 否則,如果沒找到
notifyMessage("no") -- 顯示no
end
end
將上述代碼保存爲腳本,然後在存在電話圖標的界面播放時,會點擊該圖標後,顯示yes;在不存在Phone圖標的界面上播放時,只會顯示no
httpGet函數操作二進制文件的方法
因爲httpGet函數的交互只能操作字符串,所以如果想要使用該函數傳送二進制文件(如圖片),可以把二進制文件轉換成16進制字符串,然後在服務器端逆向的把16進制字符串還原成二進制,下面代碼中的fileToHexString()函數就是一個把二進制文件轉換成16進制字符串的函數。
--------------------------------------------------
-- 將二進制文件轉換成16進制字符串
-- 可用於httpGet函數傳送文件,服務器端將16進制字符串轉換成二進制文件即可
-- 實現逆向轉換
--------------------------------------------------
function fileToHexString(file)
local file = io.open(file, 'rb');
local data = file:read("*all");
file:close();
local t = {};
for i = 1, string.len(data),1 do
local code = tonumber(string.byte(data, i, i));
table.insert(t, string.format("%02x", code));
end
return table.concat(t, "");
end
function main()
str = fileToHexString('test.dat');
notifyMessage(str);
end
腳本的模塊化教程
當腳本過大時,模塊化各個功能可以讓腳本更加便於管理。
假設a.lua存放於/mnt/sdcard/touchelf/scripts/下面(默認路徑),內容如下:
function a1()
notifyMessage("i'm a1");
end
想要在b.lua中調用a.lua中的函數a1(),那麼b.lua可以這樣寫:
package.path=package.path .. ";/mnt/sdcard/touchelf/scripts/?.lua"
require "a"
function main()
a1();
end
或者:
dofile("/mnt/sdcard/touchelf/scripts/a.lua");
function main()
a1();
end
require與dofile區別:
1.require只需要指定模塊名字(不需要加入.lua這樣後綴),而dofile需要指定文件的完整路徑。
2.require會記住load過的信息,重複調用不會導致模塊被重新載入,而dofile會。(我們可以通過dofile這種特性來實現熱更新)
3.require可以載入二進制模塊,如c語言編寫的動態庫,可以通過package.cpath來顯示動態庫查找的路徑信息。
讓你的腳本隨機化一些
有時候,我們可能希望腳本可以隨機化一點,表現的能像是真人在操作,而不要太機械,比如循環點擊一個點的時候,能夠每次點擊的位置能稍微變化一點,這個時候可以試用lua的math.random()函數,這個比如如下代碼:
math.randomseed(tostring(os.time()):sub(5):reverse()); -- 隨機種子
math.random(-5, 5);
每次都可以返回-5到5之間隨機的一個數,那麼我們可以將點擊操作寫一個函數:
function click(x, y)
touchDown(0, x + math.random(-5, 5), y + math.random(-5, 5));
mSleep(math.random(1000, 2000));
touchUp(0);
end
然後在需要點擊時之間調用這個函數,比如找圖時:
x, y = findImage("/mnt/sdcard/a.bmp");
if x ~= -1 and y ~= -1 then
click(x, y);
end
這樣每次循環點擊的位置都是有小幅變化的,而不是每次都是點擊一個點。
自定義字符串隨機:
function randomStr(str, num)
local reStr ='';
math.randomseed(tostring(os.time()):sub(5):reverse());
for i = 1, num do
local getStr = math.random(1, string.len(str));
reStr = reStr .. string.sub(str, getStr, getStr);
end
return reStr;
end
--用法
s = randomStr("abcdefghijklmnopqrstuvwxyz", 10) --生成10位隨機字母
觸摸精靈的座標體系與rotateScreen()函數的用法
1.觸摸精靈的默認座標體系
在沒有rotateScreen()這個函數之前,觸摸精靈的座標體系是固定的,以IOS設備爲例子,不論是找圖還是點擊,座標的原點始終是在HOME鍵盤在下時候的左上角是原點,例如我們用如下腳本:
function main()
mSleep(1000); -- 延遲一秒
snapshotScreen("/var/touchelf/a.bmp"); -- 將全屏截圖保存到/var/touchelf/a.bmp這個文件裏
end
在IOS設備的主屏幕播放一次,這樣就獲取瞭如下的圖:
這個圖片的尺寸和768x1024, 圖片的方向是和觸摸精靈默認的座標體系是一樣的,左上角的座標爲(0,0),右上角的座標爲(768, 0),左下角的座標爲(0, 1024),右下角的座標爲(768, 1024)。
2.通過座標點擊制定位置
如果我們想在腳本中點擊“觸摸精靈”的圖標的話,需要怎麼寫呢,我們需要獲取到該圖標的座標,獲取這個圖標的座標的方法很多,這裏我們用Photoshop打開該圖片,然後按F8打開信息面板,並把該面板的選項中的“鼠標座標”單位改爲“像素”,然後把鼠標移動到圖標的位置,這是就可以在信息面板裏看到對應的座標了,如下圖所示:
上圖中的信息面板中的信息告訴我們,“觸摸精靈”圖標的座標是(124,131),那麼我們編寫如下腳本:
function main()
touchDown(0, 124, 131); -- 手指按下(124,131)位置,第一個參數0是手指ID,這個在多點觸摸時會用到
touchUp(0); -- 手指擡起
end
在主屏幕播放如上腳本,就可以自動點擊到“觸摸精靈”的圖標了。
3.通過找圖點擊指定位置
接下來,我們想通過找圖來點擊“觸摸精靈”的座標,那麼我們首先需要獲取“觸摸精靈”圖標的截圖,我們用Photoshop截取“觸摸精靈”的圖標如下(保存時候的BMP選項: 文件格式爲windows,深度爲24位,其他的都不選):
把這個圖片傳到設備的/var/touchelf/touchelf.bmp文件,然後編寫如下腳本:
function main()
x, y = findImage("/var/touchelf/touchelf.bmp"); -- 查找touchelf.bmp這個圖標在屏幕的位置,座標保存到x和y裏
if x ~= -1 and y ~= -1 then -- 如果x和y都不是-1的話,說明找到了
touchDown(0, x+5, y+5); -- 由於x和y保存裏圖標的位置,我們把x和y傳給touchDown就可以了,這裏x和y都加5是由於找圖返回的座標是找到的圖片的左上角的座標,我們要先點中的話,點擊的位置需要往右下方偏移一下。
touchUp(0); -- 手指擡起
else -- 否則,也就是x和y有一個是-1的話,說明沒找到
notifyMessage("沒有找到"); -- 顯示消息
end
end
4.橫屏遊戲如何編寫呢
手遊基本是橫屏的,默認情況下,觸摸精靈的座標體系不會隨着屏幕畫面改變的,例如,我們在橫屏遊戲中播放上述的截圖腳本,獲取到的圖片是這樣的:
我們可以看到,截圖還是豎着的,而且這時候座標體系也沒有改變的,如果我們想點擊“人物頭像”,使用以前Photoshop信息面板查看的方法,可以看到“人物頭像”的座標是(720,65),那麼腳本如下:
function main()
touchDown(0, 720, 65); -- 手指按下人物頭像的位置,第一個參數0是手指ID,這個在多點觸摸時會用到。
touchUp(0); -- 手指擡起
end
那麼我們想找圖點擊呢,這時候我們需要找圖的是這樣的:
就像上面的圖片,我們要找的圖也必須是從豎着的圖片上扣取下了的。
5.橫屏遊戲如何更容易的編寫呢
通過第4講裏的說明,我們可以看到觸摸精靈默認的座標體系對於編寫橫屏遊戲來說不太友好,因爲我們可能想要這樣的座標體系:
我們想要上面圖片中的左上角是(0,0),右上角是(0,1024),左下角是(0, 768),右下角是(1024,768),那麼我們就可以使用rotateScreen()函數來做到這一點了。
rotateScreen()函數用於設置觸摸精靈的座標體系,它的參數有4個選項:
- 0:這個是默認的選項,就是豎着拿設備,HOME鍵在下面時候,左上角是(0,0)原點
- 90:這個對應大部分的橫屏遊戲,即橫着拿設備,HOME鍵在右面的時候,左上角是(0, 0)原點
- -90:這個對應小部分橫屏遊戲,即橫着拿設備,HOME鍵在左面的時候,左上角是(0,0)原點
- 180:這個是豎着拿設備,HOME鍵在上面時候,左上角是(0,0)原點
對於大部分橫屏遊戲來說,我們可以用rotateScreen(90)將觸摸精靈的座標體系與其設置成一樣的,比如我們使用如下腳本截圖:
function main()
mSleep(1000); -- 延遲一秒
rotateScreen(90); -- 設置觸摸精靈的座標體系設置成和遊戲一致
snapshotScreen("/var/touchelf/a.bmp"); -- 截圖保存到/var/touchelf/a.bmp文件
end
通過上面的腳本截到的圖片如下:
我們可以發現,這時候獲取的圖片和遊戲的畫面是一致的了,都是橫着的。
那麼我們想以橫屏遊戲的左上角爲原點發送點擊怎麼做呢,很簡單,在腳本開始的時候加入rotateScreen(90),以後的touchDown()等函數就可以傳給他橫屏遊戲的座標了,比如還是想點擊“人物頭像”,我們在Photoshop的信息面板中查看座標如下:
可以看到“人物頭像”的座標是(58,54),那麼可以這樣寫:
function main()
rotateScreen(90); -- 設置觸摸精靈的座標體系設置成和遊戲一致
touchDown(0, 58, 54); -- 以遊戲畫面左上角爲原點,發送點擊動作
touchUp(0);
end
那麼我們想通過找圖來點擊呢,而且不想像第4講裏的那樣找豎着的圖,我們想找如下這樣的圖:
我們把這個橫屏圖片的人物頭像截圖放到/var/touchelf/b.bmp位置,然後再簡單的修改上面的找圖腳本就可以了:
function main()
rotateScreen(90); -- 設置觸摸精靈的座標體系設置成和遊戲一致
x, y = findImage("/var/touchelf/touchelf.bmp"); -- 查找touchelf.bmp這個圖標在屏幕的位置,座標保存到x和y裏,這時返回的座標也是以橫屏遊戲的左上角爲原點的。
if x ~= -1 and y ~= -1 then -- 如果x和y都不是-1的話,說明找到了
touchDown(0, x+5, y+5); -- 那麼點擊找圖返回的座標
touchUp(0); -- 手指擡起
else -- 否則,也就是x和y有一個是-1的話,說明沒找到
notifyMessage("沒有找到"); -- 顯示消息
end
end
end
不建議使用第5種方案編寫腳本。
"os.execute"的相關應用
--註銷
os.execute("killall -9 SpringBoard");
--關機
os.execute("halt");
--重啓
os.execute("reboot");
--清除緩存
os.execute("su mobile -c uicache");
--安裝apk
os.execute("pm install /路徑/文件名.apk");
--卸載apk
os.execute("pm uninstall 包名");
--刪除文件、文件夾
function remove(path)
return os.execute("rm -rf "..path);
end
參數說明:path爲要刪除文件的路徑,支持*通配符。
如要刪除test.lua的文件,則輸入:
remove("/var/touchelf/scripts/test.lua");
當然也可直接用自帶的系統庫函數,但不能刪文件夾
os.remove("/var/touchelf/scripts/test.lua");
--移動文件
function move(path,to)
return os.execute("mv "..path.." "..to);
end
參數說明:
1.path爲待移動文件的路徑,支持*通配符。
2.to爲要移到的文件路徑,注意先判斷是否有重名文件或文件夾。
如要移動log.txt到scripts/test.lua,則輸入:
move("/var/touchelf/log.txt","/var/touchelf/scripts/test.lua");
--複製文件
function copy(path,to)
return os.execute("cp -rf "..path.." "..to);
end
參數說明:
1.path爲待複製文件的路徑,支持*通配符。
2.to爲要複製到的文件路徑,注意先判斷是否有重名文件或文件夾。
如要複製log.txt到scripts/test.lua,則輸入:
copy("/var/touchelf/log.txt","/var/touchelf/scripts/test.lua");
--創建文件夾
function newfolder(path)
return os.execute("mkdir "..path);
end
參數說明:path爲要創建文件夾的路徑。
如要創建test文件夾,則輸入:
newfolder("/var/touchelf/scripts/test");
--創建文件
function newfile(path)
return os.execute("touch "..path);
end
參數說明:path爲要創建文件的路徑。
如要創建test.lua文件,則輸入:
newfile("/var/touchelf/scripts/test.lua");
--獲取文件相關信息
function main()
path="/var/touchelf/scripts/test.lua"
f=io.file(path) --獲取文件
notifyMessage(f:size()) --顯示文件大小
if f:chown("root") then --改變文件所有者
notifyMessage(f:chown()) --顯示文件所有者
end
if f:chmod(777) then --改變文件權限
notifyMessage(f:chmod()) --顯示文件權限
end
notifyMessage(f:time()) --顯示文件修改時間
end
function io.file(path)
local _={}
function _:chmod(mode)
if mode then
return os.execute("chmod "..mode.." "..path)
else
return string.sub(io.popen("ls -l "..path):read("*l"),2,10)
end
end
function _:chown(mode)
if mode then
return os.execute("chown "..mode.." "..path)
else
return string.match(io.popen("ls -l "..path):read("*l"),string.rep("[^ ]+[ ]+",2).."([^ ]+)")
end
end
function _:size()
return string.match(io.popen("ls -l "..path):read("*l"),string.rep("[^ ]+[ ]+",4).."([^ ]+)")
end
function _:time()
return string.match(io.popen("ls -l "..path):read("*l"),string.rep("[^ ]+[ ]+",5).."("..string.rep("[^ ]+[ ]+",3)..")")
end
return _
end
--解壓zip文件
function unzip(path,to)
return os.execute("unzip "..path.." -d "..to);
end
參數說明:
1.path爲待解壓文件的路徑。
2.to爲要解壓到的文件夾路徑,默認不覆蓋。
如要解壓test.zip的文件,則輸入:
unzip("/var/touchelf/scripts/test.zip","/var/touchelf/scripts/");
補充:使用-P可以實現帶密碼解壓,load()、dofile()可以運行字符串或腳本文件。
"io庫"的相關應用
--讀取指定文件所有內容,返回一個數組
function readFile(path)
local file = io.open(path,"r");--用讀模式打開一個文件
if file then
local _list = {};
for l in file:lines() do
table.insert(_list,l)
end
file:close();--關閉默認的輸出文件
return _list
end
end
list = readFile("/var/touchelf/scripts/test.txt");
參數說明:path爲要讀取文件的路徑。
返回值:返回一個table。
io.open按指定的模式打開一個文件,成功則返回文件句柄,失敗則返回nil。
常用模式:
"r": 讀模式 (默認);
"w": 寫模式;
"a": 添加模式;
"r+": 更新模式,所有之前的數據將被保存
"w+": 更新模式,所有之前的數據將被清除
"a+": 添加更新模式,所有之前的數據將被保存,只允許在文件尾進行添加
flie:lines()打開指定的文件爲讀模式並返回一個迭代函數,每次調用將獲得文件中的一行內容,當到文件尾時,將返回nil,並自動關閉文件
--遍歷文件
function list(path)
return io.popen("ls "..path);
end
參數說明:path爲要列舉文件的文件夾的路徑,支持*通配符。
如要列舉scripts文件夾下所有的腳本文件,則輸入:
list("/var/touchelf/scripts/")
返回值:文件,請用read()函數讀取,文件結構爲各文件的文件名並以\n連接的字符串,如使用通配符,則還包含父文件夾名。
--查找文件
function find(path)
return io.popen("find "..path.." -prune");
end
參數說明:path爲要查找文件的路徑,支持*通配符。
如要查找後綴爲.lua的文件,則輸入:
find("/var/touchelf/scripts/*.lua")
返回值:文件,請用read()函數讀取,文件結構爲各文件的完整路徑並以\n連接的字符串。
----檢測指定文件是否存在
function file_exists(file_name)
local f = io.open(file_name, "r")
return f ~= nil and f:close()
end
參數說明:path爲要查找文件的路徑。
返回值:返回 true、false。
if file_exists("/var/touchelf/scripts/test.lua") then
notifyMessage("Yes");
else
notifyMessage("No");
end
"string庫"的相關應用
基本函數
函數 | 描述 | 示例 | 結果 |
---|---|---|---|
len | 計算字符串長度 | string.len("abcd") | 4 |
rep | 返回字符串s的n個拷貝 | string.rep("abcd",2) | abcdabcd |
lower | 返回字符串全部字母大寫 | string.lower("AbcD") | abcd |
upper | 返回字符串全部字母小寫 | string.upper("AbcD") | ABCD |
format | 格式化字符串 | string.format("the value is:%d",4) | the value is:4 |
sub | 從字符串裏截取字符串 | string.sub("abcd",2) | bcd |
string.sub("abcd",-2) | cd | ||
string.sub("abcd",2,-2) | bc | ||
string.sub("abcd",2,3) | bc | ||
find | 在字符串中查找(顯示位置) | string.find("cdcdcdcd","ab") | nil |
string.find("cdcdcdcd","cd") | 1 2 | ||
string.find("cdcdcdcd","cd",7) | 7 8 | ||
match | 在字符串中查找(顯示內容) | string.match("cdcdcdcd","ab") | nil |
string.match("cdcdcdcd","cd") | cd | ||
gsub | 在字符串中替換 | string.gsub("abcdabcd","a","z"); | zbcdzbcd 2 |
string.gsub("aaaa","a","z",3); | zzza 3 | ||
byte | 返回字符的整數形式 | string.byte("ABCD",4) | 68 |
char | 將整型數字轉成字符並連接 | string.char(97,98,99,100) | abcd |
基本模式串
字符類 | 描述 | 示例 | 結果 |
---|---|---|---|
. | 任意字符 | string.find("",".") | nil |
%s | 空白符 | string.find("ab cd","%s%s") | 3 4 |
%S | 非空白符 | string.find("ab cd","%S%S") | 1 2 |
%p | 標點字符 | string.find("ab,.cd","%p%p") | 3 4 |
%P | 非標點字符 | string.find("ab,.cd","%P%P") | 1 2 |
%c | 控制字符 | string.find("abcd\t\n","%c%c") | 5 6 |
%C | 非控制字符 | string.find("\t\nabcd","%C%C") | 3 4 |
%d | 數字 | string.find("abcd12","%d%d") | 5 6 |
%D | 非數字 | string.find("12abcd","%D%D") | 3 4 |
%x | 十六進制數字 | string.find("efgh","%x%x") | 1 2 |
%X | 非十六進制數字 | string.find("efgh","%X%X") | 3 4 |
%a | 字母 | string.find("AB12","%a%a") | 1 2 |
%A | 非字母 | string.find("AB12","%A%A") | 3 4 |
%l | 小寫字母 | string.find("ABab","%l%l") | 3 4 |
%L | 大寫字母 | string.find("ABab","%L%L") | 1 2 |
%u | 大寫字母 | string.find("ABab","%u%u") | 1 2 |
%U | 非大寫字母 | string.find("ABab","%U%U") | 3 4 |
%w | 字母和數字 | string.find("a1()","%w%w") | 1 2 |
%W | 非字母非數字 | string.find("a1()","%W%W") | 3 4 |
轉義字符%
字符類 | 描述 | 示例 | 結果 |
---|---|---|---|
% | 轉義字符 | string.find("abc%..","%%") | 4 4 |
string.find("abc..d","%.%.") | 4 5 |
用[]創建字符集,"-"爲連字符,"^"表示字符集的補集
字符類 | 描述 | 示例 | 結果 |
---|---|---|---|
[01] | 匹配二進制數 | string.find("32123","[01]") | 3 3 |
[AB][CD] | 匹配AC、AD、BC、BD | string.find("ABCDEF","[AB][CD]") | 2 3 |
[[]] | 匹配一對方括號[] | string.find("ABC[]D","[[]]") | 4 5 |
[1-3] | 匹配數字1-3 | string.find("312","[1-3][1-3][1-3]") | 1 3 |
[b-d] | 匹配字母b-d | string.find("dbc","[b-d][b-d][b-d]") | 1 3 |
[^%s] | 匹配任意非空字符 | string.find(" a ","[^%s]") | 3 3 |
[^%d] | 匹配任意非數字字符 | string.find("123a","[^%d]") | 4 4 |
[^%a] | 匹配任意非字母字符 | string.find("abc1","[^%a]") | 4 4 |
用"()"進行捕獲
字符類 | 描述 | 示例 | 結果 |
---|---|---|---|
() | 捕獲字符串 | string.find("12ab","(%a%a)") | 3 4 ab |
string.find("ab12","(%d%d)") | 3 4 12 |
模式修飾符
修飾符 | 描述 | 示例 | 結果 |
---|---|---|---|
+ | 表示1個或多個,匹配最多個 | string.find("aaabbb","(a+b)") | 1 4 aaab |
string.find("cccbbb","(a+b)") | nil | ||
- | 表示0個或多個,匹配最少個 | string.find("zzxyyy","(xy-)") | 3 3 x |
string.find("zzzyyy","(x-y)") | 4 4 y | ||
* | 表示0個或多個,匹配最多個 | string.find("mmmnnn","(m*n)") | 1 4 mmmb |
string.find("lllnnn","(m*n)") | 4 4 n | ||
? | 表示0個或1個 | string.find("aaabbb","(a?b)") | 3 4 ab |
string.find("cccbbb","(a?b)") | 4 4 b |
match的常見用法
描述 | 示例 | 結果 |
---|---|---|
匹配中文 | string.match("男女abc123","([^%w%p]+)") | 男女 |
匹配英文 | string.match("男女abc123","(%a+)") | abc |
匹配數字 | string.match("男女abc123","(%d+)") | 123 |
匹配英文和數字 | string.match("男女abc123","(%w+)") | abc123 |
"math庫"的相關應用
函數名 | 描述 | 示例 | 結果 |
---|---|---|---|
pi | 圓周率 | math.pi | 3.1415926535898 |
abs | 取絕對值 | math.abs(-2012) | 2012 |
ceil | 向上取整 | math.ceil(9.1) | 10 |
floor | 向下取整 | math.floor(9.9) | 9 |
max | 取參數最大值 | math.max(2,4,6,8) | 8 |
min | 取參數最小值 | math.min(2,4,6,8) | 2 |
pow | 計算x的y次冪 | math.pow(2,16) | 65536 |
sqrt | 開平方 | math.sqrt(65536) | 256 |
mod | 取模 | math.mod(65535,2) | 1 |
modf | 取整數和小數部分 | math.modf(20.12) | 20 0.12 |
randomseed | 設隨機數種子 | math.randomseed(os.time()) | |
random | 取隨機數 | math.random(5,90) | 5~90 |
rad | 角度轉弧度 | math.rad(180) | 3.1415926535898 |
deg | 弧度轉角度 | math.deg(math.pi) | 180 |
exp | e的x次方 | math.exp(4) | 54.598150033144 |
log | 計算x的自然對數 | math.log(54.598150033144) | 4 |
log10 | 計算10爲底,x的對數 | math.log10(1000) | 3 |
frexp | 將參數拆成x * (2 ^ y)的形式 | math.frexp(160) | 0.625 8 |
ldexp | 計算x * (2 ^ y) | math.ldexp(0.625,8) | 160 |
sin | 正弦 | math.sin(math.rad(30)) | 0.5 |
cos | 餘弦 | math.cos(math.rad(60)) | 0.5 |
tan | 正切 | math.tan(math.rad(45)) | 1 |
asin | 反正弦 | math.deg(math.asin(0.5)) | 30 |
acos | 反餘弦 | math.deg(math.acos(0.5)) | 60 |
atan | 反正切 | math.deg(math.atan(1)) | 45 |
觸摸精靈使用cURL命令
安卓系下載cURL模塊:http://yunpan.cn/cHstaJHupAj5u 訪問密碼 37b7
將cURL模塊放入/system/bin/內
IOS系統Cydia內搜索並下載安裝cURL軟件。
完成上述內容即可使用cURL命令
--下載腳本
os.execute("curl -o /var/touchelf/scripts/evan.lua.E2 http://www.touchel.com/evan.lua.E2")
--post命令
os.execute("curl -d 'user=evan&password=12345' http://www.touchelf.com/login.php")
更多cURL命令請自行百度。
觸摸精靈模擬物理按鍵的方法
====================
1. 模擬物理按鍵
====================
os.execute("input keyevent 按鍵鍵碼")
列子:
按下home鍵
os.execute("input keyevent 3")
打電話給10086
os.execute("input keyevent 5") --按撥號鍵
os.execute("input text \"10086\"") --輸入10086
os.execute("input keyevent 5") --按撥號鍵打通
以下就是約定的按鍵鍵碼:
AKEYCODE_UNKNOWN = 0,
AKEYCODE_SOFT_LEFT = 1,
AKEYCODE_SOFT_RIGHT = 2,
AKEYCODE_HOME = 3,
AKEYCODE_BACK = 4,
AKEYCODE_CALL = 5,
AKEYCODE_ENDCALL = 6,
AKEYCODE_0 = 7,
AKEYCODE_1 = 8,
AKEYCODE_2 = 9,
AKEYCODE_3 = 10,
AKEYCODE_4 = 11,
AKEYCODE_5 = 12,
AKEYCODE_6 = 13,
AKEYCODE_7 = 14,
AKEYCODE_8 = 15,
AKEYCODE_9 = 16,
AKEYCODE_STAR = 17,
AKEYCODE_POUND = 18,
AKEYCODE_DPAD_UP = 19,
AKEYCODE_DPAD_DOWN = 20,
AKEYCODE_DPAD_LEFT = 21,
AKEYCODE_DPAD_RIGHT = 22,
AKEYCODE_DPAD_CENTER = 23,
AKEYCODE_VOLUME_UP = 24,
AKEYCODE_VOLUME_DOWN = 25,
AKEYCODE_POWER = 26,
AKEYCODE_CAMERA = 27,
AKEYCODE_CLEAR = 28,
AKEYCODE_A = 29,
AKEYCODE_B = 30,
AKEYCODE_C = 31,
AKEYCODE_D = 32,
AKEYCODE_E = 33,
AKEYCODE_F = 34,
AKEYCODE_G = 35,
AKEYCODE_H = 36,
AKEYCODE_I = 37,
AKEYCODE_J = 38,
AKEYCODE_K = 39,
AKEYCODE_L = 40,
AKEYCODE_M = 41,
AKEYCODE_N = 42,
AKEYCODE_O = 43,
AKEYCODE_P = 44,
AKEYCODE_Q = 45,
AKEYCODE_R = 46,
AKEYCODE_S = 47,
AKEYCODE_T = 48,
AKEYCODE_U = 49,
AKEYCODE_V = 50,
AKEYCODE_W = 51,
AKEYCODE_X = 52,
AKEYCODE_Y = 53,
AKEYCODE_Z = 54,
AKEYCODE_COMMA = 55,
AKEYCODE_PERIOD = 56,
AKEYCODE_ALT_LEFT = 57,
AKEYCODE_ALT_RIGHT = 58,
AKEYCODE_SHIFT_LEFT = 59,
AKEYCODE_SHIFT_RIGHT = 60,
AKEYCODE_TAB = 61,
AKEYCODE_SPACE = 62,
AKEYCODE_SYM = 63,
AKEYCODE_EXPLORER = 64,
AKEYCODE_ENVELOPE = 65,
AKEYCODE_ENTER = 66,
AKEYCODE_DEL = 67,
AKEYCODE_GRAVE = 68,
AKEYCODE_MINUS = 69,
AKEYCODE_EQUALS = 70,
AKEYCODE_LEFT_BRACKET = 71,
AKEYCODE_RIGHT_BRACKET = 72,
AKEYCODE_BACKSLASH = 73,
AKEYCODE_SEMICOLON = 74,
AKEYCODE_APOSTROPHE = 75,
AKEYCODE_SLASH = 76,
AKEYCODE_AT = 77,
AKEYCODE_NUM = 78,
AKEYCODE_HEADSETHOOK = 79,
AKEYCODE_FOCUS = 80, // *Camera* focus
AKEYCODE_PLUS = 81,
AKEYCODE_MENU = 82,
AKEYCODE_NOTIFICATION = 83,
AKEYCODE_SEARCH = 84,
AKEYCODE_MEDIA_PLAY_PAUSE= 85,
AKEYCODE_MEDIA_STOP = 86,
AKEYCODE_MEDIA_NEXT = 87,
AKEYCODE_MEDIA_PREVIOUS = 88,
AKEYCODE_MEDIA_REWIND = 89,
AKEYCODE_MEDIA_FAST_FORWARD = 90,
AKEYCODE_MUTE = 91,
AKEYCODE_PAGE_UP = 92,
AKEYCODE_PAGE_DOWN = 93,
AKEYCODE_PICTSYMBOLS = 94,
AKEYCODE_SWITCH_CHARSET = 95,
AKEYCODE_BUTTON_A = 96,
AKEYCODE_BUTTON_B = 97,
AKEYCODE_BUTTON_C = 98,
AKEYCODE_BUTTON_X = 99,
AKEYCODE_BUTTON_Y = 100,
AKEYCODE_BUTTON_Z = 101,
AKEYCODE_BUTTON_L1 = 102,
AKEYCODE_BUTTON_R1 = 103,
AKEYCODE_BUTTON_L2 = 104,
AKEYCODE_BUTTON_R2 = 105,
AKEYCODE_BUTTON_THUMBL = 106,
AKEYCODE_BUTTON_THUMBR = 107,
AKEYCODE_BUTTON_START = 108,
AKEYCODE_BUTTON_SELECT = 109,
AKEYCODE_BUTTON_MODE = 110,
觸摸精靈安卓啓動APK直達某些頁面的方法
os.execute("am start -n {包(package)名} / {包名}.{活動(activity)名稱}")
包名package和活動activity名稱可以反編譯apk後,在每個apk的AndroidManifest.xml裏面查看。
示例:
啓動計算器
os.execute("am start -n com.android.calculator2/com.android.calculator2.Calculator")
AlarmClock(鬧鐘)的啓動方法爲:
os.execute("am start -n com.android.alarmclock/com.android.alarmclock.AlarmClock")
啓動瀏覽器 :
os.execute("am start -a android.intent.action.VIEW -d http://www.google.cn/ ")
撥打電話給10086 :
os.execute("am start -a android.intent.action.CALL -d tel:10086")
啓動 google map 直接定位到北京 :
os.execute("am start -a android.intent.action.VIEW geo:0,0?q=beijing")