[关闭]
@xxzhushou 2019-01-07T11:55:56.000000Z 字数 102631 阅读 31370

叉叉引擎XMod2.0 API手册

叉叉脚本 XMod

此页面已于2019-01-01起废弃,后续不再更新维护,敬请移步新文档库:叉叉脚本工具文档


目录索引

Lua扩展

◆ 函数 log : 输出日志到控制台

函数语法

void log(string msg)

函数说明

输出msg日志到控制台(叉叉集成开发环境中)。

使用示例

  1. local msg = string.format('测试输出: %d', 100)
  2. log(msg)

◆ 函数 printf : 格式化输出日志到控制台

函数语法

void printf(string foramt, ...)

函数说明

输出格式化后的日志内容到控制台(叉叉集成开发环境中)。

使用示例

  1. local t = { 1, 2, 3 }
  2. local size = Size(100, 200)
  3. -- 输出结果: 'format: table: 0xHHHHHH, Size[100 x 200], 100'
  4. printf('format: %s, %s, %d', t, size, 100)

◆ 函数 sleep : 休眠、暂停运行

函数语法

void sleep(integer timeMs)

函数说明

调用后脚本会休眠timeMs毫秒再继续执行。

使用示例

  1. log('开始sleep')
  2. sleep(300) -- 脚本休眠300毫秒
  3. log('结束sleep')

◆ 函数 os.netTime : 获取网络时间

函数语法

integer os.netTime(void)

函数说明

返回网络时间(local时间戳,单位秒),需要保证网络连接。

使用示例

  1. local currentTime = os.netTime()
  2. -- 输出结果: '2018-08-30 15:42:41'
  3. print(os.date('%Y-%m-%d %H:%M:%S', currentTime))

◆ 函数 os.milliTime : 获取毫秒级别本地时间

函数语法

integer os.milliTime(void)

函数说明

返回设备时间,单位毫秒。

使用示例

  1. local timeSec = os.time()
  2. local timeMilliSec = os.milliTime()
  3. -- 输出结果: 'true'
  4. print(math.floor(timeMilliSec / 1000) == timeSec)

特别说明

出于安全因素的考虑,以下Lua函数从2.0开始不再提供使用和支持:

内置全局类型

Point 坐标

◆ 常量 Point.ZERO

常量值: Point Point(0, 0)


◆ 常量 Point.INVALID

常量值: Point Point(-1, -1)


◆ 变量 Point.x : x坐标值

变量类型: integer


◆ 变量 Point.y : y坐标值

变量类型: integer


◆ 函数 Point : 构建坐标实例

函数语法

函数说明

使用示例

  1. local point = Point(100, 200)
  2. -- 输出结果: 'point = Point(100, 200)'
  3. printf('point = %s', point)

◆ 基本运算

Point支持+-*/==和取反等基本运算。

使用示例

  1. local a = Point(10, 20)
  2. local b = Point(100, 200)
  3. -- 输出结果: 'a + b = Point(110, 220)'
  4. printf('a + b = %s', a + b)
  5. -- 输出结果: 'b - a = Point(90, 180)'
  6. printf('b - a = %s', b - a)
  7. -- 输出结果: 'a * 10 = Point(100, 200)'
  8. printf('a * 10 = %s', a * 10)
  9. -- 输出结果: 'b / 10 = Point(10, 20)'
  10. printf('b / 10 = %s', b / 10)
  11. -- 输出结果: 'a * 10 == b ? true'
  12. printf('a * 10 == b ? %s', (a * 10 == b))
  13. -- 输出结果: '-a = Point(-10, -20)'
  14. printf('-a = %s', -a)

Size 尺寸

◆ 常量 Size.ZERO

常量值: Size Size(0, 0)


◆ 常量 Size.INVALID

常量值: Size Size(-1, -1)


◆ 变量 Size.width : 尺寸的宽

变量类型: integer


◆ 变量 Size.height : 尺寸的高

变量类型: integer


◆ 函数 Size : 构建尺寸实例

函数语法

函数说明

使用示例

  1. local size = Size(200, 200)
  2. -- 输出结果: 'size = Size[200 x 200]'
  3. printf('size = %s', size)

◆ 基本运算

和Point类似,Size支持+-*/==和取反等基本运算。

使用示例

  1. local a = Size(10, 20)
  2. local b = Size(100, 200)
  3. -- 输出结果: 'a + b = Size[110 x 220]'
  4. printf('a + b = %s', a + b)
  5. -- 输出结果: 'b - a = Size[90 x 180]'
  6. printf('b - a = %s', b - a)
  7. -- 输出结果: 'a * 10 = Size[100 x 200]'
  8. printf('a * 10 = %s', a * 10)
  9. -- 输出结果: 'b / 10 = Size[10 x 20]'
  10. printf('b / 10 = %s', b / 10)
  11. -- 输出结果: 'a * 10 == b ? true'
  12. printf('a * 10 == b ? %s', (a * 10 == b))
  13. -- 输出结果: '-a = Size[-10 x -20]'
  14. printf('-a = %s', -a)

Rect 矩形

◆ 常量 Rect.ZERO

常量值: Rect Rect(0, 0, 0, 0)


◆ 变量 Rect.x : 左上角x坐标值

变量类型: integer


◆ 变量 Rect.y : 左上角y坐标值

变量类型: integer


◆ 变量 Rect.width : 矩形的宽

变量类型: integer


◆ 变量 Rect.height : 矩形的高

变量类型: integer


◆ 函数 Rect : 构建矩形实例

函数语法

函数说明

使用示例

  1. local rect = Rect(100, 100, 200, 200)
  2. -- 输出结果: 'rect = Rect<Point(100, 100), Size[200 x 200]>'
  3. printf('rect = %s', rect)

◆ 函数 Rect:tl : 获取矩形的左上角坐标

函数语法

Point Rect:tl(void)

函数说明

返回当前Rect的top-left(左上角)Point坐标。

使用示例

  1. local rect = Rect(100, 100, 200, 200)
  2. -- 输出结果: 'rect:tl() = Point(100, 100)'
  3. printf('rect:tl() = %s', rect:tl())

◆ 函数 Rect:br : 获取矩形的右下角坐标

函数语法

Point Rect:br(void)

函数说明

返回当前Rect的bottom-right(右下角)Point坐标。

使用示例

  1. local rect = Rect(100, 100, 200, 200)
  2. -- 输出结果: 'rect:br() = Point(300, 300)'
  3. printf('rect:br() = %s', rect:br())

◆ 函数 Rect:size : 获取矩形尺寸

函数语法

Size Rect:size(void)

函数说明

获取当前Rect的尺寸。

使用示例

  1. local rect = Rect(100, 100, 200, 200)
  2. -- 输出结果: 'rect:size() = Size[200, 200]'
  3. printf('rect:size() = %s', rect:size())

◆ 函数 Rect:contains : 判断矩形是否包含坐标

函数语法

boolean Rect:contains(Point point)

函数说明

判断point坐标是否在当前Rect的范围内。

使用示例

  1. local rect = Rect(100, 100, 200, 200)
  2. -- 输出结果: 'true'
  3. print(rect:contains(Point(150, 200)))

◆ 函数 Rect:union : 矩形合并操作

函数语法

Rect Rect:union(Rect other)

函数说明

返回同时能包含当前Rect和other的最小Rect。

使用示例

  1. local a = Rect(100, 100, 200, 200)
  2. local b = Rect(150, 150, 300, 50)
  3. -- 输出结果: 'a:union(b) = Rect<Point(100, 100), Size[350 x 200]>'
  4. printf('a:union(b) = %s', a:union(b))

◆ 函数 Rect:intersect : 矩形相切操作

函数语法

Rect Rect:intersect(Rect other)

函数说明

返回当前Rect和other交集的最大Rect。

使用示例

  1. local a = Rect(100, 100, 200, 200)
  2. local b = Rect(150, 150, 300, 50)
  3. -- 输出结果: 'a:intersect(b) = Rect<Point(150, 150), Size[150 x 50]>'
  4. printf('a:intersect(b) = %s', a:intersect(b))

Color3B 颜色值(整型)

◆ 变量 Color3B.r : 红色色值

变量类型: integer

变量范围: 0 ~ 255


◆ 变量 Color3B.g : 绿色色值

变量类型: integer

变量范围: 0 ~ 255


◆ 变量 Color3B.b : 蓝色色值

变量类型: integer

变量范围: 0 ~ 255


◆ 函数 Color3B : 构造颜色值(整型)实例

函数语法

函数说明

从整型/字符串/等格式表示的颜色值构建Color3B对象。

使用示例

  1. local c3b = Color3B(0xaabbcc)
  2. local c3b2 = Color3B(c3b)
  3. -- 输出结果: 'rgb = (aa, bb, cc)'
  4. printf('rgb = (%x, %x, %x)', c3b2.r, c3b2.g, c3b2.b)

◆ 函数 Color3B:toInt : 转换成整型色值

函数语法

integer Color3B:toInt(void)

函数说明

将Color3B对象转换成integer表示。


◆ 函数 Color3B:toString : 转换成字符串色值

函数语法

string Color3B:toString(void)

函数说明

将Color3B对象转换成hex-string表示。

使用示例

  1. local c3b = Color3B(0xaa, 0xbb, 0xcc)
  2. -- 输出结果: 'c3b:toInt() = 0xaabbcc'
  3. printf('c3b:toInt() = %x', c3b:toInt())
  4. -- 输出结果: 'c3b:toString() = "0xaabbcc"'
  5. printf('c3b:toString() = "%s"', c3b:toString())

Color3F 颜色值(浮点型)

◆ 变量 Color3F.r : 红色色值

变量类型: number

变量范围: 0.0 ~ 1.0


◆ 变量 Color3F.g : 绿色色值

变量类型: number

变量范围: 0.0 ~ 1.0


◆ 变量 Color3F.b : 蓝色色值

变量类型: number

变量范围: 0.0 ~ 1.0


◆ 函数 Color3F : 构造颜色值(浮点型)实例

函数语法

函数说明

从整型/字符串/等格式表示的颜色值构建Color3F对象。

使用示例

  1. local c3f = Color3F(0x102030)
  2. local c3f2 = Color3F(c3f)
  3. -- 输出结果: 'rgb = (0.062745, 0.125490, 0.188235)'
  4. printf('rgb = (%f, %f, %f)', c3f2.r, c3f2.g, c3f2.b)

◆ 函数 Color3F:toInt : 转换成整型色值

函数语法

integer Color3F:toInt(void)

函数说明

将Color3F对象转换成integer表示。


◆ 函数 Color3F:toString : 转换成字符串色值

函数语法

string Color3F:toString(void)

函数说明

将Color3B对象转换成hex-string表示。

使用示例

  1. local c3f = Color3F(0.62745, 0.125490, 0.188235)
  2. -- 输出结果: 'c3f:toInt() = 0x102030'
  3. printf('c3f:toInt() = %x', c3f:toInt())
  4. -- 输出结果: 'c3f:toString() = "0x102030"'
  5. printf('c3f:toString() = "%s"', c3f:toString())

综合模块 —— xmod

◆ 常量 xmod.PLATFORM_IOS

常量值: string'iOS'


◆ 常量 xmod.PLATFORM_ANDROID

常量值: string'Android'


◆ 常量 xmod.PLATFORM

常量值: string 当前系统平台标识,'iOS'、'Android'之一


◆ 常量 xmod.PRODUCT_CODE

常量值: integer当前产品平台代号标识

常量范围:


◆ 常量 xmod.PRODUCT_CODE_DEV

常量值: integer 1


◆ 常量 xmod.PRODUCT_CODE_XXZS

常量值: integer 2


◆ 常量 xmod.PRODUCT_CODE_IPA

常量值: integer 3


◆ 常量 xmod.PRODUCT_CODE_KUWAN

常量值: integer 4


◆ 常量 xmod.PRODUCT_CODE_SPIRIT

常量值: integer 5


◆ 常量 xmod.PRODUCT_NAME

常量值: string 当前产品平台代号名称,'DEV'、'XXZS'、'IPA'、'KUWAN'、'SPIRIT'之一


◆ 常量 xmod.VERSION_CODE

常量值: integer当前脚本引擎版本号


◆ 常量 xmod.VERSION_NAME

常量值: string 当前脚本引擎版本名


◆ 常量 xmod.HANDLER_ON_USER_EXIT

常量值: integer 1


◆ 常量 xmod.HANDLER_ON_RUNTIME_ERROR

常量值: integer 2


◆ 常量 xmod.SCREENCAP_POLICY_STANDARD

常量值: integer 0


◆ 常量 xmod.SCREENCAP_POLICY_AGGRESSIVE

常量值: integer 1


◆ 常量 xmod.SCREENCAP_POLICY

常量值: string'screencap_policy'


◆ 常量 xmod.SCREENCAP_KEEP

常量值: string'screencap_keep'


◆ 函数 xmod.setConfig : 设置引擎属性

函数语法

函数说明

设置引擎属性,目前key仅支持以下值(其他key值会忽略):

使用示例

  1. if xmod.PRODUCT_CODE ~= xmod.PRODUCT_CODE_IPA then
  2. -- IPA运行平台, 开启AGGRESSIVE模式
  3. xmod.setConfig(xmod.SCREENCAP_POLICY, xmod.SCREENCAP_POLICY_AGGRESSIVE)
  4. end

◆ 函数 xmod.getConfig : 获取引擎属性

函数语法

函数说明

获取当前设置的引擎属性。

使用示例

  1. local policy = xmod.getConfig(xmod.SCREENCAP_POLICY, xmod.SCREENCAP_POLICY_STANDARD)
  2. -- 可能输出结果: 'policy = 0'
  3. printf('policy = %d', policy)

◆ 函数 xmod.getPublicPath : 获取引擎公共目录

函数语法

string xmod.getPublicPath(void)

函数说明

获取引擎公共文件夹目录路径,详情参见附录A. 引擎目录说明

使用示例

  1. -- 保存截图到引擎公共目录
  2. local path = xmod.getPublicPath() .. '/test.png'
  3. screen.snapshot(path)

◆ 函数 xmod.getPrivatePath : 获取脚本私有目录

函数语法

string xmod.getPrivatePath(void)

函数说明

获取脚本私有文件夹目录路径,详情参见附录A. 引擎目录说明

使用示例

  1. -- 保存截图到脚本私有目录
  2. local path = xmod.getPrivatePath() .. '/test.png'
  3. screen.snapshot(path)

◆ 函数 xmod.resolvePath : 目录转换

函数语法

string xmod.resolvePath(string path)

函数说明

[private]xxxx/[public]xxxx等路径表达形式的全路径转换,方便快捷访问引擎公共目录和脚本私有目录,详情参见附录A. 引擎目录说明

使用示例

  1. -- 保存截图到引擎公共目录
  2. screen.snapshot(xmod.resolvePath('[public]test.png'))
  3. -- 保存截图到脚本私有目录
  4. screen.snapshot(xmod.resolvePath('[private]test.png'))

◆ 函数 xmod.setOnEventCallback : 设置事件回调

函数语法

void xmod.setOnEventCallback(integer event, function callback)

函数说明

设置当触发了event事件时,回调到callback函数。目前支持的event取值是:

使用示例

  1. -- 监听用户主动退出事件,提示某些信息
  2. xmod.setOnEventCallback(xmod.EVENT_ON_USER_EXIT, function ()
  3. UI.toast('欢迎下次使用 bye!')
  4. end)
  5. -- 监听脚本运行时错误,保存错误信息
  6. xmod.setOnEventCallback(xmod.EVENT_ON_RUNTIME_ERROR, function (errMsg)
  7. local path = xmod.getPublicPath() .. '/err.log'
  8. local f = io.open(path, 'w')
  9. if f then
  10. f:write(errMsg)
  11. f:close()
  12. UI.toast('出错了!请将错误日志"' .. path .. '"发送给作者(QQ:123456)')
  13. end
  14. end)

◆ 函数 xmod.exit : 脚本退出

函数语法

void xmod.exit(void)

函数说明

主动退出脚本运行。

使用示例

  1. xpcall(doLaunch, function()
  2. UI.toast('something go wrong. 脚本已退出')
  3. xmod.exit()
  4. end)

◆ 函数 xmod.restart : 脚本重启

函数语法

void xmod.restart(void)

函数说明

主动重启脚本。

使用示例

  1. xpcall(doLaunch, function()
  2. UI.toast('something go wrong. 脚本重启中')
  3. xmod.restart()
  4. end)

脚本控制模块 —— script

UserInfo 用户信息

◆ 变量 UserInfo.id : 唯一标识

变量类型: string

变量描述: 当前脚本用户的唯一标识,开发助手下获取返回'null'。注意该值并非果盘账号,但能唯一对应果盘账号。


◆ 变量 UserInfo.membership : 会员标识

变量类型: integer

变量描述: 当前脚本用户的会员标识,开发助手下获取返回3.

变量范围:

注意通过激活码激活的用户(包括日卡),也会被认定为付费用户。


◆ 变量 UserInfo.expiredTime : 剩余时间

变量类型: integer

变量描述: 当前脚本用户的套餐剩余时间(单位秒),开发助手下获取返回-1


ScriptInfo 脚本信息

◆ 变量 ScriptInfo.id : 唯一标识

变量类型: integer

变量描述: 当前脚本ID,开发助手下获取返回-1


◆ 函数 script.getUserInfo : 获取用户信息

函数语法

UserInfo,integer script.getUserInfo(void)

函数说明

获取当前脚本用户信息,返回UserInfo类型数据和错误码。错误码对照表如下:

使用示例

  1. local userInfo, code = script.getUserInfo()
  2. if code == 0 then
  3. -- 试用用户, 提醒付费
  4. if userInfo.membership == 2 then
  5. UI.toast('试用将于%s结束。现在脚本限时特价-50% off,3天后恢复原价!', os.date('%Y-%m-%d %H:%M:%S', os.netTime() + userInfo.expiredTime))
  6. end
  7. end

◆ 函数 script.getScriptInfo : 获取脚本信息

函数语法

ScriptInfo,integer script.getScriptInfo(void)

函数说明

获取当前脚本信息,返回ScriptInfo类型数据和错误码。错误码对照表如下:

使用示例

  1. local scriptInfo, code = script.getScriptInfo()
  2. if code == 0 then
  3. printf('当前脚本ID: %d', scriptInfo.id)
  4. end

◆ 函数 script.getBillboard : 获取脚本公告

函数语法

string,integer script.getBillboard(string key, string token)

函数说明

根据key和token,获取对应脚本公告信息,返回公告内容和错误码。错误码对照表如下:

补充说明

使用示例

  1. -- 获取后台配置key'hello_text'的公告内容, 开发环境下需要传入token
  2. local content, code = script.getBillboard('hello_text', token)
  3. if content ~= '' then
  4. UI.toast(content)
  5. end

◆ 函数 script.getUIData : 获取ui目录资源内容

函数语法

string script.getUIData(string file)

函数说明

获取xsp文件ui/目录下的file文件资源。

使用示例

  1. local cjson = require('cjson')
  2. -- 获取ui.json文件内容
  3. local uiJsonStr = script.getUIData('ui.json')
  4. -- cjson进行decode, 得到table
  5. local uiJson = cjson.decode(uiJsonStr)
  6. -- 修改ui.json的宽高
  7. uiJson['width'] = uiJson['width'] * 0.8
  8. uiJson['height'] = uiJson['height'] * 0.8
  9. -- table交由UI展示
  10. local context = UI.createContext(uiJson)
  11. context:show()

◆ 函数 script.getResData : 获取res目录资源内容

函数语法

string script.getResData(string file)

函数说明

获取xsp文件res/目录下的file文件资源。

使用示例

  1. -- xspres/num.traineddata文件转存到私有目录下
  2. local lfs = require('lfs')
  3. local numFile = 'num.traineddata'
  4. local rawData = script.getResData(numFile)
  5. local destDir = xmod.getPrivatePath() .. '/tessdata'
  6. if lfs.mkdir(destDir) then
  7. local f = io.open(destDir .. '/' .. numFile, 'w')
  8. if f then
  9. f:write(rawData)
  10. f:close()
  11. end
  12. else
  13. UI.toast('创建目录"' .. destDir .. '"失败!')
  14. xmod.exit()
  15. end

界面图像模块 —— screen

Image 图像

◆ 常量 Image.ROTATION_CLOCKWISE_90

常量值: integer 1


◆ 常量 Image.ROTATION_CLOCKWISE_180

常量值: integer 2


◆ 常量 Image.ROTATION_CLOCKWISE_270

常量值: integer 3


◆ 函数 Image.fromScreen : 从屏幕构造图像实例

函数语法

Image Image.fromScreen(Rect rect)

函数说明

将屏幕rect范围的图像截取成Image对象并返回。

特别说明

该函数结果受以下函数影响:

使用示例

  1. -- 截取屏幕Rect(0, 0, 100, 100)范围的图像, 并保存至脚本私有目录
  2. local img = Image.fromScreen(Rect(0, 0, 100, 100))
  3. img:saveToFile(xmod.getPrivatePath() .. '/test.png')
  4. -- 图片较大时, 使用完毕最好主动释放
  5. img:release()

◆ 函数 Image.fromFile : 从文件构造图像实例

函数语法

Image Image.fromFile(string path)

函数说明

加载path路径文件成Image对象并返回。

特别说明

path路径形式支持'[public]'/'[private]'等前缀。

使用示例

  1. -- 加载public目录下的test.png文件
  2. local img = Image.fromFile('[public]test.png')
  3. ...
  4. -- 加载/sdcard目录下的test.png文件
  5. local img2 = Image.fromFile('/sdcard/test.png')
  6. ...
  7. -- 加载xsp文件中res/目录下的test.png文件
  8. local img3 = Image.fromFile('test.png')
  9. ...

◆ 函数 Image:release : 释放图像

函数语法

void Image:release(void)

函数说明

主动释放Image对象,避免内存占用过高。

使用示例

  1. -- 截取屏幕Rect(0, 0, 100, 100)范围的图像, 并保存至脚本私有目录
  2. local img = Image.fromScreen(Rect(0, 0, 100, 100))
  3. img:saveToFile(xmod.getPrivatePath() .. '/test.png')
  4. img:release()

◆ 函数 Image:getSize : 获取图像尺寸

函数语法

Size Image:getSize(void)

函数说明

获取Image尺寸,返回Size类型。

使用示例

  1. local img = Image.fromScreen(Rect(0, 0, 100, 100))
  2. -- 输出结果: 'img:size() = Size[100 x 100]'
  3. printf('img:size() = %s', img:getSize())
  4. img:release()

◆ 函数 Image:getWidth : 获取图像尺寸-宽

函数语法

integer Image:getWidth(void)

函数说明

获取Image的宽度。

使用示例

  1. local img = Image.fromScreen(Rect(0, 0, 100, 100))
  2. -- 输出结果: 'img:getWidth() = 100'
  3. printf('img:getWidth() = %s', img:getWidth())
  4. img:release()

◆ 函数 Image:getHeight : 获取图像尺寸-高

函数语法

integer Image:getHeight(void)

函数说明

获取Image的高度。

使用示例

  1. local img = Image.fromScreen(Rect(0, 0, 100, 100))
  2. -- 输出结果: 'img:getHeight() = 100'
  3. printf('img:getHeight() = %s', img:getHeight())
  4. img:release()

◆ 函数 Image:setRotation : 旋转图像

函数语法

void Image:setRotation(integer rotation)

函数说明

旋转当前图像实例,rotation支持以下三个参数:

分别是将图像顺时针旋转90°、180°和270°

使用示例

  1. local img = Image.fromScreen(Rect(0, 0, 100, 100))
  2. img:setRotation(Image.ROTATION_CLOCKWISE_180)
  3. if img:saveToFile(xmod.getPrivatePath() .. '/test.jpg') then
  4. UI.toast('succeed!')
  5. end
  6. img:release()

◆ 函数 Image:saveToFile : 把图像实例保存到本地

函数语法

boolean Image:saveToFile(string path)

函数说明

将图片保存至path路径,仅支持jpg/png后缀的路径。

使用示例

  1. local img = Image.fromScreen(Rect(0, 0, 100, 100))
  2. if img:saveToFile(xmod.getPrivatePath() .. '/test.jpg') then
  3. UI.toast('succeed!')
  4. end
  5. img:release()

◆ 函数 Image:clip : 截取图像

函数语法

void Image:clip(Rect rect)

函数说明

在当前Image截取保留rect范围的像素。

使用示例

  1. local img = Image.fromScreen(Rect(0, 0, 100, 100))
  2. img:clip(Rect(20, 20, 20, 20))
  3. -- 输出结果: 'clipped size = Size[20 x 20]'
  4. printf('cliped size = %s', img:getSize())
  5. img:release()

◆ 函数 Image:getRGB : 获取图像颜色值(整型)

函数语法

函数说明

获取Image下pos = Point(x, y)坐标的R, G, B值。

使用示例

  1. -- 旋转前的(0, 0)处像素等于顺时针90°旋转后的(h - 1, 0)处像素
  2. local img = Image.fromScreen(Rect(0, 0, 100, 100))
  3. local r1, g1, b1 = img:getRGB(0, 0)
  4. img:setRotation(Image.ROTATION_CLOCKWISE_90)
  5. local r2, g2, b2 = img:getRGB(img:getHeight() - 1, 0)
  6. -- 输出结果: 'same RGB ? true'
  7. printf('same RGB ? %s', (r1 == r2) and (g1 == g2) and (b1 == b2))
  8. img:release()

◆ 函数 Image:getColor : 获取图像颜色值

函数语法

函数说明

获取Image下pos = Point(x, y)坐标的Color3B值。

使用示例

  1. -- 旋转前的(0, 0)处像素等于顺时针90°旋转后的(h - 1, 0)处像素
  2. local img = Image.fromScreen(Rect(0, 0, 100, 100))
  3. local c3b1 = img:getColor(0, 0)
  4. img:setRotation(Image.ROTATION_CLOCKWISE_90)
  5. local c3b2 = img:getColor(img:getHeight() - 1, 0)
  6. -- 输出结果: 'same Color3B ? true'
  7. printf('same Color3B ? %s', c3b1 == c3b2)
  8. img:release()

◆ 函数 Image:binarize : 图像二值化成table

函数语法

函数说明

根据diff/diffs偏色设置,将图片二值化成二维table数组,支持传入单组偏色 diff = '0xHHHHHH-0xHHHHHH' 和多组偏色 diffs = {'0xHHHHHH-0xHHHHHH', ...}。关于偏色和二值化的详细介绍请参见附录D. 偏色和二值化说明

使用示例

  1. -- 打印二值化后的数组
  2. local img = Image.fromScreen(Rect(0, 0, 100, 100))
  3. local data = img:binarize('0xcccccc-0x303030')
  4. -- 或者使用多组偏色值:
  5. -- local data = img:binarize({ '0xcccccc-0x303030', '0x1f1f1f-0x202020' })
  6. for _, row in pairs(data) do
  7. print(table.concat(row))
  8. end
  9. img:release()

◆ 常量 screen.LANDSCAPE_RIGHT

常量值: integer 1


◆ 常量 screen.LANDSCAPE_LEFT

常量值: integer 2


◆ 常量 screen.PORTRAIT

常量值: integer 3


◆ 常量 screen.PRIORITY_DEFAULT

常量值: integer 28672(0x7000)


◆ 常量 screen.PRIORITY_LEFT_FIRST

常量值: integer 4096 (0x1000)


◆ 常量 screen.PRIORITY_RIGHT_FIRST

常量值: integer 4097 (0x1001)


◆ 常量 screen.PRIORITY_UP_FIRST

常量值: integer 8192 (0x2000)


◆ 常量 screen.PRIORITY_DOWN_FIRST

常量值: integer 8208 (0x2010)


◆ 常量 screen.PRIORITY_HORIZONTAL_FIRST

常量值: integer 16384 (0x4000)


◆ 常量 screen.PRIORITY_VERTICAL_FIRST

常量值: integer 16640 (0x4100)


◆ 常量 screen.MOCK_NONE

常量值: integer 0


◆ 常量 screen.MOCK_INPUT

常量值: integer 0x1000


◆ 常量 screen.MOCK_INPUT_FIXED

常量值: integer 0x1000


◆ 常量 screen.MOCK_INPUT_RELATIVE

常量值: integer 0x3000


◆ 常量 screen.MOCK_OUTPUT

常量值: integer 0x10000


◆ 常量 screen.MOCK_BOTH

常量值: integer 0x11000


◆ 函数 screen.init : 初始化屏幕参数

函数语法

void screen.init(integer orientation)

函数说明

指定参考的坐标系,需要在使用touch和screen模块之前指定。orientation参数可以是以下值之一:

不论orientation指定的是哪种,坐标原点均在所指定的参考坐标系的左上角。

脚本运行过程中可以多次调用screen.init转换坐标系,后续执行按照最近一次screen.init指定的坐标系作为标准运行。

注意由于screen.init后会影响其他函数运行的结果,因此需要注意重复调用screen.init的情况下容易出错的情况。

使用示例

  1. local tap = function(x, y)
  2. touch.down(1, x, y)
  3. sleep(20)
  4. touch.up(1, x, y)
  5. end
  6. -- 以竖屏为参考坐标系
  7. screen.init(screen.PORTRAIT)
  8. local size = screen.getSize()
  9. -- 假定当前设备分辨率为1280x1920, 输出: 'size = Size[1280 x 1920]'
  10. printf('size = %s', size)
  11. -- 点击设备右下角(竖屏状态下)的(1230, 1870)处
  12. tap(size.width - 50, size.height - 50)
  13. -- 修改以横屏home右为参考坐标系
  14. screen.init(screen.LANDSCAPE_RIGHT)
  15. -- 下面tap函数期望结果是点击设备右下角(横屏home右状态下)的(1870, 1230)处
  16. -- 但实际上点击的是超出屏幕范围(1920, 1280)的无效坐标(1230, 1870)
  17. -- 原因是size是上次screen.init后获取的, 与当前坐标系不符
  18. tap(size.width - 50, size.height - 50) -- 错误
  19. tap(screen.getSize().width - 50, screen.getSize().height - 50) -- 正确

◆ 函数 screen.getSize : 获取屏幕分辨率尺寸

函数语法

Size screen.getSize(void)

函数说明

获取屏幕分辨率尺寸。

特别说明

该函数结果受以下函数影响:

使用示例

  1. screen.init(screen.LANDSCAPE_RIGHT)
  2. local size = screen.getSize()
  3. -- 点击屏幕中央
  4. touch.down(1, size.width / 2, size.height / 2)
  5. sleep(20)
  6. touch.up(1, size.width / 2, size.height / 2)

◆ 函数 screen.getDPI : 获取屏幕DPI

函数语法

integer screen.getDPI(void)

函数说明

获取屏幕DPI(每英寸点数)。


◆ 函数 screen.capture : 截取屏幕

函数语法

Image screen.capture(Rect rect)

函数说明

截取屏幕范围为rect的图像,并返回Image类型。该函数与Image.fromScreen功能一致。

特别说明

该函数结果受以下函数影响:

使用示例

  1. screen.init(screen.LANDSCAPE_RIGHT)
  2. local img = screen.capture(Rect(100, 100, 200, 200))
  3. -- 顺时针旋转90°并保存至public目录
  4. img:setRotation(Image.ROTATION_CLOCKWISE_90)
  5. img:saveToFile(xmod.getPublicPath() .. '/test.png')

◆ 函数 screen.keep : 保持屏幕内容

函数语法

void screen.keep(boolean value)

函数说明

传入参数value = true时,将会保持当前屏幕内容不变,在重新调用screen.keep(false)前的多次调用取色、找色、截图、找图等函数时,将会直接调用screen.keep(true)时保持的屏幕内容。

该函数主要用于优化多次找图找色函数的效率。

使用示例

  1. screen.init(screen.LANDSCAPE_RIGHT)
  2. -- 以下函数调用找色30次, 但只触发10次截图
  3. for i = 1, 10 do
  4. screen.keep(true) -- keep(true)时进行一次截图更新
  5. -- 下面三次连续找色, 基于上面screen.keep(true)时的截图缓存进行
  6. local pos = screen.findColor(Rect(100, 100, 200, 200), 0x112233)
  7. if pos ~= Point.INVALID then
  8. UI.toast('No.1 found')
  9. end
  10. sleep(1000)
  11. pos = screen.findColor(Rect(150, 150, 200, 200), 0x445566)
  12. if pos ~= Point.INVALID then
  13. UI.toast('No.2 found')
  14. end
  15. sleep(1000)
  16. pos = screen.findColor(Rect(200, 200, 200, 200), 0x778899)
  17. if pos ~= Point.INVALID then
  18. UI.toast('No.3 found')
  19. end
  20. sleep(1000)
  21. screen.keep(false) -- 释放截图缓存
  22. end

◆ 函数 screen.getOrientation : 获取屏幕方向

函数语法

integer screen.getOrientation(void)

函数说明

获取当前设备的屏幕方向。

注意该函数返回值仅和当前设备物理转向有关,并非返回screen.init设定的值。

使用示例

  1. local orientation = screen.getOrientation()
  2. if orientation == screen.PORTRAIT then
  3. UI.toast('竖屏')
  4. elseif orientation == screen.LANDSCAPE_LEFT then
  5. UI.toast('横屏, home在左边')
  6. elseif orientation == screen.LANDSCAPE_RIGHT then
  7. UI.toast('横屏, home在右边')
  8. end

◆ 函数 screen.snapshot : 截图并保存至本地

函数语法

函数说明

实时截图屏幕rect范围(不指定或rect = Rect(0, 0, 0, 0)表示全屏范围)的图像并保存至path路径,可选quality为图片质量(取值范围0-100),截图成功返回true,失败返回false(例如指定路径无权限访问)。

注意path路径只能是jpg/png后缀结尾。

特别说明

该函数结果受以下函数影响:

使用示例

  1. -- 保存截图到引擎公共目录
  2. local path = xmod.getPublicPath() .. '/test.png'
  3. screen.snapshot(path)
  4. -- 保存截图到引擎公共目录, 指定quality=85
  5. local path2 = xmod.getPublicPath() .. '/test2.png'
  6. screen.snapshot(path, Rect(0, 0, 0, 0), 85)

◆ 函数 screen.getRGB : 获取屏幕颜色值(RGB)

函数语法

函数说明

获取当前屏幕中pos = Point(x, y)坐标的R、G、B值。

特别说明

该函数结果受以下函数影响:

使用示例

  1. -- 获取(110, 110)坐标处的RGB色值
  2. local pos = Point(100, 100)
  3. local r, g, b = screen.getRGB(pos + Point(10, 10))
  4. printf('rgb = %d, %d, %d', r, g, b)

◆ 函数 screen.getColor : 获取屏幕颜色值

函数语法

函数说明

获取当前屏幕中pos = Point(x, y)坐标的Color3B值。

特别说明

该函数结果受以下函数影响:

使用示例

  1. -- 获取(110, 110)坐标处的Color3B色值
  2. local pos = Point(100, 100)
  3. local c3b = screen.getColor(pos + Point(10, 10))
  4. printf('c3b = %d, %d, %d', c3b.r, c3b.g, c3b.b)

◆ 函数 screen.matchColor : 比较颜色值

函数语法

函数说明

对比当前屏幕中pos = Point(x, y)坐标的颜色值与color颜色值,返回结果为在模糊度fuzziness(取值范围0-100,默认100)基准下判断是否吻合。

color支持所有附录B. 颜色值和颜色序列规范-颜色值中描述的颜色值格式数据。

特别说明

该函数结果受以下函数影响:

使用示例

  1. if screen.matchColor(Point(100, 100), 0x303030, 95) then
  2. print('(100, 100)坐标处色值与0x303030吻合(5%容差下)')
  3. end

◆ 函数 screen.matchColors : 比较颜色序列

函数语法

函数说明

对比当前屏幕中colors描述下的颜色序列,返回结果为在全局模糊度globalFuzz(取值范围0-100,默认100)基准下判断是否吻合。

特别说明

该函数结果受以下函数影响:

使用示例

  1. if screen.matchColors('268|802|0x181F85,297|803|0x00BBFE,371|798|0x0B6BBE', 95) then
  2. print('对应坐标的颜色序列吻合(5%容差下)')
  3. end

◆ 函数 screen.findImage : 查找图像

函数语法

函数说明

根据指定的屏幕范围rect中,查找image指定的图像,可选fuzzness指定模糊度(范围0-100,默认100),可选priority指定搜索优先级,返回第一个找到的坐标,查找失败返回Point.INVALID。

特别说明

该函数结果受以下函数影响:

使用示例

  1. screen.init(screen.LANDSCAPE_RIGHT)
  2. -- Rect(100, 100, 50, 50)范围中, 查找匹配xsp res/logo.png图像, 模糊度为95
  3. screen.findImage(Rect(100, 100, 50, 50), 'logo.png', 95)
  4. -- 也可以匹配从sdcard加载的图像文件
  5. local image = Image.fromFile('/sdcard/logo.png')
  6. screen.findImage(Rect(100, 100, 50, 50), image, 95)
  7. image:release()

◆ 函数 screen.findColor : 查找颜色值/序列坐标

函数语法

函数说明

根据指定的屏幕范围rect中,查找color色值或序列的坐标值,可选globalFuzz指定全局模糊度(范围0-100,默认100),可选priority指定搜索优先级,返回第一个找到的坐标,查找失败返回Point.INVALID。

特别说明

该函数结果受以下函数影响:

使用示例

  1. -- 组合priority用到的二进制操作模块bit库, 引擎内置但需要主动require加载使用
  2. local bit = require('bit32')
  3. -- 先指定坐标系进行初始化
  4. screen.init(screen.LANDSCAPE_RIGHT)
  5. -- 使用screen.keep优化找色效率
  6. screen.keep(true)
  7. -- 从下到上, 从左到右的顺序查找
  8. local priority = bit.bor(screen.PRIORITY_LEFT_FIRST, screen.PRIORITY_DOWN_FIRST, screen.PRIORITY_VERTICAL_FIRST)
  9. -- Rect(100, 100, 200, 200)范围查找色值0xba3e00, 模糊度为90
  10. local pos = screen.findColor(Rect(100, 100, 200, 200), 0xba3e00, 90, priority)
  11. if pos ~= Point.INVALID then
  12. printf('No.1 found at %s', pos)
  13. end
  14. -- Rect(100, 100, 300, 500)范围查找string色值序列,模糊度为90, 默认优先级
  15. local pos = screen.findColor(Rect(100, 100, 200, 200), '0|0|0xffff57,17|14|0x48621b,53|-3|0xb1ff54', 90)
  16. if pos ~= Point.INVALID then
  17. printf('No.2 found at %s', pos)
  18. end
  19. -- Rect(100, 100, 300, 500)范围查找table色值序列,模糊度为90, 默认优先级
  20. local pos = screen.findColor(Rect(100, 100, 200, 200),
  21. {
  22. { pos = Point(0, 0), color = 0xffff57 },
  23. { pos = Point(17, 14), color = 0x48621b },
  24. { pos = Point(53, -3), color = 0xb1ff54 }
  25. }, 90)
  26. if pos ~= Point.INVALID then
  27. printf('No.3 found at %s', pos)
  28. end
  29. screen.keep(false)

◆ 函数 screen.findColors : 查找所有颜色值/序列坐标

函数语法

函数说明

函数功能与screen.findColor类似,但返回rect范围内所有符合条件的点(最多不超过limit个)。

特别说明

该函数结果受以下函数影响:

使用示例

  1. -- 生成priority用到的二进制操作模块bit库, 引擎内置但需要主动require加载使用
  2. local bit = require('bit32')
  3. -- 先指定坐标系进行初始化
  4. screen.init(screen.LANDSCAPE_RIGHT)
  5. -- 使用screen.keep优化找色效率
  6. screen.keep(true)
  7. -- 从下到上, 从左到右的顺序查找
  8. local priority = bit.bor(screen.PRIORITY_LEFT_FIRST, screen.PRIORITY_DOWN_FIRST, screen.PRIORITY_VERTICAL_FIRST)
  9. -- Rect(100, 100, 200, 200)范围查找色值0xba3e00, 模糊度为90, 上限99
  10. local result = screen.findColors(Rect(100, 100, 200, 200), 0xba3e00, 90, priority, 99)
  11. if #result > 0 then
  12. for i, pos in pairs(result) do
  13. printf('No.1 found %d at %s', i, pos)
  14. end
  15. end
  16. -- Rect(100, 100, 300, 500)范围查找string色值序列,模糊度为90, 默认优先级, 默认上限200
  17. local result = screen.findColors(Rect(100, 100, 200, 200), '0|0|0xffff57,17|14|0x48621b,53|-3|0xb1ff54', 90)
  18. if #result > 0 then
  19. for i, pos in pairs(result) do
  20. printf('No.2 found %d at %s', i, pos)
  21. end
  22. end
  23. -- Rect(100, 100, 300, 500)范围查找table色值序列,模糊度为90, 默认优先级, 默认上限200
  24. local result = screen.findColors(Rect(100, 100, 200, 200),
  25. {
  26. { pos = Point(0, 0), color = 0xffff57 },
  27. { pos = Point(17, 14), color = 0x48621b },
  28. { pos = Point(53, -3), color = 0xb1ff54 }
  29. }, 90)
  30. if #result > 0 then
  31. for i, pos in pairs(result) do
  32. printf('No.3 found %d at %s', i, pos)
  33. end
  34. end
  35. screen.keep(false)

◆ 函数 screen.setMockMode : 设置坐标转换模式

函数语法

void screen.setMockMode(integer mode)

函数说明

配合screen.setMockTransform函数使用,用于控制脚本中坐标的转换模式,mode可以有以下取值:


◆ 函数 screen.setMockTransform : 设置坐标转换回调函数

函数语法

Rect screen.setMockTransform(function transform)

函数说明

配合screen.setMockMode使用,设置转换函数,用于脚本对多分辨率的支持,通过该函数开发者可以对脚本运行过程中其他函数传入、返回的rect数据进行修改,返回修改后的值。

transform接收两个参数:

特别说明

该函数会影响以下函数结果:

输入数据指以上所有受screen.setMockTransform函数影响的函数所传入rect区域参数或者point位置参数,例如touch.down(x, y)中的x和y参数会以mode = screen.MOCK_INPUT_FIXED, rect = Rect(x, y, 0, 0)形式传递到transform函数中;

输出数据指以上所有受screen.setMockTransform函数影响的函数返回值(如果有的话),例如result = screen.findColors(...)中result table里每项x, y数据会以mode = screen.MOCK_OUTPUT, rect = Rect(x, y, 0, 0)形式传递到transform函数中。

以screen.findColor代码为例:

  1. local pos = screen.findColor(Rect(100, 200, 300, 300),
  2. {
  3. { pos = Point(0, 0), color = 0x101010 },
  4. { pos = Point(-10, 30), color = 0x202020 }
  5. })
  6. if pos ~= Point.INVALID then
  7. touch.down(1, pos)
  8. sleep(20)
  9. touch.up(1, pos)
  10. end

设置了screen.setMockTransform的transform转换函数之后,以上代码等同于:

  1. local bit = require('bit32')
  2. -- 搜索范围是固定类型
  3. local rect = transform(screen.MOCK_INPUT_FIXED, Rect(100, 200, 300, 300))
  4. local colors = {}
  5. for k, c in pairs(colors) do
  6. if k > 1 then
  7. -- 第一个点是目标色点, 不需要转换
  8. -- 从第二个点开始, 使用screen.MOCK_INPUT_RELATIVE组合模式
  9. table.insert(colors, { pos = transform(bit.bor(screen.MOCK_INPUT_RELATIVE, k), Rect(c.pos, Size(0, 0))):tl(), color = c.color })
  10. end
  11. end
  12. local tmp = screen.findColor(rect, colors)
  13. local pos = transform(screen.MOCK_OUTPUT, Rect(tmp, Size(0, 0))):tl()
  14. -- 点击的坐标是固定类型
  15. if pos ~= Point.INVALID then
  16. touch.down(1, transform(screen.MOCK_INPUT_FIXED, pos))
  17. sleep(20)
  18. touch.up(1, transform(screen.MOCK_INPUT_FIXED, pos))
  19. end

使用示例

  1. function setScreenScale(width, height)
  2. -- 对输入和输出结果进行转换
  3. screen.setMockMode(screen.MOCK_BOTH)
  4. screen.setMockTransform(function (mode, rect)
  5. -- 简单缩放兼容中, 不论modeINPUT还是OUTPUT
  6. -- 都直接按对应缩放比例进行缩放即可
  7. local screenSize = screen.getSize()
  8. local scaleW, scaleH = width / screenSize.width, height / screenSize.height
  9. -- rect进行等比缩放, 返回修改后的rect
  10. rect.x = rect.x * scaleW
  11. rect.y = rect.y * scaleH
  12. rect.width = rect.width * scaleW
  13. rect.height = rect.height * scaleH
  14. return rect
  15. end)
  16. end
  17. -- 1080P分辨率设备开发的脚本, 简单的使用宽高等比转换, 尝试兼容其他同比例分辨率的设备
  18. setScreenScale(1920, 1080)
  1. local function isQuanmianping()
  2. -- 根据实际分辨率, 判断是否全面屏
  3. return true
  4. end
  5. -- 对输入和输出结果进行转换
  6. local bit = require('bit32')
  7. screen.setMockMode(screen.MOCK_BOTH)
  8. -- 适配某些游戏在全面屏设备上下有黑边的情况, 假定黑边高度为40
  9. screen.setMockTransform(function (mode, rect)
  10. -- 如果是输入类型
  11. if bit.band(mode, screen.MOCK_INPUT) == screen.MOCK_INPUT then
  12. if bit.band(mode, screen.MOCK_INPUT_RELATIVE) == screen.MOCK_INPUT_RELATIVE then
  13. -- 找色序列输入类型, 可以按需处理缩放, 这里只考虑单纯的黑边兼容
  14. else
  15. -- 固定坐标输入类型, 如果是全面屏则将y坐标加上黑边高度
  16. if isQuanmianping() then
  17. rect.y = rect.y + 40
  18. end
  19. end
  20. end
  21. return rect
  22. end)
  23. -- 需要取消转换, 则直接将转换函数设置成nil即可
  24. screen.setMockTransform(nil)

点按模块 —— touch

◆ 常量 touch.KEY_HOME

常量值: integer0


◆ 常量 touch.KEY_BACK

常量值: integer2


◆ 常量 touch.KEY_MENU

常量值: integer3


◆ 常量 touch.KEY_POWER

常量值: integer4


◆ 常量 touch.KEY_VOLUME_UP

常量值: integer5


◆ 常量 touch.KEY_VOLUME_DOWN

常量值: integer6


◆ 函数 touch.down : 模拟点击按下

函数语法

函数说明

指定手指序号index和pos = Point(x, y)坐标,模拟点击按下操作。

index用于标记手指序号,用于多点触控中标记多只手指,分别控制它们的移动。一般从1开始递增,模拟不同手指使用不同index。

特别说明

使用touch.down、touch.move和touch.up函数时,中间一定要使用sleep插入一定的延时,建议大于15毫秒,否则可能会出现点击无效等异常情况。

该函数结果受以下函数影响:

使用示例

  1. screen.init(screen.PORTRAIT)
  2. -- 模拟按下起始坐标(100, 200)
  3. local pos = Point(100, 200)
  4. touch.down(1, pos)
  5. for i = 1, 10 do
  6. sleep(15)
  7. -- 模拟手指每次移动递增(3, 2)像素
  8. pos = pos + Point(3, 2)
  9. touch.move(1, pos)
  10. end
  11. sleep(15)
  12. -- 模拟抬起手指
  13. touch.up(1, pos)

◆ 函数 touch.move : 模拟点击滑动

函数语法

函数说明

指定手指序号index和pos = Point(x, y)坐标,模拟点击移动操作。

index用于标记手指序号,用于多点触控中标记多只手指,分别控制它们的移动。一般从1开始递增,模拟不同手指使用不同index。

特别说明

使用touch.down、touch.move和touch.up函数时,中间一定要使用sleep插入一定的延时,建议大于20毫秒,否则可能会出现点击无效等异常情况。

touch.move必须用在touch.down之后才有意义。

该函数结果受以下函数影响:

使用示例

  1. -- 模拟序号为1的点击按下坐标(100, 100)
  2. touch.down(1, 100, 100)
  3. -- 模拟序号为2的点击按下坐标(300, 500)
  4. touch.down(2, 300, 500)
  5. sleep(30);
  6. -- 使用for循环模拟不同序号的手指向不同方向分离
  7. for i = 1, 100, 10 do
  8. touch.move(1, 200 - i, 400 - i)
  9. touch.move(2, 300 + i, 500 + i)
  10. sleep(30)
  11. end
  12. -- 分别模拟抬起操作
  13. touch.up(1, 200 - 100, 400 - 100)
  14. touch.up(2, 300 + 100, 500 + 100)

◆ 函数 touch.up : 模拟点击抬起

函数语法

函数说明

指定手指序号index和pos = Point(x, y)坐标,模拟点击抬起操作。

index用于标记手指序号,用于多点触控中标记多只手指,分别控制它们的移动。一般从1开始递增,模拟不同手指使用不同index。

特别说明

使用touch.down、touch.move和touch.up函数时,中间一定要使用sleep插入一定的延时,建议大于20毫秒,否则可能会出现点击无效等异常情况。

touch.up必须用在touch.down或touch.move之后才有意义。

该函数结果受以下函数影响:


◆ 函数 touch.press : 模拟按键按下

函数语法

函数说明

模拟点击设备功能按键的操作,type可以是以下值:

使用示例

  1. -- 单按Home
  2. touch.press(touch.KEY_HOME)
  3. -- 长按菜单键
  4. touch.press(touch.KEY_MENU, true)

◆ 函数 touch.doublePress : 模拟按键双击

函数语法

void touch.doublePress(integer type)

函数说明

模拟双击设备功能按键的操作,type可以是以下值:

使用示例

  1. -- 双击Home
  2. touch.doublePress(touch.KEY_HOME)

◆ 函数 touch.captureTap : 捕获用户点击

函数语法

函数说明

等待timeoutM毫秒(默认6000毫秒),期间监听用户进行一次或count次屏幕点击,并返回点击的坐标

特别说明

该函数结果受以下函数影响:

简单存储模块 —— storage

◆ 函数 storage.put : 存储数据

函数语法

函数说明

将key-value键值存到本地缓存。

特别说明

storage.put并不会立刻写入到文件,只是写入到内存,任何未经storage.commit的存储数据会在脚本重启后丢失。需要同步到文件需要主动调用storage.commit


◆ 函数 storage.get : 提取数据

函数语法

函数说明

从本地存储中获取key对应的数据,如果key不存在则返回defValue。

◆ 函数 storage.purge : 清除所有数据

函数语法

void storage.purge(void)

函数说明

清除当前storage.put存入的所有数据。


◆ 函数 storage.commit : 提交数据缓存

函数语法

boolean storage.commit(void)

函数说明

将storage.put操作存入的所有数据内容写入到文件中,存放于私有目录并加密。


使用示例

  1. -- 首次获取, 由于key=age不存在, 返回defValue=18
  2. local age = storage.get('age', 18)
  3. printf('age = %d', age)
  4. -- age1, 存回内存
  5. storage.put('age', age + 1)
  6. age = storage.get('age', 18)
  7. printf('age = %d', age)
  8. storage.put('name', 'Ace')
  9. storage.put('vip', true)
  10. -- 只有commit后才会一次性存入到文件(路径根据脚本自动生成)
  11. storage.commit()

任务执行模块 —— task

◆ 函数 task.execTimer : 定时执行任务

函数语法

void task.execTimer(integer delayMs, function callback, ...)

函数说明

从调用起在指定的timeMs毫秒延时之后,回调指定的callback函数,同时把传入参数回调到callback中。

使用示例

  1. --每隔2toast提示一次a + b + c的结果
  2. local function func(a, b, c)
  3. UI.toast('a + b + c = ' .. (a + b + c))
  4. a, b, c = a + 1, b + 2, c + 3
  5. task.execTimer(2000, func, a, b, c)
  6. end
  7. task.execTimer(2000, func, 1, 2, 3)
  8. local t = 0
  9. while t < 10 do
  10. sleep(1000)
  11. t = t + 1
  12. end

◆ 函数 task.execAsync : 异步执行任务

函数语法

函数说明

引擎内部启动新线程执行异步操作,执行完成回调callback函数结果,目前仅支持网络访问操作。

使用示例

  1. local function urlencode(w)
  2. pattern = "[^%w%d%?=&:/._%-%* ]"
  3. s = string.gsub(w, pattern, function(c)
  4. local c = string.format("%%%02X", string.byte(c))
  5. return c
  6. end)
  7. s = string.gsub(s, " ", "+")
  8. return s
  9. end
  10. -- 异步httpget请求
  11. task.execAsync({
  12. -- 指定httpget类型
  13. type = "httpget",
  14. -- 注意请求的URL需要进行url编码
  15. url = urlencode("http://httpbin.org/get?x=测试x&y=测试y"),
  16. callback = function (result)
  17. -- 回调结果为table
  18. assert(type(result) == "table")
  19. -- 注意: 虽然请求会异步执行, 但回调函数依然在lua主线程执行, 不要在回调里执行其他阻塞操作
  20. printf("async task httpget callback: code = %d, data len = %d", result.code, #result.data)
  21. end
  22. })
  23. -- 异步httppost请求
  24. task.execAsync({
  25. type = "httppost",
  26. url = "http:/httpbin.org/post",
  27. -- 自定义请求头, 注意按照'<key>:<value>#<key>:<value>#...'的格式
  28. headers = "User-Agent:Test-Agent#Accept-Language:zh-CN",
  29. -- post请求的数据
  30. content = "test content 2",
  31. callback = function (result)
  32. -- httpgethttppost返回数据格式一致
  33. assert(type(result) == "table")
  34. printf("async task httppost callback: code = %d, data len = %d", result.code, #result.data)
  35. end
  36. })
  37. local t = 0
  38. while t < 10 do
  39. sleep(1000)
  40. t = t + 1
  41. end

系统/运行时模块 —— runtime

◆ 函数 runtime.vibrate : 模拟设备震动

函数语法

void runtime.vibrate(integer durationMs)

函数说明

设备震动durationMs毫秒。


◆ 函数 runtime.readClipboard : 读取粘贴板

函数语法

string runtime.readClipboard(void)

函数说明

读取系统剪贴板内容并返回。

使用示例

  1. local code = runtime.readClipboard()
  2. printf('code = %s', code)

◆ 函数 runtime.writeClipboard : 写入粘贴板

函数语法

void runtime.readClipboard(string content)

函数说明

将content内容写入到系统剪贴板。

使用示例

  1. xmod.setOnEventCallback(xmod.EVENT_ON_RUNTIME_ERROR, function (errMsg)
  2. UI.toast('出错了!错误信息已复制至粘贴板,请联系作者反馈!')
  3. runtime.writeClipboard(errMsg)
  4. end)

◆ 函数 runtime.inputText : 模拟输入文本

函数语法

void runtime.inputText(string content)

函数说明

将content内容写入到当前输入框。

content中出现以下字符时,将按特殊处理:

特别说明

使用示例

  1. -- 点击输入框获取焦点(假设已知输入框坐标150, 150)
  2. touch.down(1, 150, 150)
  3. sleep(20)
  4. touch.up(1, 150, 150)
  5. sleep(1000)
  6. -- 输入内容
  7. runtime.inputText('that \r\n')
  8. sleep(1000)
  9. -- 清空输入框内容, 再输入新内容, 然后模拟切换下一个输入目标(如果有的话)
  10. runtime.inputText('#CLEAR#this is a good#DEL#se.#NEXT#\r\n')
  11. sleep(1000)
  12. -- 输入内容
  13. runtime.inputText('that is a duck?\r\n')
  14. sleep(1000)
  15. -- 删除上一个输入内容中的 '?\r\n' 字符, 再重新输入 '.\r\n'
  16. runtime.inputText('#DEL##DEL##DEL#.\r\n')
  17. sleep(1000)
  18. -- 其他输入
  19. runtime.inputText('and finally we have a #WOLF#.\r\nwith an enclosing #!\r\n')
  20. sleep(2000)

◆ 函数 runtime.launchApp : 启动应用

函数语法

boolean runtime.launchApp(string appID)

函数说明

启动设备中包名为appID的应用程序,启动成功返回true,否则返回false。

注:该函数不支持在iOS的IPA精灵产品中使用。


◆ 函数 runtime.killApp : 关闭应用

函数语法

void runtime.killApp(string appID)

函数说明

关闭设备中包名为appID的应用程序。

注:该函数不支持在iOS的IPA精灵产品中使用。


◆ 函数 runtime.isAppRunning : 判断应用是否运行

函数语法

boolean runtime.isAppRunning(string appID)

函数说明

检测设备中包名为appID的应用程序是否正在运行。

注:该函数不支持在iOS的IPA精灵产品中使用。


◆ 函数 runtime.getForegroundApp : 获取前台应用包名

函数语法

string runtime.getForegroundApp(void)

函数说明

获取当前前台应用程序的包名。

注:该函数不支持在iOS的IPA精灵产品中使用。


Android子模块runtime.android

◆ 函数 runtime.android.getSystemProperty : 获取Android系统属性

函数语法

void runtime.android.getSystemProperty(string key)

函数说明

<仅Android>获取系统常量属性key对应值。

使用示例

  1. if xmod.PLATFORM == xmod.PLATFORM_ANDROID then
  2. printf('CPU构架: %s', runtime.android.getSystemProperty('ro.arch'))
  3. printf('手机产品号: %s', runtime.android.getSystemProperty('ro.build.product'))
  4. end

UI展示模块 —— UI

UIContext

◆ 函数 UIContext:show : 显示UI界面

函数语法

void UIContext:show(void)

函数说明

创建并展示UI到屏幕。

注意UI:show为非阻塞调用,调用后会立即返回。

使用示例

  1. local showing = true
  2. local context = UI.createContext('testUI.json')
  3. context:getRootView():setActionCallback(UI.ACTION.CLICK, function()
  4. -- 注册root view被点击时关闭UI显示
  5. context:close()
  6. showing = false
  7. end)
  8. -- 调用后立即创建显示UI并返回
  9. context:show()
  10. -- 循环直到root view被点击出发关闭
  11. while showing do
  12. sleep(1000)
  13. end

◆ 函数 UIContext:close : 关闭UI界面

函数语法

void UIContext:close(void)

函数说明

主动关闭UI界面。


◆ 函数 UIContext:getRootView : 获取根组件

函数语法

UIView UIContext:getRootView(void)

函数说明

获取构建的UIContext中的根UIView实例。


◆ 函数 UIContext:findView : 搜索组件

函数语法

UIView UIContext:findView(string tid)

函数说明

搜索并返回UIContext显示架构中ID为tid的UIView实例。

特别说明

UI中根节点的ID是无法自定义或无法修改的,有固定值'_root'。因此不要对根节点设置ID然后通过UIContext:findView获取,而是直接使用UIContext:rootView函数。


◆ 函数 UIContext:createView : 动态创建组件

函数语法

UIView UIContext:createView(any layout)

函数说明

从当前UIContext示例中动态创建UIView示例,layout结构共享UI.createContext时传入的style属性。

其中layout可以是以下类型参数:

使用示例

  1. local rootLayout = {
  2. view = 'scroller',
  3. style = {
  4. width = 750,
  5. ['background-color'] = '#ff0',
  6. ['align-items'] = 'center'
  7. },
  8. subviews = {
  9. {
  10. id = 'test_btn',
  11. view = 'div',
  12. class = 'btn',
  13. subviews = {
  14. {
  15. view = 'text',
  16. class = 'txt',
  17. value = 'ok'
  18. }
  19. }
  20. }
  21. }
  22. }
  23. local globalStyle = {
  24. txt = {
  25. color = '#41b883',
  26. ['font-size'] = 40,
  27. ['padding-top'] = 10,
  28. ['padding-bottom'] = 10
  29. },
  30. logo = {
  31. width = 200,
  32. height = 30,
  33. padding = 10,
  34. margin = 20
  35. },
  36. btn = {
  37. width = 710,
  38. height = 80,
  39. ['align-items'] = 'center',
  40. ['border-width'] = 1.5,
  41. ['border-radius'] = 24,
  42. ['border-color'] = '#dddddd',
  43. ['background-image'] = 'linear-gradient(to top, #E3F5FB, #F9FEFF)'
  44. },
  45. ['btn:active'] = {
  46. ['background-image'] = 'linear-gradient(to top, #DFDFDF, #AFAFAF)'
  47. }
  48. }
  49. -- 根据json or table创建context
  50. local showing = true
  51. local context = UI.createContext(rootLayout, globalStyle)
  52. local okbtn = context:findView('test_btn')
  53. okbtn:setActionCallback(UI.ACTION.CLICK, function(id, action)
  54. -- 主动关闭展示
  55. context:close()
  56. showing = false
  57. end)
  58. context:show()
  59. local count = 1
  60. while showing do
  61. sleep(1000)
  62. count = count + 1
  63. if count == 3 then
  64. local logoLayout = {
  65. view = 'image',
  66. class = 'logo', -- 动态创建的image使用到了globalStyle中的'logo'
  67. src = 'http://www.xxzhushou.cn/statics/images/xxcms5/logo.png',
  68. style = {
  69. width = 280,
  70. height = 76
  71. }
  72. }
  73. local logoView = context:createView(logoLayout)
  74. -- 将创建的logoView添加到root view
  75. context:getRootView():addSubview(logoView)
  76. end
  77. end

UIView

◆ 函数 UIView:getID : 获取组件标识

函数语法

string UIView:getID(void)

函数说明

返回当前UIView实例的ID。

特别说明

UI中根节点的ID是无法自定义或无法修改的,有固定值'_root'。


◆ 函数 UIView:getType : 获取组件类型

函数语法

integer UIView:getType(void)

函数说明

返回当前UIView实例的类型,可能是以下取值之一:

关于不同UIView类型属性和作用,请参阅附录F. UI内置基础组件库


◆ 函数 UIView:getAttr : 获取组件属性

函数语法

函数说明

返回当前UIView实例的属性对中键值为key的属性,返回类型可能是booleannumberstring之一。

要了解详细的属性设置列表,请参阅附录F. UI内置基础组件库中各组件的特有属性。


◆ 函数 UIView:getAttrs : 获取组件所有属性

函数语法

table UIView:getAttrs(void)

函数说明

返回当前UIView实例的所有属性对。

要了解详细的属性设置列表,请参阅附录F. UI内置基础组件库中各组件的特有属性。


◆ 函数 UIView:getStyle : 获取组件样式

函数语法

函数说明

返回当前UIView实例样式表中键值为key的样式,返回类型可能是booleannumberstring之一。

要了解详细的样式设置列表,请参阅附录E. UI模块设计和样式


◆ 函数 UIView:getStyles : 获取组件所有样式

函数语法

table UIView:getStyles(void)

函数说明

返回当前UIView实例的所有样式表。

要了解详细的样式设置列表,请参阅附录E. UI模块设计和样式


◆ 函数 UIView:setAttr : 设置组件属性

函数语法

函数说明

设置当前UIView实例的key-value属性对,也可以设置attrs多组属性对。

要了解详细的属性设置列表,请参阅附录F. UI内置基础组件库中各组件的特有属性。

使用示例

  1. local context = UI.createContext('testUI.json')
  2. local root = context:getRootView()
  3. -- key-value形式
  4. root:setAttr('checked', false)
  5. -- table形式
  6. root:setAttr({
  7. checked = false,
  8. visibility = false
  9. })

◆ 函数 UIView:setStyle : 设置组件样式

函数语法

函数说明

设置当前UIView实例的key-value样式对,也可以设置styles多组样式对。

要了解详细的样式设置列表,请参阅附录E. UI模块设计和样式

使用示例

  1. local context = UI.createContext('testUI.json')
  2. local root = context:getRootView()
  3. -- key-value形式
  4. root:setStyle('color', 'red')
  5. -- key-value形式的Pseudo伪类样式
  6. root:setStyle('color:active', 'blue')
  7. -- table形式
  8. root:setStyle({
  9. color = '#ff0',
  10. ['background-color'] = 'blue'
  11. })

◆ 函数 UIView:subviewsCount : 获取组件的子组件数量

函数语法

integer UIView:subviewsCount(void)

函数说明

返回当前UIView实例的子组件数量。


◆ 函数 UIView:getSubview : 获取子组件

函数语法

UIView UIView:getSubview(integer index)

函数说明

返回当前UIView实例下第index个子组件(注意index从1开始计数)。

使用示例

  1. local context = UI.createContext('testUI.json')
  2. local root = context:getRootView()
  3. for i = 1, root:subviewsCount() do
  4. local subview = root:getSubview(i)
  5. -- 将所有文本颜色改成红色
  6. if view:getType() == UI.TYPE.TEXT then
  7. view:setStyle('color', 'red')
  8. end
  9. end

◆ 函数 UIView:addSubview : 添加子组件

函数语法

函数说明

将subview添加到当前UIView子组件列表的第index处(注意index从1开始计数,默认添加到末尾)。

使用示例

  1. local context = UI.createContext('testUI.json')
  2. local root = context:getRootView()
  3. local logoLayout = {
  4. view = 'image',
  5. src = 'http://www.xxzhushou.cn/statics/images/xxcms5/logo.png',
  6. style = {
  7. width = 280,
  8. height = 76
  9. }
  10. }
  11. local logoView = context:createView(logoLayout)
  12. -- 添加图片到root view末尾
  13. root:addSubview(logoView)

◆ 函数 UIView:removeSubview : 移除子组件

函数语法

void UIView:removeSubview(integer index)

函数说明

将当前UIView子组件列表的第index处子组件移除(注意index从1开始计数)。

使用示例

  1. local context = UI.createContext('testUI.json')
  2. local root = context:getRootView()
  3. -- 移除第一项子组件
  4. root:removeSubview(1)

◆ 函数 UIView:removeFromParent : 将当前组件从父组件移除

函数语法

void UIView:removeFromParent(void)

函数说明

将当前UIView从父组件中移除。

使用示例

  1. local context = UI.createContext('testUI.json')
  2. local root = context:getRootView()
  3. for i = 1, root:subviewsCount() do
  4. local subview = root:getSubview(i)
  5. if subview:getID() == 'test_btn' then
  6. subview:removeFromParent()
  7. break
  8. end
  9. end

◆ 函数 UIView:setActionCallback : 设置组件的回调函数

函数语法

void UIView:setActionCallback(integer action, function callback)

函数说明

监听指定action事件,当事件发生时触发callback回调函数,当callback为nil时取消对应action事件监听。

要了解详细的回调事件,请参阅附录E. UI模块设计和样式中关于伪类和事件响应的介绍。

特别说明

对UIView的回调监听设置,必须在UIContext:show之前设置,否则无效。


◆ 函数 UIView:toJson : 将组件导出为Json格式字符串

函数语法

string UIView:toJson(void)

函数说明

将组件的当前设置导出为Json格式字符串。

使用示例

  1. -- 加载testUI.json
  2. local context = UI.createContext('testUI.json')
  3. -- 修改根节点的背景颜色
  4. local root = context:getRootView()
  5. root:setStyle('background-color', 0xffffff)
  6. -- 导出当前的根节点配置,写入到公共目录的rootView.json文件中
  7. local jsonStr = root:toJson()
  8. local f = io.open('[public]rootView.json', 'w')
  9. f:write(jsonStr)
  10. f:close()

◆ 常量 UI.TYPE.UNKNOWN

常量值: integer-1


◆ 常量 UI.TYPE.CONTAINER

常量值: integer0


◆ 常量 UI.TYPE.DIV

常量值: integer1


◆ 常量 UI.TYPE.TEXT

常量值: integer2


◆ 常量 UI.TYPE.IMAGE

常量值: integer3


◆ 常量 UI.TYPE.SCROLLER

常量值: integer4


◆ 常量 UI.TYPE.LIST

常量值: integer5


◆ 常量 UI.TYPE.SWITCH

常量值: integer10


◆ 常量 UI.TYPE.INPUT

常量值: integer11


◆ 常量 UI.TYPE.TEXTAREA

常量值: integer12


◆ 常量 UI.TYPE.VIDEO

常量值: integer13


◆ 常量 UI.TYPE.INDICATOR

常量值: integer14


◆ 常量 UI.TYPE.WEB

常量值: integer17


◆ 常量 UI.TYPE.LOADING

常量值: integer18


◆ 常量 UI.ACTION.APPEAR

常量值: integer0


◆ 常量 UI.ACTION.DISAPPER

常量值: integer1


◆ 常量 UI.ACTION.CLICK

常量值: integer2


◆ 常量 UI.ACTION.LONG_PRESS

常量值: integer3


◆ 常量 UI.ACTION.SWIPE

常量值: integer4


◆ 常量 UI.PSEUDO.ACTIVE

常量值: string'active'


◆ 常量 UI.PSEUDO.FOCUS

常量值: string'focus'


◆ 常量 UI.PSEUDO.ENABLED

常量值: string'enabled'


◆ 常量 UI.PSEUDO.DISABLED

常量值: string'disabled'


◆ 常量 UI.TOAST.LENGTH_SHORT

常量值: integer0


◆ 常量 UI.TOAST.LENGTH_LONG

常量值: integer1


◆ 函数 UI.toast : Toast提示

函数语法

函数说明

以HUD方式显示提示信息,length可选参数:


◆ 函数 UI.createContext : 构建UI实例

函数语法

函数说明

根据layout和style,创建UIContext实例。

其中layout和style可以是以下类型参数:

使用示例

  1. -- table格式
  2. local rootLayout = {
  3. view = 'scroller',
  4. style = {
  5. width = 750,
  6. ['background-color'] = '#ff0',
  7. ['align-items'] = 'center'
  8. },
  9. subviews = {
  10. {
  11. view = 'text',
  12. class = 'txt',
  13. value = 'text文字'
  14. }, {
  15. id = 'test_input',
  16. view = 'input',
  17. value = 'input输入框',
  18. style = {
  19. width = 710,
  20. height = 70,
  21. ['background-color'] = '#AFAFAF'
  22. }
  23. }
  24. }
  25. }
  26. -- json字符串格式
  27. local globalStyle = [[
  28. {
  29. txt = {
  30. color = '#41b883',
  31. ['font-size'] = 40,
  32. ['padding-top'] = 10,
  33. ['padding-bottom'] = 10
  34. }
  35. }
  36. ]]
  37. -- 根据json or table创建context
  38. local context = UI.createContext(rootLayout, globalStyle)
  39. -- 也可以根据xsp文件中ui/目录下的layout.jsonstyle.json创建
  40. -- local context = UI.createContext('layout.json', 'style.json')
  41. context:show()

◆ 函数 UI.register : 设置UI模板

函数语法

void UI.register(string name, any layout)

函数说明

注册命名为name,对应组件结构为layout的新组件,用于UI组件的扩展和复用。

其中layout可以是以下类型参数:

使用示例

以下示例仅为展示API使用效果,其中使用到的UIView属性和样式请参阅附录E. UI模块设计和样式做进一步了解。

  1. -- 支持UI的扩展、复用, 这里注册新组件mycell
  2. UI.register('mycell', {
  3. view = 'div',
  4. style = {
  5. ['flex-direction'] = 'row',
  6. ['align-items'] = 'center',
  7. ['padding-left'] = 24,
  8. ['padding-right'] = 24,
  9. ['background-color'] = '#fff'
  10. },
  11. subviews = {
  12. {
  13. -- 扩展元素只能是slot类型
  14. view = 'slot',
  15. name = 'title'
  16. },
  17. {
  18. view = 'slot',
  19. name = 'value'
  20. }
  21. }
  22. })
  23. local rootLayout = {
  24. view = 'scroller',
  25. style = {
  26. width = 750,
  27. ['background-color'] = '#ff0',
  28. ['align-items'] = 'center'
  29. },
  30. subviews = {
  31. {
  32. -- 自己扩展的UI: checkbox
  33. id = 'test_checkbox',
  34. view = 'mycell',
  35. checked = false,
  36. -- 填充slot
  37. slots = {
  38. {
  39. -- slot title
  40. view = 'text',
  41. name = 'title',
  42. value = '显示input'
  43. },
  44. {
  45. -- slot value
  46. view = 'image',
  47. name = 'value',
  48. style = {
  49. width = 40,
  50. height = 40
  51. },
  52. src = 'https://gw.alicdn.com/tfs/TB14fp2pwMPMeJjy1XbXXcwxVXa-72-72.png'
  53. }
  54. }
  55. }
  56. }
  57. }
  58. local context = UI.createContext(rootLayout)
  59. context:show()

内置C扩展模块

注意引擎所有内置C扩展模块均需要主动require后方可使用。

文件系统操作模块 —— lfs

API参考:https://keplerproject.github.io/luafilesystem/manual.html

正则表达匹配模块 —— lpeg

API参考:http://www.inf.puc-rio.br/~roberto/lpeg/#func

JSON模块 —— cjson

API参考:https://www.kyne.com.au/~mark/software/lua-cjson-manual.html

Socket模块 —— socket

API参考:http://w3.impa.br/~diego/software/luasocket/reference.html

OpenSSL/Https模块 —— ssl

API参考:https://github.com/brunoos/luasec/wiki

大漠文字识别模块 —— dmocr

◆ 函数 dmocr.create : 创建大漠OCR

函数语法

函数说明

根据dict或dictPath(需要放在res/目录下)指定的字库信息,创建大漠识别实例并返回。

注意字库用文件形式存放时需要使用UTF8编码。


◆ 函数 dmocr:getText : 大漠OCR识别

函数语法

函数说明

对rect范围内图像和偏色diffs(偏色说明请参考附录D. 偏色和二值化说明)进行二值化处理,根据模糊度fuzz(范围0-100)和搜索方向dir,识别文字并返回。返回数据根据detail参数有不同返回类型。

特别说明

该函数结果受以下函数影响:

注意该函数不受 screen.setMockTransform影响。

使用示例

  1. local dict = {
  2. 'FFFFFC000000000000000000000001FFF$u$0.0.56$15',
  3. 'FFFFFC$l$0.0.42$21',
  4. '10EE1B06608811062084108218C1FF8FF$a$0.1.77$15',
  5. 'FFFFFC03008030040080100200600F00F$h$0.0.71$21',
  6. '0040080100200400801002FFFFFC010020040080100200400800400$王$4.2.83$21',
  7. '1FE200400801002007F8000000000080601804030300E002002001001001001001$哈$0.1.118$26'
  8. }
  9. local dmocr = require('dmocr')
  10. local ocr = dmocr.create(dict)
  11. -- 或者可以加载res/dict.txt字库文件: local ocr = dmocr.create("dict.txt")
  12. -- 表示范围内全部搜索, 以字符串形式返回识别结果
  13. local result = ocr:getText(Rect(0, 0, 1135, 639), { "0x613d3b-0x202020", "0x797979-0x202020" }, 95, false, 0)
  14. printf('result: %s', result)
  15. -- 表示范围内横向搜索, table形式返回识别到的所有结果及其坐标
  16. local result2 = ocr:getText(Rect(0, 0, 1135, 639), { "0x613d3b-0x202020" }, 95, true, 1)
  17. for k, v in pairs(result2) do
  18. printf('{ char = "%s", pos = %s }', v.char, v.pos)
  19. end

Tesseract文字识别模块 —— tessocr

引擎内置支持Tesseract 3.02.02和3.05.02两个版本,使用时请注意区分加载,且不同版本字库并不通用。

◆ 函数 tessocr.create : 创建Tesseract OCR

函数语法

函数说明

载入Tesseract字库,并指定检测方式,创建成功返回tessocr实例和版本号,创建失败返回nil和错误信息。

config可以配置以下选项:

config为nil时,默认加载lang = 'eng'内置字库文件。

使用示例

  1. -- 可以选择3.02.023.05.02版本, 指定加载'tessocr_<version>'库即可
  2. local tessocr = require('tessocr_3.05.02')
  3. -- 加载默认eng字库(引擎内置)
  4. local ocr1, msg = tessocr.create()
  5. if ocr1 == nil then
  6. UI.toast('tessocr No.1 create failed: ' .. msg)
  7. end
  8. -- 加载xsp文件中res/目录下的myengmynum字库
  9. local ocr2, msg = tessocr.create({
  10. path = 'res/',
  11. lang = 'myeng+mynum'
  12. })
  13. if ocr2 == nil then
  14. UI.toast('tessocr No.2 create failed: ' .. msg)
  15. end
  16. -- 加载叉叉助手中提供的字库扩展(注意区分3.02.023.05.02版本)
  17. local ocr3, msg = tessocr.create({
  18. path = '[external]',
  19. lang = 'eng_ext'
  20. })
  21. if ocr3 == nil then
  22. UI.toast('tessocr No.3 create failed: ' .. msg)
  23. end
  24. -- 加载自定义路径的任意字库(注意字库文件上层路径必须命名为'tessdata'
  25. local ocr4, msg = tessocr.create({
  26. path = '/sdcard/tessdata',
  27. lang = 'mynum'
  28. })
  29. if ocr4 == nil then
  30. UI.toast('tessocr No.4 create failed: ' .. msg)
  31. end

◆ 函数 tessocr:setPSM : Tesseract设置PSM模式

函数语法

void tessocr:setPSM(integer psm)

函数说明

设置Tesseract的Page Segmentation Mode,可选值如下:


◆ 函数 tessocr:setWhitelist : Tesseract设置白名单

函数语法

void tessocr:setWhitelist(string list)

函数说明

设置Tesseract识别白名单,设置后仅识别白名单中出现的字库。


◆ 函数 tessocr:setBlacklist : Tesseract设置黑名单

函数语法

void tessocr:setBlacklist(string list)

函数说明

设置Tesseract识别黑名单,设置后不会识别出黑名单中的字库。


◆ 函数 tessocr:getText : Tesseract OCR识别

函数语法

函数说明

函数返回integer类型的code错误码、string类型的content识别字符串和table类型的details详细结果。

特别说明

该函数结果受以下函数影响:

使用示例

  1. local tessocr = require('tessocr_3.05.02')
  2. -- 加载xsp文件中res/目录下的num字库
  3. local ocr, msg = tessocr.create({
  4. path = 'res/',
  5. lang = 'num'
  6. })
  7. if ocr ~= nil then
  8. local code, result
  9. -- 设定PSM模式为单个字符模式
  10. ocr:setPSM(10)
  11. -- 设置白名单
  12. ocr:setWhitelist('0123456789')
  13. code, result = ocr:getText({
  14. { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  15. { 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0 },
  16. { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  17. { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  18. { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  19. { 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  20. { 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  21. { 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0 },
  22. { 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0 },
  23. { 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0 },
  24. { 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0 },
  25. { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0 },
  26. { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0 },
  27. { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1 },
  28. { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0 },
  29. { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1 },
  30. { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1 },
  31. { 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0 },
  32. { 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 },
  33. { 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0 },
  34. { 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0 },
  35. { 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0 }
  36. })
  37. if code == 0 then
  38. -- 输出结果: 'text = "6"'
  39. printf('text = "%s"', result)
  40. else
  41. printf('ocr:getText failed!')
  42. end
  43. -- 重置成默认PSM模式
  44. ocr:setPSM(6)
  45. -- 清空白名单设置
  46. ocr:setWhitelist('')
  47. code, result = ocr:getText(Rect(100, 100, 200, 200), { "0x613d3b-0x202020", "0x797979-0x202020" })
  48. if code == 0 then
  49. printf('text = "%s"', result)
  50. else
  51. printf('ocr:getText failed!')
  52. end
  53. -- 获取详细结果
  54. code, result, detail = ocr:getText(Rect(100, 100, 200, 200), { "0x613d3b-0x202020", "0x797979-0x202020" })
  55. if code == 0 then
  56. printf('text = "%s"', result)
  57. for _, v in pairs(detail) do
  58. printf('{ text = "%s", rect = %s, confidence = %.2f }', v.char, v.rect, v.confidence)
  59. end
  60. else
  61. printf('ocr:getText failed!')
  62. end
  63. else
  64. printf('tessocr.create error: %s', msg)
  65. end

◆ 函数 tessocr:release : 释放Tesseract实例

函数语法

void tessocr:release(void)

函数说明

释放Tesseract字库识别对象,当加载字库文件较大时,建议主动控制使用。

使用示例

  1. local tessocr = require('tessocr_3.05.02')
  2. local ocr = tessocr.create({
  3. path = 'res/',
  4. lang = 'myeng+mynum'
  5. })
  6. -- 使用ocr进行识别
  7. ...
  8. -- 使用完毕, 主动释放内存
  9. ocr:release()

Http网络传输模块 —— chttp

◆ 函数 chttp.create : 构建chttp实例

函数语法

chttp chttp.create(void)

函数说明

创建chttp实例,用于后续API操作。


◆ 函数 chttp:close : 释放chttp实例

函数语法

void chttp:close(void)

函数说明

主动关闭chttp实例。


◆ 函数 chttp:setHeader : 设置http请求头字段

函数语法

void chttp:setHeader(table headers)

函数说明

自定义请求的头字段信息。

使用示例

  1. local request = require('chttp').create()
  2. request:setHeader({
  3. Accept = 'application/json',
  4. ['Content-Type'] = 'application/x-www-form-urlencoded'
  5. })

◆ 函数 chttp:setUrl : 设置http请求地址

函数语法

void chttp:setUrl(string url)

函数说明

设置请求的目标地址。

使用示例

  1. local request = require('chttp').create()
  2. request:setUrl('http://www.httpbin.org/get')
  3. print(request:get().text)

◆ 函数 chttp:setBody : 设置http请求内容

函数语法

void chttp:setBody(string body)

函数说明

设置请求的附带内容。

使用示例

  1. local request = require('chttp').create()
  2. request:setUrl('http://www.httpbin.org/post')
  3. request:setHeader({ ['Content-Type'] = 'text/plain' })
  4. request:setBody('This is raw POST data')
  5. print(request:post().text)

◆ 函数 chttp:setAuth : 设置http请求验证信息

函数语法

void chttp:setAuth(string username, string password)

函数说明

设置请求的用户验证账号和密码。

使用示例

  1. local request = require('chttp').create()
  2. request:setUrl('http://www.httpbin.org/basic-auth/user/pass')
  3. request:setAuch('user', 'pass')
  4. print(request:get().text)

◆ 函数 chttp:setCookies : 设置http请求的cookies

函数语法

void chttp:setCookies(table cookies)

函数说明

设置请求的cookies信息。

使用示例

  1. local request = require('chttp').create()
  2. request:setUrl('http://www.httpbin.org/get')
  3. request:setCookies({
  4. hello = 'world',
  5. ['ice cream'] = 'is delicious'
  6. })
  7. print(request:get().text)

◆ 函数 chttp:post : 发送http POST请求

函数语法

table chttp:post(void)

函数说明

执行Post请求,返回执行结果。

返回的table数据中,包含以下参数:

使用示例

  1. local request = require('chttp').create()
  2. request:setUrl('http://www.httpbin.org/post')
  3. request:setPayload({
  4. key = 'value'
  5. })
  6. local ret = request:post()
  7. printf('status code = %d', ret.status)
  8. printf('return text = %s', ret.text)

◆ 函数 chttp:get : 发送http GET请求

函数语法

table chttp:get(void)

函数说明

执行Get请求,返回执行结果。

返回结果类型与chttp:get()结果一致。


◆ 函数 chttp:delete : 发送http DELETE请求

函数语法

table chttp:delete(void)

函数说明

执行Delete请求,返回执行结果。

返回结果类型与chttp:get()结果一致。


◆ 函数 chttp:head : 发送http HEAD请求

函数语法

table chttp:head(void)

函数说明

执行Head请求,返回执行结果。

返回结果类型与chttp:get()结果一致。


◆ 函数 chttp:patch : 发送http PATCH请求

函数语法

table chttp:patch(void)

函数说明

执行Patch请求,返回执行结果。

返回结果类型与chttp:get()结果一致。


◆ 函数 chttp:put : 发送http PUT请求

函数语法

table chttp:put(void)

函数说明

执行Put请求,返回执行结果。

返回结果类型与chttp:get()结果一致。


◆ 函数 chttp:options : 发送http OPTIONS请求

函数语法

table chttp:options(void)

函数说明

执行Options请求,返回执行结果。

返回结果类型与chttp:get()结果一致。


◆ 函数 chttp:setTimeout : 设置http请求超时

函数语法

void chttp:setTimeout(integer timeout)

函数说明

设置请求超时时间(单位毫秒)。

使用示例

  1. local request = require('chttp').create()
  2. request:setUrl('http://www.httpbin.org/get')
  3. request:setTimeout(3000)
  4. print(request:get().text)

◆ 函数 chttp:setParam : 设置http请求参数

函数语法

void chttp:setParam(table params)

函数说明

设置请求的参数内容。

使用示例

  1. local request = require('chttp').create()
  2. request:setUrl('http://www.httpbin.org/get')
  3. request:setParam({ key = 'value' })
  4. print(request:get().text)

◆ 函数 chttp:setPayload : 设置http请求内容

函数语法

void chttp:setPayload(void)

函数说明

设置请求的附带内容。

功能与chttp:setBody类似,区别在于设置的是key-value形式数据。

使用示例

  1. local request = require('chttp').create()
  2. request:setUrl('http://www.httpbin.org/put')
  3. request:setPayload({ key = 'value' })
  4. print(request:put().text)

◆ 函数 chttp:setLowSpeed : 设置http请求最低速度和持续时间

函数语法

void chttp:setLowSpeed(integer limit, integer time)

函数说明

设置最低下载速度和持续时间。

如果在指定时间传输速率超过设置的最低值,则会自动断开该连接。

使用示例

  1. local request = require('chttp').create()
  2. request:setUrl('http://www.httpbin.org/get')
  3. request:setParam({ key = 'value' })
  4. request:setLowSpeed(1, 1)
  5. print(request:get().text)

通用加解密/哈希算法模块 —— crypto

◆ 函数 crypto.md5 : MD5摘要算法

函数语法

string crypto.md5(string msg)

函数说明

对msg内容进行MD5算法处理,返回32位摘要。


◆ 函数 crypto.sha1 : SHA-1摘要算法

函数语法

string crypto.sha1(string msg)

函数说明

对msg内容进行sha-1算法处理,返回40位摘要。


◆ 函数 crypto.base64Encode : base64编码

函数语法

string crypto.base64Encode(string msg)

函数说明

对msg内容进行base64算法编码,可以将二进制数据转换成可视字符表示。


◆ 函数 crypto.base64Decode : base64解码

函数语法

string crypto.base64Encode(string msg)

函数说明

对msg内容进行base64算法解码,可以将base64编码的数据转换成二进制数据。


◆ 函数 crypto.hash : 32位哈希算法

函数语法

integer crypto.hash(integer key, string msg)

函数说明

根据32位整型key,对msg内容进行hash算法处理,返回32位整型摘要。


◆ 函数 crypto.hash64 : 64位哈希算法

函数语法

integer crypto.hash64(integer key, string msg)

函数说明

根据64位整型key,对msg内容进行hash64算法处理,返回64位整型摘要。


◆ 函数 crypto.rc4Encrypt : RC4加密

函数语法

string crypto.rc4Encrypt(string key, string msg)

函数说明

根据密钥key,对msg内容进行rc4算法加密,返回加密后数据。


◆ 函数 crypto.rc4Decrypt : RC4解密

函数语法

string crypto.rc4Decrypt(string key, string msg)

函数说明

根据密钥key,对msg内容进行rc4算法解密,返回解密后数据。


◆ 函数 crypto.xxteaEncrypt : XXTEA加密

函数语法

string crypto.xxteaEncrypt(string key, string msg)

函数说明

根据密钥key,对msg内容进行XXTEA算法加密,返回加密后数据。


◆ 函数 crypto.xxteaDecrypt : XXTEA解密

函数语法

string crypto.xxteaDecrypt(string key, string msg)

函数说明

根据密钥key,对msg内容进行XXTEA算法解密,返回解密后数据。


官方扩展UI库 —— wui

引擎内置的类web组件类型看似不多,但其实其他UI组件类型如checkbox、radio可通过扩展实现,WUI正是基于引擎UI框架扩展的一套UI库,额外提供了chekcbox、checkboxList、radio、tabBar、tabPage、gridSelect等常用的组件类型。

另外,WUI项目库是完全开源的,欢迎开发者随时扩充和实现自己的UI组件。使用叉叉集成开发环境(简称IDE)新建项目时,会自动导入WUI组件库源码。

你也可以在这里下载最新的WUI源码:GitHub:@xxzhushou/WUI

导入WUI库后,每一种组件均有静态和动态两种创建方式供开发者使用:

静态方式是通过组件的createLayout函数构建对应UI组件的table结构,然后添加到其他组件的subviews中展示。

  1. -- require路径根据实际修改
  2. local wui = require('wui.wui')
  3. -- createLayout本质上只是构建了UI组件的table描述
  4. local layout1 = wui.Checkbox.createLayout({ title = '选项1', value = 1, hasTopBorder = true, hasBottomBorder = false })
  5. local layout2 = wui.Checkbox.createLayout({ title = '选项2', value = 2, checked = true, config = { checkedColor = '#f00', uncheckedColor = '#0f0' } })
  6. local rootLayout = {
  7. view = 'scroller',
  8. subviews = {
  9. layout1,
  10. layout2
  11. }
  12. }
  13. local context = UI.createContext(rootLayout)
  14. context:show()
  15. while true do
  16. sleep(1000)
  17. end

动态方式是指调用组件的createView函数创建对应的UIView实例进行操作,通过UIView:addSubview函数添加到其他UIView实例中。

  1. local context = UI.createContext(rootLayout)
  2. local root = context:getRootView()
  3. -- 传递参数跟createLayout一样, 但是返回的是UIView实例
  4. local checkbox = wui.Checkbox.createView(context, { title = '选项', value = 3, checked = true, disabled = true })
  5. -- 添加到根组件末尾
  6. root:addSubview(checkbox)

wui.Button组件

◆ 函数 wui.Button.createLayout : 静态构建Button组件

函数语法

table wui.Button.createLayout(table layout)

函数说明

静态构建Button组件。

layout: table类型,有以下设置参数:


◆ 函数 wui.Button.createView : 动态构建Button组件

函数语法

UIView wui.Button.createView(UIContext context, table layout)

函数说明

动态构建Button组件。


◆ 函数 wui.Button.setOnClickedCallback : 设置Button组件的回调函数

函数语法

void wui.Button.setOnClickedCallback(UIView button, function callback)

函数说明

注册button组件点击事件回调处理函数。

使用示例

  1. local btn = wui.Button.createView(context, { id = 'btn_1', size = 'medium' })
  2. context:getRootView():addSubview(btn)
  3. wui.Button.setOnClickedCallback(context:findView('btn_1'), function (id, action)
  4. print("button setOnClickedCallback "' .. id .. '" clicked")
  5. end)

wui.Radio组件

◆ 函数 wui.Radio.createLayout : 静态构建Radio组件

函数语法

table wui.Radio.createLayout(table layout)

函数说明

静态构建Radio组件。

layout: table类型,有以下设置参数:


◆ 函数 wui.Radio.createView : 动态构建Radio组件

函数语法

UIView wui.Radio.createView(UIContext context, table layout)

函数说明

动态构建Radio组件。


◆ 函数 wui.Radio.setOnCheckedCallback : 设置Radio组件的回调函数

函数语法

void wui.Radio.setOnCheckedCallback(UIView radio, function callback)

函数说明

注册Radio组件点击事件回调处理函数。

使用示例

  1. local radioList = {
  2. { title = '选项1', value = 1 },
  3. { title = '选项2', value = 2, checked = true },
  4. { title = '选项3', value = 3 },
  5. { title =' 选项4', value = 4 },
  6. { title = '未选不可修改', value = 5, disabled = true },
  7. { title = '已选不可修改', value = 6, disabled = true, checked = true }
  8. }
  9. local radio = wui.Radio.createView(context, { list = radioList })
  10. wui.Radio.setOnCheckedCallback(radio, function(id, title, value, index, lastIndex)
  11. print("radio id: " .. id)
  12. print("radio item title: " .. title)
  13. print("radio item value: " .. tostring(value))
  14. print("current radio item index: " .. tostring(index))
  15. print("last radio item index: " .. tostring(lastIndex))
  16. end)
  17. context:getRootView():addSubview(radio)

wui.Checkbox组件

◆ 函数 wui.Checkbox.createLayout : 静态构建Checkbox组件

函数语法

table wui.Checkbox.createLayout(table layout)

函数说明

静态构建Checkbox组件。

layout: table类型,有以下设置参数:


◆ 函数 wui.Checkbox.createView : 动态构建Checkbox组件

函数语法

UIView wui.Checkbox.createView(UIContext context, table layout)

函数说明

动态构建Checkbox组件。


◆ 函数 wui.Checkbox.setOnCheckedCallback : 设置Checkbox组件的回调函数

函数语法

void wui.Checkbox.setOnCheckedCallback(UIView checkbox, function callback)

函数说明

注册Checkbox组件点击事件回调处理函数。

使用示例

  1. local layout = {
  2. title = '已选且禁用',
  3. value = 100,
  4. checked = true,
  5. disabled = true
  6. }
  7. local checkbox = wui.Checkbox.createView(context, layout)
  8. local function onChecked(id, title, value, checked)
  9. print("checkbox item id: " .. id)
  10. print("checkbox item title: " .. title)
  11. print("checkbox item value: " .. tostring(value))
  12. print("checkbox item checked: " .. tostring(checked))
  13. end
  14. wui.Checkbox.setOnCheckedCallback(checkbox, onChecked)
  15. context:getRootView():addSubview(checkbox)

wui.CheckboxList组件

◆ 函数 wui.CheckboxList.createLayout : 静态构建CheckboxList组件

函数语法

table wui.CheckboxList.createLayout(table layout)

函数说明

静态构建CheckboxList组件。

layout: table类型,有以下设置参数:


◆ 函数 wui.CheckboxList.createView : 动态构建CheckboxList组件

函数语法

UIView wui.CheckboxList.createView(UIContext context, table layout)

函数说明

动态构建CheckboxList组件。


◆ 函数 wui.CheckboxList.setOnCheckedCallback : 设置CheckboxList组件的回调函数

函数语法

void wui.CheckboxList.setOnCheckedCallback(UIView checkboxList, function callback)

函数说明

注册CheckboxList组件点击事件回调处理函数。

使用示例

  1. local list = {
  2. { title = '选项1', value = 1 },
  3. { title = '选项2', value = 2, checked = true , disabled = true },
  4. { title = '选项3', value = { 3, '333' } },
  5. { title = '选项4', value = '选项4', hasBottomBorder = false }
  6. }
  7. local checkboxList = wui.CheckboxList.createView(context, { list = list })
  8. wui.CheckboxList.setOnCheckedCallback(checkboxList, function(id, checkedList)
  9. print("checkboxList id: " .. id)
  10. for i, v in ipairs(checkedList) do
  11. printf("> checked item: index = %d, value = %s", v.index, tostring(v.value))
  12. end
  13. end)
  14. context:getRootView():addSubview(checkboxList)

wui.TabBar组件

◆ 函数 wui.TabBar.createLayout : 静态构建TabBar组件

函数语法

table wui.TabBar.createLayout(table layout)

函数说明

静态构建TabBar组件。

layout: table类型,有以下参数设置:


◆ 函数 wui.TabBar.createView : 动态构建TabBar组件

函数语法

UIView wui.TabBar.createView(UIContext context, table layout)

函数说明

动态构建TabBar组件。


◆ 函数 wui.TabBar.setOnSelectedCallback : 设置TabBar组件的回调函数

函数语法

void wui.TabBar.setOnSelectedCallback(UIView tabBar, function callback)

函数说明

注册tabBar组件点击事件回调处理函数。

使用示例

  1. local tabPages = {
  2. {
  3. view = 'div',
  4. style = {
  5. width = 480,
  6. ['background-color'] = '#00ff00'
  7. },
  8. subviews = {
  9. {
  10. view = 'text',
  11. value = '配置1',
  12. style = {
  13. ['font-size'] = 50,
  14. color = '#707070'
  15. }
  16. }
  17. }
  18. },
  19. {
  20. view = 'div',
  21. style = {
  22. width = 480,
  23. ['background-color'] = '#0000ff'
  24. },
  25. subviews = {
  26. {
  27. view = 'text',
  28. value = '配置2',
  29. style = {
  30. ['font-size'] = 50,
  31. color = '#707070'
  32. }
  33. }
  34. }
  35. }
  36. }
  37. local tabBarConfig = {}
  38. tabBarConfig.currentPage = 2
  39. tabBarConfig.pageWidth = 480
  40. tabBarConfig.pageHeight = 450
  41. tabBarConfig.tabTitles = {
  42. {
  43. title = '配置1',
  44. icon = 'https://gw.alicdn.com/tfs/TB1MWXdSpXXXXcmXXXXXXXXXXXX-72-72.png',
  45. activeIcon = 'https://gw.alicdn.com/tfs/TB1kCk2SXXXXXXFXFXXXXXXXXXX-72-72.png'
  46. }, {
  47. title = '配置2',
  48. icon = 'https://gw.alicdn.com/tfs/TB1Do3tSXXXXXXMaFXXXXXXXXXX-72-72.png',
  49. activeIcon = 'https://gw.alicdn.com/tfs/TB1LiNhSpXXXXaWXXXXXXXXXXXX-72-72.png',
  50. }
  51. }
  52. tabBarConfig.tabStyle = {
  53. titleColor = '#660077',
  54. activeTitleColor = '#66ff77',
  55. backgroundColor = '#660000',
  56. activeBackgroundColor = '#008800',
  57. isActiveTitleBold = true,
  58. tabWidth = 120,
  59. tabHeight = 90,
  60. iconWidth = 50,
  61. iconHeight = 50,
  62. fontSize = 20
  63. }
  64. local tabBar = wui.TabBar.createView(context, { pages = tabPages, config = tabBarConfig })
  65. wui.TabBar.setOnSelectedCallback(tabBar, function (id, currentPage)
  66. print('tabBar id: ' .. id)
  67. print('tabBar currentPage: ' .. tostring(currentPage))
  68. end)
  69. context:getRootView():addSubview(tabBar)

wui.TabPage组件

◆ 函数 wui.TabPage.createLayout : 静态构建TabPage组件

函数语法

table wui.TabPage.createLayout(table layout)

函数说明

静态构建TabPage组件。

layout: table类型,有以下参数设置:


◆ 函数 wui.TabPage.createView : 动态构建TabPage组件

函数语法

UIView wui.TabPage.createView(UIContext context, table layout)

函数说明

动态构建TabPage组件。


◆ 函数 wui.TabPage.setOnSelectedCallback : 设置TabPage组件的回调函数

函数语法

void wui.TabPage.setOnSelectedCallback(UIView tabPage, function callback)

函数说明

注册TabPage组件点击事件回调处理函数。

使用示例

  1. local pages = {
  2. {
  3. view = 'div',
  4. style = {
  5. width = 480,
  6. ['background-color'] = '#0000ff'
  7. },
  8. subviews = {
  9. {
  10. view = 'text',
  11. value = '配置1',
  12. style = {
  13. ['font-size'] = 100,
  14. color = '#707070'
  15. }
  16. }
  17. }
  18. },
  19. {
  20. view = 'div',
  21. style = {
  22. width = 480,
  23. ['background-color'] = '#ee00ff'
  24. },
  25. subviews = {
  26. {
  27. view = 'text',
  28. value = '配置2',
  29. style = {
  30. ['font-size'] = 100,
  31. color = '#707070'
  32. }
  33. }
  34. }
  35. }
  36. }
  37. local tabPageConfig = {}
  38. tabPageConfig.currentPage = 1
  39. tabPageConfig.pageWidth = 480
  40. tabPageConfig.pageHeight = 560
  41. tabPageConfig.tabTitles = {
  42. {
  43. title = '配置1',
  44. icon = 'https://gw.alicdn.com/tfs/TB1MWXdSpXXXXcmXXXXXXXXXXXX-72-72.png',
  45. activeIcon = 'https://gw.alicdn.com/tfs/TB1kCk2SXXXXXXFXFXXXXXXXXXX-72-72.png',
  46. },
  47. {
  48. title = '配置2',
  49. icon = 'https://gw.alicdn.com/tfs/TB1ARoKSXXXXXc9XVXXXXXXXXXX-72-72.png',
  50. activeIcon = 'https://gw.alicdn.com/tfs/TB19Z72SXXXXXamXFXXXXXXXXXX-72-72.png'
  51. }
  52. }
  53. tabPageConfig.tabStyle = {
  54. backgroundColor = '#FFFFFF',
  55. titleColor = '#666666',
  56. activeTitleColor = '#3D3D3D',
  57. activeBackgroundColor = '#FFFFFF',
  58. isActiveTitleBold = true,
  59. iconWidth = 70,
  60. iconHeight = 70,
  61. width = 160,
  62. height = 120,
  63. fontSize = 24,
  64. hasActiveBottom = true,
  65. activeBottomColor = '#FFC900',
  66. activeBottomHeight = 6,
  67. activeBottomWidth = 120,
  68. textPaddingLeft = 10,
  69. textPaddingRight = 10
  70. }
  71. local tabPage = wui.TabPage.createView(context, { pages = pages, config = tabPageConfig })
  72. wui.TabPage.setOnSelectedCallback(tabPage, function (id, currentPage)
  73. print('tabPage id: ' .. id)
  74. print('tabPage currentPage: ' .. tostring(currentPage))
  75. end)
  76. context:getRootView():addSubview(tabPage)

wui.GridSelect组件

◆ 函数 wui.GridSelect.createLayout : 静态构建GridSelect组件

函数语法

table wui.GridSelect.createLayout(table layout)

函数说明

静态构建GridSelect组件。

layout: table类型,有以下参数设置:


◆ 函数 wui.GridSelect.createView : 动态构建GridSelect组件

函数语法

UIView wui.GridSelect.createView(UIContext context, table layout)

函数说明

动态构建GridSelect组件。


◆ 函数 wui.GridSelect.setOnSelectedCallback : 设置GridSelect组件的回调函数

函数语法

void wui.GridSelect.setOnSelectedCallback(UIView gridSelect, function selectCallback, function overLimitCallback)

函数说明

注册gridSelect组件点击事件回调处理函数。

使用示例

  1. local gridStyle = {
  2. lineSpacing = 14,
  3. width = 110,
  4. height = 50,
  5. fontSize = 20,
  6. color = '#333333',
  7. checkedColor = '#ffffff',
  8. disabledColor = '#eeeeee',
  9. borderColor = '#666666',
  10. checkedBorderColor = '#ffb200',
  11. backgroundColor = '#ffffff',
  12. checkedBackgroundColor = '#ffb200',
  13. }
  14. local testData1 = {
  15. { title = '上海', disabled = true },
  16. { title = '杭州', checked = true },
  17. { title = '北京' },
  18. { title = '广州' },
  19. { title = '深圳' },
  20. { title = '南京' }
  21. }
  22. local testData2 = {
  23. { title = '上海' },
  24. { title = '杭州', checked = true },
  25. { title = '北京', checked = true },
  26. { title = '广州' },
  27. { title = '深圳' },
  28. { title = '南京' }
  29. }
  30. local view = wui.GridSelect.createView(context, { list = testData1, config = { single = true } })
  31. wui.GridSelect.setOnSelectedCallback(view, function (id, index, checked, checkedList)
  32. print("gridSelect selectedCallback id: " .. id)
  33. print("gridSelect selectedCallback current index: " .. tostring(index))
  34. print("gridSelect selectedCallback current checked: " .. tostring(checked))
  35. for i, v in ipairs(checkedList) do
  36. print("> gridSelect selectedCallback selected index: " .. tostring(v))
  37. end
  38. end
  39. )
  40. context:getRootView():addSubview(view)
  41. local view2 = wui.GridSelect.createView(context, { list = testData2, config = { limit = 2, totalWidth = 650, gridStyle = gridStyle } })
  42. wui.GridSelect.setOnSelectedCallback(view2,
  43. function (id, index, checked, checkedList)
  44. print("gridSelect selectedCallback id: " .. id)
  45. print("gridSelect selectedCallback current index: " .. tostring(index))
  46. print("gridSelect selectedCallback current checked: " .. tostring(checked))
  47. for i, v in ipairs(checkedList) do
  48. print("> gridSelect selectedCallback selected index: " .. tostring(v))
  49. end
  50. end,
  51. function (id, limit)
  52. print("gridSelect overLimitCallback id: " .. id))
  53. print("gridSelect overLimitCallback limit: " .. tostring(limit))
  54. end
  55. )
  56. context:getRootView():addSubview(view2)

XMod扩展

xsp库

库文件生成

xsp库和普通xsp脚本包导出方式一致,只需通过叉叉集成开发环境的功能菜单中的发布-导出脚本即可将代码或者图片资源打包成xsp库。

库文件导入和使用

导入xsp库时,只需要在叉叉集成开发环境中对应工程项目下的库文件目录下导入xsp库即可。也可以直接将xsp库文件拷贝到工程目录下的lib目录中。

要加载xsp库中某个代码模块,同样也是通过require函数调用。如现有以下fooLib.xsp库,包含一个名为fooModule的模块:

fooModule

那么,按上述生成fooLib.xsp库文件后,部署在目标工程的库文件目录下之后,只需要在代码中调用require 'fooLib.fooModule'即可调用fooLib.xsp库中的fooModule模块:

using fooModule

使用xsp库中的资源文件时,需要以URI的形式来访问,资源路径为库名+资源在库内路径,同时需要添加xsp的scheme前缀,例如:

  1. -- test_lib/src/main.lua
  2. local rootLayout = {
  3. view = 'scroller',
  4. subviews = {
  5. {
  6. view = 'image',
  7. style = {
  8. width = 80,
  9. height = 80
  10. },
  11. src = 'xsp://fooLib/test.png'
  12. }
  13. }
  14. }

多重嵌套

xsp库是支持多重嵌套的,如fooLib库中还使用到barLib库,那么只需保证barLib库也按照上述要求导入到fooLib中即可,外部工程可以通过调用require 'fooLib.barLib.bar'来加载barLib库中的bar模块。

C/C++扩展

前言

在阅读后续内容之前,需要确认开发者具备以下的基本技能:

如果你有移动平台原生开发相关的经验,或者在其他平台有过Lua C扩展的开发经验,那么以下内容同样也适合你。

没有以上相关经验或技能,但有兴趣并决心学习的开发者也不要气馁,学习最好的时机是昨天,其次是今天。

准备工作

相关安装及部署细节和步骤本文略过不表,请各位开发者善用搜索引擎解决问题。

Android
iOS

API详解

XMod C/C++扩展工程可以在这里下载最新的配置文件和代码(附带例子):GitHub:@xxzhushou/CExtension

Lua虚拟机API

Lua虚拟机API定义在头文件XModLua53APIStub.h中,叉叉引擎从2.0版本开始,使用Lua v5.3运行环境,扩展支持 除以下列表外 的所有公开Lua C API接口:

详细Lua 5.3 C API功能介绍请参阅官方文档:Lua5.3 Reference Manual中的C APIauxiliary library部分。

Lua扩展API

Lua扩展API部分定义在头文件XModLuaExtAPIStub.h中,主要是针对XMod引擎内部的Lua扩展操作,目前有以下API:

注意:由于Lua是基于栈进行数据交换的,除特殊说明,以上所有API均只能在Lua线程(默认触发线程)中调用,不能在其他线程调用,否则会引起不可控的报错甚至闪退。

XMod引擎API

XMod引擎API部分定义在头文件XModAPIStub.h中,主要是针对XMod引擎本身提供的一些C++接口操作,目前有以下API:

代码规范(重点)

头文件引入

有Lua扩展模块经验的开发者可能会留意到,XMod引擎并没有提供Lua原生的lua.h、lauxlib.h等头文件供开发者引入。

在XMod引擎扩展中,提供了XModExtSupport.h这个头文件作为整个XMod引擎扩展库的总头文件,实际上所有lua.hlauxlib.h等Lua官方的头文件已经被合并到了XModLua53APIStub.h这个头文件中,你只能在需要用到Lua模块的地方单独include这个头文件来使用Lua的C API,而 不能 再用类似#include <lua.h>这样的写法。参见示例module/unzip模块中的lua_unzip.cpp中的头文件依赖。

需要注意的是,由于XModExtSupport.h中默认集成的头文件中依赖了C++的namespace等关键词,所以任何包含了XModExtSupport.h的源代码,都需要以cpp/cc/cxx等后缀格式结尾,不能使用c后缀格式,其他源代码文件不受影响。

模块入口函数

每个模块必须提供入口函数,也就是当Lua代码中调用require '<module_name>'时,实际触发的C++入口函数。而这个C++模块入口函数,同样也有统一的规范:

看似规则复杂,实际上要同时保证上面这三点要求,只需要在入口函数上面加上LUALIB_API宏定义即可,例如lua_unzip.cppluaopen_unzip函数的定义是:

  1. LUALIB_API int luaopen_unzip(lua_State *L)
  2. {
  3. ...
  4. }

LUALIB_API宏是在XModLua53APIStub.h中定义的,可以拆解为:

  • extern "C"告诉C++编译器使用C命名方式修饰该函数;
  • __attribute__((visibility("default")))则告诉编译器这个函数符号是可见导出的。

编译和打包

GitHub:@xxzhushou/CExtension项目中的modules/unzip工程为例。

Android动态库编译
iOS动态库编译

待补充。

可以参照modules目录下的工程,创建自定义的扩展模块,也可以在LuaRock官网展示列表中寻找最新和优秀的Lua开源项目,自行编译成动态库后使用。

加载和使用

编译成功后,必须保留动态库的文件命名格式 lib<module_name>.so(Android) 或 lib<module_name>.dylib(iOS),其中<module_name>是模块名称,而且该名称不能和以下XMod官方内置的模块名称冲突:

使用时将编译好的库文件放到脚本工程下的lib目录,即集成开发环境中的库文件目录下。但注意Android和iOS的动态库规范有差异,因此部署也有差异。

部署Android动态库文件

XMod引擎目前支持且仅支持以下两种Android架构:

目前普遍的真机设备是使用ARM架构,其中支持arm64的设备一般也是兼容arm的,而x86架构主要用于安卓模拟器(也有极少数的x86的真机设备)。

由于这两种架构本身互不兼容(事实上部分模拟器也可能集成了Intel的houdini模块以兼容arm在x86的运行),上述编译出来的动态库需要按照架构区分存放,具体搜索优先级是:

cmodule这个动态库为例,假设脚本运行在arm架构的Android设备上,那么当代码中使用require 'cmodule'加载cmoudle动态库,XMod加载器会按照以下优先级搜索cmodule模块:

如果不存在这两个文件,require失败脚本报错;如果文件存在,则会尝试进行加载。

注意由于不同架构互不兼容,虽然x86架构的模拟器一般有专门的转换模块兼容arm格式的动态库,但反过来是行不通的。所以可能会出现只编译了x86架构的动态库,但没有严格按照架构进行后缀区分,那么脚本运行在arm架构设备上会被错误加载了只兼容x86的动态库,严重可能会引起引擎的崩溃。

除非你明确清楚和知道当前脚本的运行平台和环境,否则强烈建议严格按照本文的架构后缀进行区分,避免不必要的问题发生。

部署iOS动态库文件

待补充。

修改工程配置

双击左边导航栏的工程名称,打开工程属性设置,在下方C扩展配置设置面板中,点击添加然后编辑名称和入口函数(注意名称只需要填写模块名,不是完整的动态库文件名),最后确定保存后即可在代码中使用。

editing project

附录

A. 引擎目录说明

公共目录路径

脚本私有目录路径

B. 颜色值和颜色序列规范

颜色值

引擎中所有颜色值、颜色序列的表示中,当使用integer表示时,对应的十六进制表示中采用0xRRGGBB格式来指定色值,即0xRRGGBB和Color3B(RR, GG, BB)表示同一个色值。

颜色值支持以下三种格式描述,任一均可:

颜色序列

颜色序列是一组或多组的颜色值、坐标。支持以下两种格式描述,任一均可:

其中:

要进一步了解关于offset偏色值的描述,可以参阅附录D. 偏色和二值化说明-偏色处的详细说明。

最简单的找色脚本中,指定单点查找色值,例如以下代码:

  1. local pos = screen.findColor(Rect(50, 50, 300, 300), 0x112233)
  2. if pos ~= Point.INVALID then
  3. touch.down(1, pos)
  4. sleep(50)
  5. touch.up(1, pos)
  6. end

使用以上方法找色时,常常会因为屏幕上有大量符合指定颜色的点而不能找到需要的坐标。该函数通过在寻找到一个符合指定颜色color的坐标后,进一步确认其周边点坐标的方式,来确定准确目标。例如,现在我们在图像上找到了我们需要的一个按钮,这个按钮的样式是不变的,但是它的整体位置却会在整个屏幕上变化,现在我们想要在脚本运行时得到其坐标。

首先确定一个参照点:
颜色为 0x181F85,坐标为 (268, 802),下表序号1。
记录下来,继续寻找周边的几个参照点,以及与第一个参照点的相对坐标,分别为下表序号2-4:

现在我们找到了需要的所有参照点:

序号 颜色 绝对坐标 相对坐标
1 0x181F85 (268, 802) (0, 0)
2 0x00BBFE (297, 803) (29, 1)
3 0x0B6BBE (371, 798) (103, -4)
4 0x150972 (333, 811) (65, 9)

应用上述坐标写成多点找色,也就是颜色序列:

  1. local pos = screen.findColor(
  2. Rect(0, 0, 639, 959),
  3. -- 颜色序列string描述
  4. "0|0|0x181F85,29|1|0x00BBFE|90,103|-4|0x0B6BBE-0x050505,65|9|0x150972")
  5. local pos2 = screen.findColor(
  6. Rect(0, 0, 639, 959),
  7. -- 颜色序列table描述
  8. {
  9. { pos = Point(0, 0), color = 0x181F85 },
  10. { pos = Point(29, 1), color = 0x00BBFE, fuzz = 90 },
  11. { pos = Point(103, -4), color = 0x0B6BBE, offset = 0x050505 },
  12. { pos = Point(65, 9), color = 0x15097 2}
  13. })

C. 坐标体系和搜索方向

坐标体系

TODO

搜索方向

引擎部分提供的找图、找色API有可选的priority设置,可选以下参数及其组合,指定查找过程中方向的优先级:

下图展示了在5x3px的搜索范围中,不同组合的搜索顺序。

priority示例

图示圆圈表示像素点,圈中数字表示搜索的顺序,箭头表示像素点的查找过程。

示例:

  1. -- 组合priority用到的二进制操作模块bit库, 引擎内置但需要主动require加载使用
  2. local bit = require('bit32')
  3. -- 指定从下到上, 从左到右, 并且垂直优先(即优先从下到上方向)的顺序进行查找
  4. local priority = bit.bor(screen.PRIORITY_LEFT_FIRST, screen.PRIORITY_DOWN_FIRST, screen.PRIORITY_VERTICAL_FIRST)
  5. -- Rect(100, 100, 200, 200)范围查找色值0xba3e00, 模糊度为90
  6. local pos = screen.findColor(Rect(100, 100, 200, 200), 0xba3e00, 90, priority)
  7. if pos ~= Point.INVALID then
  8. printf('No.1 found at %s', pos)
  9. end

D. 偏色和二值化说明

偏色

引擎中偏色使用diff = { 'C1-D1', 'C2-D2', ... }的格式来描述,其意义是:

当区域内任意一个颜色值Cxy,满足条件 max(Ci - Di, 0x000000) ≤ Cxy ≤ min(Ci + Di, 0xffffff),i = 1, 2, … 的时候,pos = Point(x, y)的颜色就是有效颜色(0xffffff),否则认为是无效颜色(0x000000)。

举个例子,{ '0x1f1f1f-0x303030', '0xacacac-0x101010' } 表示,指定区域内的所有颜色值Cxy,只要满足 max(0x1f1f1f - 0x303030, 0x000000) ≤ Cxy ≤ min(0x1f1f1f + 0x303030, 0xffffff) 或 max(0xacacac - 0x101010, 0x000000) ≤ Cxy ≤ min(0xacacac + 0x101010, 0xffffff),即Cxy范围在 [0x000000, 0x4f4f4f] 或 [0x9c9c9c, 0xbcbcbc] 区间内,那么pos = (x, y)的色值就是有效色值。

二值化

图片经过diff偏色指定的序列处理过程称为二值化,二值化后的图片只有黑和白两种颜色,可以用于提交给大漠、Tesseract等文字识别处理,提高识别精准度。

二值化后的图片(或二维数组)只有黑白两种颜色,一般默认白色为有效颜色,黑色为无效颜色。

E. UI模块设计和样式

设计理念

从2.0开始,引擎引入了一个新的UI模块,可让开发者使用近似Web开发体验来构建高性能、富交互的自定义界面。

创建一个界面,由界面布局结构、样式描述、事件响应三部分构成:

完整示例:

  1. -- 界面布局
  2. local rootLayout = {
  3. view = 'scroller',
  4. -- 样式描述(内联)
  5. style = {
  6. width = 750,
  7. ['background-color'] = '#ff0',
  8. ['align-items'] = 'center'
  9. },
  10. subviews = {
  11. {
  12. view = 'text',
  13. class = 'txt',
  14. value = '测试'
  15. }, {
  16. view = 'image',
  17. style = {
  18. width = 40,
  19. height = 40
  20. },
  21. src = 'https://gw.alicdn.com/tfs/TB14fp2pwMPMeJjy1XbXXcwxVXa-72-72.png'
  22. }, {
  23. id = 'test_btn',
  24. view = 'div',
  25. class = 'btn',
  26. subviews = {
  27. {
  28. view = 'text',
  29. class = 'txt',
  30. value = 'ok'
  31. }
  32. }
  33. }
  34. }
  35. }
  36. -- 样式描述(全局)
  37. local globalStyle = {
  38. txt = {
  39. color = '#41b883',
  40. ['font-size'] = 40,
  41. ['padding-top'] = 10,
  42. ['padding-bottom'] = 10
  43. },
  44. btn = {
  45. width = 710,
  46. height = 80,
  47. ['align-items'] = 'center',
  48. ['border-width'] = 1.5,
  49. ['border-radius'] = 24,
  50. ['border-color'] = '#dddddd',
  51. ['background-image'] = 'linear-gradient(to top, #E3F5FB, #F9FEFF)'
  52. },
  53. ['btn:active'] = {
  54. ['background-image'] = 'linear-gradient(to top, #DFDFDF, #AFAFAF)'
  55. }
  56. }
  57. local context = UI.createContext(rootLayout, globalStyle)
  58. -- 事件响应
  59. context:findView('test_btn'):setActionCallback(UI.ACTION.CLICK, function (id, action)
  60. context:close()
  61. end)
  62. while true do
  63. sleep(1000)
  64. end

界面布局

和HTML中类似,不同标签代表的组件有各自的属性,其中一些组件还能有子组件。

布局的主要属性有:

最顶层组件,我们称为根组件(root view),建议使用以下两种类型组件作为根组件:

样式描述

使用类CSS的样式语法,可理解为CSS的一个子集,两者有一些细微的区别。

支持以下两种方式来设定样式:

所有组件都支持以下通用样式规则。

事件响应

引擎提供了通过事件触发动作的能力,例如在用户点击组件时执行某些回调函数。下面列出了可被添加到引擎UI组件上以定义事件动作的属性:

资源加载方式

UI模块支持以下几种资源加载模式(scheme):

F. UI内置基础组件库

div组件

div组件是用于包装其它组件的最基本容器。支持所有的通用样式、特性、flexbox 布局。

其类似于HTML的div容器,嵌套层级不可过深,否则容易引起性能问题,建议控制在 10 层以内。

div支持包括div本身在内的任何组件作为自己的子组件。因此在写一个组件时,推荐外层使用div作为根容器。

text组件

用来将文本按照指定的样式渲染出来,文本头尾空白会被过滤。

特有属性:

image组件

image用于在界面中显示单个图片。必须指定样式中的宽度和高度,否则无法正常显示。

特有属性:

input组件

input组件用来创建接收用户输入字符的输入组件。input组件的工作方式因type属性的值而异。

特有属性:

textarea组件

用于用户交互,接受用户输入数据。可以认为是自适应高度的input。

textarea组件支持text组件的所有属性,除此之外还支持以下属性:

scroller组件

scroller是一个可以容纳多个子组件的滚动组件。如果子组件的总高度/宽度高于其本身,那么所有的子组件都可滚动。

特有属性:

注意scroll-direction定义了scroller的滚动方向,样式表属性flex-direction定义了scroller的布局方向(默认值是'column'),两个方向必须一致(由于这两个值均是默认值,当需要一个竖直方向的scroller时,这两个值可以不设置)。

当需要一个水平方向的scroller时,使用scroll-direction = 'horizontal'和flex-direction = 'row';
当需要一个竖直方向的scroller时,使用scroll-direction = 'vertical'和flex-direction = 'column'。

注意scroll-direction为Attr属性,而flex-direction为Style样式设置。

web组件

用于显示由src属性指定的页面内容,必须指定web组件的width和height样式。

注意web组件不能包含任何嵌套的子组件。

特有属性:

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注