framework.functions
补充了一些常用函数,并替换了少量内置函数。
~~
tonumber
转换为数值,如果无法转换则返回 0。
tonumber() 原本是 Lua 内置函数,但内置版本在无法转换时会返回 nil,这样还是需要进行后续判断。quick 替换了内置版本。
格式:
value = tonumber(值)
~~
toint
转换为整数,如果无法转换则返回 0。
格式:
value = toint(值)
~~
tobool
转换为布尔值。
格式:
value = tobool(值)
~~
totable
转换为表格,如果传入的值不是表格,则返回一个空表格。
格式:
value = totable(值)
~~
clone
深度克隆一个值。
格式:
value = clone(值)
用法示例:
-- 下面的代码,t2 是 t1 的引用,修改 t2 的属性时,t1 的内容也会发生变化 local t1 = {a = 1, b = 2} local t2 = t1 t2.b = 3 -- t1 = {a = 1, b = 3} <-- t1.b 发生变化 -- clone() 返回 t1 的副本,修改 t2 不会影响 t1 local t1 = {a = 1, b = 2} local t2 = clone(t1) t2.b = 3 -- t1 = {a = 1, b = 2} <-- t1.b 不受影响
~~
class
创建一个类。
格式:
类 = class(类名, [父类])
用法示例:
-- 定义名为 Shape 的基础类 local Shape = class("Shape") -- ctor() 是类的构造函数,在调用 Shape.new() 创建 Shape 对象实例时会自动执行 function Shape:ctor(shapeName) self.shapeName = shapeName printf("Shape:ctor(%s)", self.shapeName) end -- 为 Shape 定义个名为 draw() 的方法 function Shape:draw() printf("draw %s", self.shapeName) end -- -- Circle 是 Shape 的继承类 local Circle = class("Circle", Shape) function Circle:ctor() -- 如果继承类覆盖了 ctor() 构造函数,那么必须手动调用父类构造函数 -- 类名.super 可以访问指定类的父类 Circle.super.ctor(self, "circle") self.radius = 100 end function Circle:setRadius(radius) self.radius = radius end -- 覆盖父类的同名方法 function Circle:draw() printf("draw %s, raidus = %0.2f", self.shapeName, self.raidus) end -- local Rectangle = class("Rectangle", Shape) function Rectangle:ctor() Rectangle.super.ctor(self, "rectangle") end -- local circle = Circle.new() -- 输出: Shape:ctor(circle) circle:setRaidus(200) circle:draw() -- 输出: draw circle, radius = 200.00 local rectangle = Rectangle.new() -- 输出: Shape:ctor(rectangle) rectangle:draw() -- 输出: draw rectangle
请参考:class() 高级用法
~~
import
载入一个模块。
格式:
import(模块名, [当前模块名])
import() 与 require() 功能相同,但具有一定程度的自动化特性。
假设我们有如下的目录结构:
-
app/
-
classes/
-
MyClass.lua
-
MyClassBase.lua
-
data/
-
Data1.lua
-
Data2.lua
-
-
-
MyClass 中需要载入 MyClassBase 和 MyClassData。如果用 require(),MyClass 内的代码如下:
local MyClassBase = require("app.classes.MyClassBase") local MyClass = class("MyClass", MyClassBase) local Data1 = require("app.classes.data.Data1") local Data2 = require("app.classes.data.Data2")
假如我们将 MyClass 及其相关文件换一个目录存放,那么就必须修改 MyClass 中的 require() 命令,否则将找不到模块文件。
而使用 import(),我们只需要如下写:
local MyClassBase = import(".MyClassBase") local MyClass = class("MyClass", MyClassBase) local Data1 = import(".data.Data1") local Data2 = import(".data.Data2")
当在模块名前面有一个“.”时,import() 会从当前模块所在目录中查找其他模块。因此 MyClass 及其相关文件不管存放到什么目录里,我们都不再需要修改 MyClass 中的 import() 命令。这在开发一些重复使用的功能组件时,会非常方便。
我们可以在模块名前添加多个“.”,这样 import() 会从更上层的目录开始查找模块。
~
不过 import() 只有在模块级别调用(也就是没有将 import() 写在任何函数中)时,才能够自动得到当前模块名。如果需要在函数中调用 import(),那么就需要指定当前模块名:
# MyClass.lua # 这里的 ... 是隐藏参数,包含了当前模块的名字,所以最好将这行代码写在模块的第一行 local CURRENT_MODULE_NAME = ... local function testLoad() local MyClassBase = import(".MyClassBase", CURRENT_MODULE_NAME) # 更多代码 end
~~
handler
将 Lua 对象及其方法包装为一个匿名函数。
格式:
函数 = handler(对象, 对象.方法)
在 quick-cocos2d-x 中,许多功能需要传入一个 Lua 函数做参数,然后在特定事件发生时就会调用传入的函数。例如触摸事件、帧事件等等。
local MyScene = class("MyScene", function() return display.newScene("MyScene") end) function MyScene:ctor() self.frameTimeCount = 0 -- 注册帧事件 self:scheduleUpdate(self.onEnterFrame) end function MyScene:onEnterFrame(dt) self.frameTimeCount = self.frameTimeCount + dt end
上述代码执行时将出错,报告“Invalid self”,这就是因为 C++ 无法识别 Lua 对象方法。因此在调用我们传入的 self.onEnterFrame 方法时没有提供正确的参数。
要让上述的代码正常工作,就需要使用 handler() 进行一下包装:
function MyScene:ctor() self.frameTimeCount = 0 -- 注册帧事件 self:scheduleUpdate(handler(self, self.onEnterFrame)) end
实际上,除了 C++ 回调 Lua 函数之外,在其他所有需要回调的地方都可以使用 handler()。
math.round
对一个数值四舍五入,如果传入的参数不是数值,则返回 0。
格式:
value = math.round(值)
~~
io.exists
测试文件是否存在,如果存在返回 true。
格式:
result = io.exists(路径)
可以使用 CCFileUtils:fullPathForFilename() 函数查找特定文件的完整路径,例如:
local path = CCFileUtils:sharedFileUtils():fullPathForFilename("gamedata.txt") if io.exists(path) then .... end
~~
io.readfile
读取文件,并返回文件内容。
格式:
contents = io.readfile(路径)
io.readfile() 会一次性读取整个文件的内容,并返回一个字符串,因此该函数不适宜读取太大的文件。
~~
io.writefile
将内容写入文件,成功返回 true。
格式:
io.writefile(路径, 内容, 写入模式)
“写入模式”参数决定 io.writefile() 如何写入内容,可用的值如下:
-
“w+”: 覆盖文件已有内容,如果文件不存在则创建新文件
-
“a+”: 追加内容到文件尾部,如果文件不存在则创建文件
此外,还可以在“写入模式”参数最后追加字符“b”,表示以二进制方式写入数据,这样在某些平台上可以避免内容写入不完整。
io.writefile() 默认的“写入参数”是“w+b”。
Android 特别提示:在 Android 平台上,文件只能写入存储卡所在路径,assets 和 data 等目录都是无法写入的。
~~
io.pathinfo
拆分一个路径字符串,返回组成路径的各个部分。
格式:
parts = io.pathinfo(路径)
使用示例:
local pathinfo = io.pathinfo("/var/app/test/abc.png") -- pathinfo.dirname = "/var/app/test/" -- pathinfo.filename = "abc.png" -- pathinfo.basename = "abc" -- pathinfo.extname = ".png"
~~
io.filesize
返回指定文件的大小,如果失败返回 false。
格式:
size = io.filesize(路径)
~~
table.nums
计算表格包含的字段数量。
格式:
count = table.nums(表格对象)
Lua 的“#”操作可以取得表格的长度,但仅限从 1 开始连续数字为索引的表格。table.nums() 可以计算任何表格的长度。
~~
table.keys
返回指定表格中的所有键。
格式:
keys = table.keys(表格对象)
用法示例:
local t = {a = 1, b = 2, c = 3} local keys = table.keys(t) -- keys = {"a", "b", "c"}
~~
table.values
返回指定表格中的所有值。
格式:
values = table.values(表格对象)
用法示例:
local t = {a = "1", b = "2", c = "3"} local values = table.values(t) -- values = {1, 2, 3}
~~
table.merge
合并两个表格。
格式:
table.merge(目标表格对象, 来源表格对象)
将来源表格中所有键及其值复制到目标表格对象中,如果存在同名键,则覆盖其值。
用法示例:
local dest = {a = 1, b = 2} local src = {c = 3, d = 4} table.merge(dest, src) -- dest = {a = 1, b = 2, c = 3, d = 4}
~~
string.htmlspecialchars
转换特殊的字符为 HTML 编码。
格式:
result = string.htmlspecialchars(字符串)
下列字符会被转换:
-
'&' (ampersand) 转换为 '&'
-
'”' (double quote) 转换为 '"'
-
”'” (single quote) 转换为 '''
-
'<' (less than) 转换为 '<'
-
'>' (greater than) 转换为 '>'
~~
string.nl2br
将字符串中的换行符转换为 HTML 换行标记。
格式:
result = string.nl2br(字符串)
用法示例:
local text = "Hello\nWorld." local result = string.nl2br(text) -- result = "Hello<br />World."
将 string.nl2br() 和 string.htmlspecialchars() 结合使用,可以对字符串进行转换,确保转换结果符合 HTML 要求,并且没有安全问题。
local text = "---> Hello\nWorld <---" local result = string.nl2br(string.htmlspecialchars(text)) -- result = "---> Hello<br /> <---"
~~
string.text2html
对字符串进行格式化,确保其中的特殊字符都转换为 HTML 标记。
格式:
result = string.text2html(字符串)
string.text2html() 除了转换特殊字符和换行符,还会将制表符“\t”替换为空格,再将空格替换为“ ”。
~~
string.split
分割字符串。
格式:
result = string.split(要分割的字符串, 分隔符)
用法示例:
local result = string.split("1,2,3", ",") -- result = {"1", "2", "3"}
~~
string.ltrim
删除字符串前部的空白字符。
格式:
result = string.ltrim(字符串)
空白字符包括:空格、制表符“\t”、换行符“\n”和“\r”。
用法示例:
local result = string.ltrim(" \n\tHello") -- result = "Hello"
~~
string.rtrim
删除字符串尾部的空白字符。
格式:
result = string.rtrim(字符串)
~~
string.trim
删除字符串两端的空白字符。
格式:
result = string.trim(字符串)
~~
string.ucfirst
返回首字母大写的字符串。
格式:
result = string.ucfirst(字符串)
~~
string.urlencode
生成符合 URL 规范的字符串。
格式:
result = string.urlencode(字符串)
为了通过 URL 传递数据,字符串中所有的非字母和数字都会被替换为“%编码”格式,空格会被替换为“+”。
~~
string.utf8len
计算一个 UTF8 字符串包含的字符数量。
格式:
count = string.utf8len(字符串)
当一个 UTF8 字符串中包含中文时,string.len() 返回的结果是字符串的字节长度。string.utf8len() 会确保始终返回字符串中包含的字符数量。
~~
string.formatNumberThousands
将数字格式化为千分位格式。
格式:
result = string.formatNumberThousands(数值)
用法示例:
local result = string.formatNumberThousands(12345) -- result = "12,345"