澳门美高梅手机网站KV3文件简介及DOTA2起定义音效制作

<link
href=”http://statics.1024tools.com/libs/highlight.js/styles/monokai.css”
rel=”stylesheet” />
<pre class=’hljs’><code><span class=”hljs-comment”>–
用一个文书学会Lua</span>

近年于召开COTA的音效,进一步深刻了kv3文件,kv3于由kv2还是比好写,而且代码相对会简单很多,而且,KV3可以十分便宜地改成成json(因为格式太像了),如果我们怀念就此底现成的家伙来治本kv3文件的言辞,只待自己写一个简易的kv3-json转换器就可以了。

<span class=”hljs-comment”>– 用鲜个 “-”
开头的代码表示注释,注释代码不见面叫解释器识别(不会见运作)</span>

言归正传,首先来说一下kv3文件。

<span class=”hljs-comment”>–[[
用两个'[‘ 和’]’框起来的意味多尽注释。

即使即来讲,dota2打定义玩受利用到kv3文件的片段包括了 vmdl, vpcf,
vsndevts,也即是范、特效和音效文件,此外还有custom_net_tables.txt使用的吗是kv3文件,更多的有些(例如npc文件夹的那些东西)能不能够因此kv3,我还没有尝试了,欢迎去碰。

–]]</span>
<span class=”hljs-comment”>– 上面就一行前面的 ‘–‘
不是须的,但是推荐写成这样的款式,因为这样看起</span>
<span class=”hljs-comment”>–
比较整齐,而且如果您只要收回这节注释,那么以同开始的前加一个-就可了</span>

1. KV3的语法格式

kv3凡V社开发之超常规数据格式,非常像json,增加的效能是同意二迈入制编码,版本控制和数量注释等等,此外还有额外的语法支持,比如多执行注释和多行字符串等。

<span class=”hljs-comment”>– 就比如这么</span>
<span class=”hljs-comment”>—[[</span>
test = <span class=”hljs-number”>2</span> <span
class=”hljs-comment”>– 这行是无为诠释掉的</span>
<span class=”hljs-comment”>–]]</span>

1.1 文件头

每个KV3文件还得一个文书头,里面含有了标识编码和格式的guid,对于多数丁来讲,只待牢记创建文件的当儿复制粘贴这一行到文件头就是足以了。

<!-- kv3 encoding:text:version{e21c7f3c-8a33-41c5-9977-a76d3a32aa0d} format:generic:version{7412167c-06e9-4698-aff2-e63eb59037e7} -->

<span
class=”hljs-comment”>——————————————————————————–</span>
<span class=”hljs-comment”>– 1.
变量类型以及程序流程控制</span>
<span
class=”hljs-comment”>——————————————————————————–</span>

1.2 语法

语法很简短,一个文书就足以验证所有题目

<!-- kv3 encoding:text:version{e21c7f3c-8a33-41c5-9977-a76d3a32aa0d} format:generic:version{7412167c-06e9-4698-aff2-e63eb59037e7} -->
{
    boolValue = false // 布尔值
    intValue = 128 // 整数
    doubleValue = 64.000000 // 浮点数
    stringValue = "hello world" // 字符串
    stringThatIsAResourceReference = resource:"particles/items3_fx/star_emblem.vpcf" // 这个是带有resource flag前缀的特殊用法
    multiLineStringValue = """
First line of a multi-line string literal.
Second line of a multi-line string literal.
"""
// 多行字符串
    arrayValue =
    [
        1,
        2,
    ]
// 数组,注意各个元素之间有逗号
    objectValue =
    {
        n = 5
        s = "foo"
    }
// Object,注意各个元素之间没有逗号
/*
这是一个多行注释
*/
}

num = <span class=”hljs-number”>42</span> <span
class=”hljs-comment”>– 数值(number)类型</span>

1.3 多执行字符串的异说明

于kv3中形容多执字符串,需要用三单括号开始,之后立即开始一个新行,在差不多行字符串结束之后,需要开始一个新行,之后写三个括号。这片单新行都是要的。在这六只括号内的有字符,都见面让直读取,而不解析(也就是说\n之类的连无见面吃分解啊换行。)

s = <span class=”hljs-string”>’walternate'</span> <span
class=”hljs-comment”>– 字符串类型</span>
t = <span class=”hljs-string”>”double-quotes are also
fine”</span> <span class=”hljs-comment”>–
字符串也可就此双引号括起来</span>
<span class=”hljs-comment”>– 用两个'[‘
‘]’括起来的表示多尽字符串,如果你当[[其后放一个换行符,那么这换行符会被忽视</span>
u = <span class=”hljs-string”>[[ Double brackets
start and end
multi-line strings.]]</span>
t = <span class=”hljs-keyword”>nil</span> <span
class=”hljs-comment”>–
一个变量如果为装置也nil,那么这变量将会给放飞,并受垃圾回收机制自动收集</span>

2. kv3从定义音效

dota2的自定义音效的采取得简单栽档次的文本,一个凡是位于soundevents中之vsndevts
kv3文件,一个凡坐落sounds文件夹着的音频文件(mp3和wav格式的音乐文件都是支持之,其他品类的文本没有测试)。音频文件就不说了,只要加大着便得了,在好vsndevts的编制之后,音频文件将会见于电动编译成vsnd文件。
此地先放一个演示文件,再来仔细说:

<!-- kv3 encoding:text:version{e21c7f3c-8a33-41c5-9977-a76d3a32aa0d} format:generic:version{7412167c-06e9-4698-aff2-e63eb59037e7} -->
{
    Rock.ui_startup =
    {
        type = "dota_update_ui_startup"
        vsnd_files =
        [
            "sounds/ui_startup_01.vsnd",
            "sounds/ui_startup_02.vsnd",
        ]
        volume = "1.000000"
        weights =
        [
            "1",
            "1",
        ]
    }
}

只要这么定义之后,我们就是可当lua或者js文件中来运EmitSound的各API来使用
“Rock.ui_startup”来播放我们在sounds文件夹着的ui_startup_01.mp3或者ui_startup_02.mp3了。

解释一下几个参数:
1、 type 声音的风波类,这个波是那个重大的,目前怀有或的价值包括

    dota_src1_2d // 2D音频
    dota_src1_3d // 3D音频

    battle_end_countdown // 战斗结束的倒数计时
    dota_gamestart_horn // 游戏开始的号角

    dota_update_vo_clamped_panning
    dota_update_vo_spatial_stereo
    dota_update_vo_switch
    dota_update_vo_default
    dota_update_vo_clamped
    dota_update_vo_announcer // 几种类型的voice

    dota_update_ganked_music
    dota_update_music_3layer
    dota_update_battle_music
    dota_update_battle_end
    dota_update_hero_select
    dota_update_default

    dota_update_killed
    dota_update_smoke
    dota_update_smoke_end
    dota_update_smoke_end_hero
    dota_update_roshan
    dota_update_roshan_end
    dota_music_respawn
    dota_update_countdown
    dota_update_opvar_track

    dota_music_stinger_stoptracks

    dota_ui_start_multi
    dota_ui_limit_time
    dota_update_ui_startup
    dota_update_ui_main
    dota_stop_loop_ui
    dota_voip

    dota_limit_speakers_ui
    dota_limit_speakers_inv
    dota_limit_speakers_spectui

俺们一般的话就需要动用dota_src1_2d或者dota_src1_3d色的节奏就是得了,要牢记的少数即是,如果你突然不亮要怎么定义了,就顶法定的vsndevts文件中错过摸索同样类型的公文,仿照着抄就得了。

2、声音之习性定义

// 属性名 范例值 说明
soundlevel "81.000000" 声音强度
distance_max "2500.000000" 最大范围,3d音效使用

spread_radius "6000.000000" 扩展范围

rand_delay_min "1.000000" 随机开始延迟的最小和最大值
rand_delay_max "5.000000"

volume 0-1 声音的音量
volume_fade_in "1.500000" 淡入时间
volume_fade_out "1.500000" 淡出时间
volume_falloff_min "10.000000" 减弱距离
volume_falloff_max "1000.000000"
volume_rand_min "-0.149902" 随机的音量偏移的最小和最大值
volume_rand_max "0.149902"

pitch 0-1 音调,属性和音量类似

pitch_rand_min "-0.010000"
pitch_rand_max "0.010000"

vsnd_files "sounds/vo/announcer/announcer_now_select.vsnd" // 定义音乐文件,不管你的音乐是啥扩展名,一概写成vsnd就可以
vsnd_files 
    [
        "sounds/vo/announcer/announcer_now_select1.vsnd",
        "sounds/vo/announcer/announcer_now_select2.vsnd"
    ]

weights
    [
        1,
        1
    ]
// 随机在多个音乐之间选择一个,用weights来定义不同的文件的出现概率

start_point "2.000000"
end_point "9.000000"
restart_time "41.599998"
stop_at_time "40.000000"
// 循环播放的音频的起始点、结束点、重新开始的时间

position "[5545.06, 4998.54, 1494]"
// 定义播放的位置

// 下面的这些属性不常用,有兴趣的可以继续往下看
limiter_on
    0 1
limiter_event_name "ui.spect_pickup_in"
limiter_max "1.000000"
limiter_match_entity "0.000000"
limiter_match_type 0 1
limiter_match_substring "0.000000"
limiter_match_entity "1.000000"

memory_type 0

volume_remap_x1 "0.250000"
volume_remap_x2 "0.500000"
volume_remap_x3 "0.750000"
volume_remap_x4 "1.000000"
volume_remap_y1 "0.250000"
volume_remap_y2 "0.500000"
volume_remap_y3 "0.750000"
volume_remap_y4 "1.000000"

remap_vol_x1 "0.800000"
remap_vol_y1 "0.250000"
remap_vol_x2 "0.900000"
remap_vol_y2 "0.500000"
remap_vol_x3 "1.000000"
remap_vol_y3 "1.000000"
remap_vol_x4 "1.000000"
remap_vol_y4 "1.000000"

volume_move_vol "0.010000"
volume_move_vel "300.000000"
volume_move_filter_vel "1.000000"



pitch_remap_x1 "0.250000"
pitch_remap_x2 "0.500000"
pitch_remap_x3 "0.750000"
pitch_remap_x4 "1.000000"
pitch_remap_y1 "0.250000"
pitch_remap_y2 "0.500000"
pitch_remap_y3 "0.750000"
pitch_remap_y4 "1.000000"

remap_intensity_x1 "0.000000"
remap_intensity_y1 "1.000000"
remap_intensity_x2 "0.200000"
remap_intensity_y2 "1.000000"
remap_intensity_x3 "0.670000"
remap_intensity_y3 "1.000000"
remap_intensity_x4 "1.000000"
remap_intensity_y4 "0.500000"


track "explore2"
random_delay_opvar "laning_01_random_delay_opvar"


use_event_data
laning_master



mixgroup "HeroPick"
mixgroup "Weapons"
mixgroup "Stingers"
mixgroup "Ping"
mixgroup "All"
mixgroup "Ultimates"
mixgroup "Physics"
mixgroup "Ambient"
mixgroup "Creeps"

stops_others 0 or 1

block_name "ui_generic_button_click"
block_time "0.250000"
block_time2 "0.750000"
block_duration "1.500000"

soundevent_01 "ui_menu_fadeout"
soundevent_02 "ui_select_md"

use_01 "1.000000"
use_02 "1.000000"
use_03 "1.000000"



stop_entry_name "random_wheel_spin"

opvar_field_name "dota_random_wheel_speed"
opvar_stack_name "dota_opvars"
opvar_operator_name "opvars"



event_type
    0 1 2 3 4

<span class=”hljs-comment”>– 表,这个表代表t[1] = 1, t[2] =
“a”,t[“b”]啊一个函数类型</span>
<span class=”hljs-comment”>–
将会当第三独组成部分详细分解表</span>
t = {<span class=”hljs-number”>1</span>,<span
class=”hljs-string”>”a”</span>,b = <span
class=”hljs-function”><span
class=”hljs-keyword”>function</span><span
class=”hljs-params”>()</span></span> <span
class=”hljs-keyword”>end</span>}

<span class=”hljs-comment”>–
函数类型,将会见于亚独片详细分解函数</span>
foo = <span class=”hljs-function”><span
class=”hljs-keyword”>function</span><span
class=”hljs-params”>()</span></span> <span
class=”hljs-keyword”>end</span>

<span class=”hljs-comment”>–
如果一个变量未让定义,也足以利用,但是及时有限个变量都见面是nil(空值)</span>
foo = anUnknownVariable

<span class=”hljs-comment”>– 布尔列</span>
aBoolValue = <span class=”hljs-keyword”>false</span>

<span class=”hljs-comment”>– or 和 and 代表 或 和
且</span>
<span class=”hljs-comment”>– 当 or
的第一只操作数为false或nil的早晚,返回第二独操作数的值</span>
ans = aBoolValue <span class=”hljs-keyword”>and</span>
<span class=”hljs-string”>’yes'</span> <span
class=”hljs-keyword”>or</span> <span
class=”hljs-string”>’no'</span> <span
class=”hljs-comment”>–> ‘no'</span>

<span class=”hljs-comment”>–
nil和false为假,其余所有数值在准判定的下都为真</span>
<span class=”hljs-comment”>– not代表取反</span>
<span class=”hljs-keyword”>if</span> <span
class=”hljs-keyword”>not</span> aBoolValue <span
class=”hljs-keyword”>then</span> <span
class=”hljs-built_in”>print</span>(<span
class=”hljs-string”>’twas false'</span>) <span
class=”hljs-keyword”>end</span>

<span class=”hljs-comment”>– while循环</span>
<span class=”hljs-comment”>–
这里而介绍一个着重概念,代码块,代表一个打do开始到end结束之区域</span>
<span class=”hljs-comment”>–
一个文件本身吗是一个代码块</span>
<span class=”hljs-keyword”>while</span> a < <span
class=”hljs-number”>2</span> <span
class=”hljs-keyword”>do</span>
a = a + <span class=”hljs-number”>1</span>
<span class=”hljs-keyword”>end</span>

<span class=”hljs-comment”>– 条件判定 If</span>
<span class=”hljs-keyword”>if</span> num > <span
class=”hljs-number”>40</span> <span
class=”hljs-keyword”>then</span> <span
class=”hljs-comment”>– 如果num大于40,那么执行</span>
<span class=”hljs-built_in”>print</span>(<span
class=”hljs-string”>’over 40′</span>) <span
class=”hljs-comment”>– print这一行</span>
<span class=”hljs-keyword”>elseif</span> s ~= <span
class=”hljs-string”>’walternate'</span> <span
class=”hljs-keyword”>then</span> <span
class=”hljs-comment”>– 不然如果s不顶 walternate </span>
<span class=”hljs-built_in”>io</span>.write(<span
class=”hljs-string”>’not over 40\n'</span>) <span
class=”hljs-comment”>– 那么输出</span>
<span class=”hljs-keyword”>else</span>
<span class=”hljs-comment”>– 变量默认为全局的</span>
thisIsGlobal = <span class=”hljs-number”>5</span>

<span class=”hljs-comment”>–
如果以头里加上一个local,那么就是见面是一对变量</span>
<span class=”hljs-comment”>–
局部变量的打算范围就限于当前代码块</span>
<span class=”hljs-keyword”>local</span> line = <span
class=”hljs-built_in”>io</span>.read()

<span class=”hljs-comment”>– 使用 .. 来链接字符串</span>
<span class=”hljs-built_in”>print</span>(<span
class=”hljs-string”>’Winter is coming, ‘</span> .. line)
<span class=”hljs-keyword”>end</span>

karlSum = <span class=”hljs-number”>0</span>
<span class=”hljs-keyword”>for</span> i = <span
class=”hljs-number”>1</span>, <span
class=”hljs-number”>100</span> <span
class=”hljs-keyword”>do</span> <span
class=”hljs-comment”>–
for循环,包含1顶100,默认的step为1(可概括),如果如修改step,可以形容为
for i = 1, 100, 10 do</span>
karlSum = karlSum + i
<span class=”hljs-keyword”>end</span>

<span class=”hljs-comment”>–
如果只要倒序for循环,那么用负数的step</span>
fredSum = <span class=”hljs-number”>0</span>
<span class=”hljs-keyword”>for</span> j = <span
class=”hljs-number”>100</span>, <span
class=”hljs-number”>1</span>, -<span
class=”hljs-number”>1</span> <span
class=”hljs-keyword”>do</span> fredSum = fredSum + j <span
class=”hljs-keyword”>end</span>

<span class=”hljs-comment”>– Repeat循环</span>
<span class=”hljs-keyword”>repeat</span>
<span class=”hljs-built_in”>print</span>(<span
class=”hljs-string”>’the way of the future'</span>)
num = num – <span class=”hljs-number”>1</span>
<span class=”hljs-keyword”>until</span> num == <span
class=”hljs-number”>0</span> <span
class=”hljs-comment”>– 循环直到num为0</span>

<span
class=”hljs-comment”>——————————————————————————–</span>
<span class=”hljs-comment”>– 2. 函数类型</span>
<span
class=”hljs-comment”>——————————————————————————–</span>

<span class=”hljs-function”><span
class=”hljs-keyword”>function</span> <span
class=”hljs-title”>fib</span><span
class=”hljs-params”>(n)</span></span>
<span class=”hljs-keyword”>if</span> n < <span
class=”hljs-number”>2</span> <span
class=”hljs-keyword”>then</span> <span
class=”hljs-keyword”>return</span> n <span
class=”hljs-keyword”>end</span>
<span class=”hljs-keyword”>return</span> fib(n – <span
class=”hljs-number”>2</span>) + fib(n – <span
class=”hljs-number”>1</span>)
<span class=”hljs-keyword”>end</span>

<span class=”hljs-comment”>– 闭包和匿名函数</span>
<span class=”hljs-function”><span
class=”hljs-keyword”>function</span> <span
class=”hljs-title”>adder</span><span
class=”hljs-params”>(x)</span></span>
<span class=”hljs-comment”>–
这个函数将会见于adder被调用的时刻吃创造,之后返回一个匿名函数</span>
<span class=”hljs-keyword”>return</span> <span
class=”hljs-function”><span
class=”hljs-keyword”>function</span> <span
class=”hljs-params”>(y)</span></span> <span
class=”hljs-keyword”>return</span> x + y <span
class=”hljs-keyword”>end</span>
<span class=”hljs-keyword”>end</span>

a1 = adder(<span class=”hljs-number”>9</span>)
a2 = adder(<span class=”hljs-number”>36</span>)
<span class=”hljs-built_in”>print</span>(a1(<span
class=”hljs-number”>16</span>)) <span
class=”hljs-comment”>–> 25</span>
<span class=”hljs-built_in”>print</span>(a2(<span
class=”hljs-number”>64</span>)) <span
class=”hljs-comment”>–> 100</span>

<span class=”hljs-comment”>–
一个函数或者赋值语句可以生多个返回值,过多之归来值会被放弃,不够的返回值为nil</span>

x, y, z = <span class=”hljs-number”>1</span>, <span
class=”hljs-number”>2</span>, <span
class=”hljs-number”>3</span>, <span
class=”hljs-number”>4</span>
<span class=”hljs-comment”>– x = 1, y = 2, z = 3
4被舍弃</span>

<span class=”hljs-function”><span
class=”hljs-keyword”>function</span> <span
class=”hljs-title”>bar</span><span
class=”hljs-params”>(a, b, c)</span></span>
<span class=”hljs-built_in”>print</span>(a, b, c)
<span class=”hljs-keyword”>return</span> <span
class=”hljs-number”>4</span>, <span
class=”hljs-number”>8</span>, <span
class=”hljs-number”>15</span>, <span
class=”hljs-number”>16</span>, <span
class=”hljs-number”>23</span>, <span
class=”hljs-number”>42</span>
<span class=”hljs-keyword”>end</span>

x, y = bar(<span class=”hljs-string”>’zaphod'</span>)
<span class=”hljs-comment”>–> 打印出来的结果是 “zaphod nil
nil”</span>
<span class=”hljs-comment”>– x = 4, y = 8,
15..42季单价值为舍弃</span>

<span class=”hljs-comment”>–
函数是第一像样值(和另变量使用起来连随便极端特别分别)</span>
<span class=”hljs-comment”>–
下面这简单单东西是同样的</span>
<span class=”hljs-function”><span
class=”hljs-keyword”>function</span> <span
class=”hljs-title”>f</span><span
class=”hljs-params”>(x)</span></span> <span
class=”hljs-keyword”>return</span> x * x <span
class=”hljs-keyword”>end</span>
f = <span class=”hljs-function”><span
class=”hljs-keyword”>function</span> <span
class=”hljs-params”>(x)</span></span> <span
class=”hljs-keyword”>return</span> x * x <span
class=”hljs-keyword”>end</span>

<span class=”hljs-comment”>–
如果单独来一个字符串或者表作为参数,可以绝不括号来调用</span>
<span class=”hljs-built_in”>print</span> <span
class=”hljs-string”>’hello'</span>
<span class=”hljs-built_in”>print</span> {}

<span
class=”hljs-comment”>——————————————————————————–</span>
<span class=”hljs-comment”>– 3. 表</span>
<span
class=”hljs-comment”>——————————————————————————–</span>

<span class=”hljs-comment”>–
表是lua唯一的复杂性变量类型</span>
<span class=”hljs-comment”>–
可以当作数组或者队列等各种数码结构来采取</span>

<span class=”hljs-comment”>–
表默认使用字符串类型的key</span>
t = {key1 = <span class=”hljs-string”>’value1′</span>, key2
= <span class=”hljs-keyword”>false</span>}

<span class=”hljs-comment”>–
字符串类型的key可以用一个”.”的法门来引用</span>
<span class=”hljs-built_in”>print</span>(t.key1) <span
class=”hljs-comment”>– 打印数值类 ‘value1’.</span>
t.newKey = {} <span class=”hljs-comment”>–
给一个表添加一个初的key</span>
t.key2 = <span class=”hljs-keyword”>nil</span> <span
class=”hljs-comment”>– 移除表的键,这个空间会受假释</span>

<span class=”hljs-comment”>–
一切非nil的价都好看做key(空表,函数,userdata,浮点数,都可以当key)</span>
u = {[<span class=”hljs-string”>’@!#'</span>] = <span
class=”hljs-string”>’qbert'</span>, [{}] = <span
class=”hljs-number”>1729</span>, [<span
class=”hljs-number”>6.28</span>] = <span
class=”hljs-string”>’tau'</span>}
<span class=”hljs-built_in”>print</span>(u[<span
class=”hljs-number”>6.28</span>]) <span
class=”hljs-comment”>– 输出tau</span>

a = u[<span class=”hljs-string”>’@!#'</span>] <span
class=”hljs-comment”>– a于赋值为 ‘qbert'</span>
b = u[{}] <span class=”hljs-comment”>–
你也许会见以为这会回来1729,但是实际上会回去nil</span>
<span class=”hljs-comment”>–
因为这里实在是新建了一个拖欠的发明,这个表和上面赋值的上的酷表是勿相同的</span>
<span class=”hljs-comment”>– 正确的写法应该是</span>
<span class=”hljs-comment”>–[[
local a = {}
u = {[a] = 1729}
print(u[a])
–]]</span>

<span class=”hljs-comment”>–
在表中循环,循环所有key</span>
<span class=”hljs-keyword”>for</span> key, val <span
class=”hljs-keyword”>in</span> <span
class=”hljs-built_in”>pairs</span>(u) <span
class=”hljs-keyword”>do</span> <span
class=”hljs-comment”>– Table iteration.</span>
<span class=”hljs-built_in”>print</span>(key, val)
<span class=”hljs-comment”>–[[
输出:
@!# qbert
table:EFA123 1729
6.28 tau
–]]</span>
<span class=”hljs-keyword”>end</span>

<span class=”hljs-comment”>–
_G是具备全局变量存放的表明,包括外自己</span>
<span class=”hljs-built_in”>print</span>(<span
class=”hljs-built_in”>_G</span>[<span
class=”hljs-string”>’_G'</span>] == <span
class=”hljs-built_in”>_G</span>) <span
class=”hljs-comment”>– Prints ‘true’.</span>

<span class=”hljs-comment”>– 作为数组使用</span>

<span class=”hljs-comment”>–
如果在新建table的时节没有点名key,那么用会见自行复制给整数的key</span>
v = {<span class=”hljs-string”>’value1′</span>, <span
class=”hljs-string”>’value2′</span>, <span
class=”hljs-number”>1.21</span>, <span
class=”hljs-string”>’gigawatts'</span>}
<span class=”hljs-keyword”>for</span> i = <span
class=”hljs-number”>1</span>, #v <span
class=”hljs-keyword”>do</span> <span
class=”hljs-comment”>– 对于频繁组的table来说,
#v能够赢得数组的因素个数</span>
<span class=”hljs-comment”>–
如果table不是一味的int为键值的高频组,那么以见面只回去</span>
<span class=”hljs-comment”>– int部分的个数</span>
<span class=”hljs-built_in”>print</span>(v[i]) <span
class=”hljs-comment”>–
对于lua来说,数组的下标是自从1始的</span>
<span class=”hljs-keyword”>end</span>

<span
class=”hljs-comment”>——————————————————————————–</span>
<span class=”hljs-comment”>– 3.1 元表和元方法</span>
<span
class=”hljs-comment”>——————————————————————————–</span>

<span class=”hljs-comment”>–
元表和元方法会比较复杂也较难理解</span>

<span class=”hljs-comment”>–
在lua中,table可以应用setmetatable函数来安他的元表</span>
<span class=”hljs-comment”>–
之后对这table的有的操作,将会见冲metatable的安装来</span>
<span class=”hljs-comment”>– 进行相应的操作</span>
<span class=”hljs-comment”>–
元表的一部分艺术称为元方法</span>

f1 = {a = <span class=”hljs-number”>1</span>, b = <span
class=”hljs-number”>2</span>}
f2 = {a = <span class=”hljs-number”>2</span>, b = <span
class=”hljs-number”>3</span>}

<span class=”hljs-comment”>– 如果您于此时节实施 f1 + f2
将会发生一个荒唐</span>
<span class=”hljs-comment”>– 尝试对table进行加法操作</span>

<span class=”hljs-comment”>–
这个时节咱们定义一个元表</span>
metafraction = {}
<span class=”hljs-comment”>– 重新定义元表的 __add
元方法</span>
<span class=”hljs-function”><span
class=”hljs-keyword”>function</span> <span
class=”hljs-title”>metafraction.__add</span><span
class=”hljs-params”>(f1, f2)</span></span>
<span class=”hljs-keyword”>local</span> sum = {}
sum.b = f1.b * f2.b
sum.a = f1.a * f2.b + f2.a * f1.b
<span class=”hljs-keyword”>return</span> sum
<span class=”hljs-keyword”>end</span>

<span class=”hljs-comment”>– 之后定义 f1 f2 两单table的元表为
metafraction</span>
<span class=”hljs-built_in”>setmetatable</span>(f1,
metafraction)
<span class=”hljs-built_in”>setmetatable</span>(f2,
metafraction)

s = f1 + f2 <span class=”hljs-comment”>– 这里品尝对 f1
推行加法操作,将见面尝试当 f1 的元表中失找寻 __add
方法,之后执行的</span>

<span class=”hljs-comment”>– 元表的 __add
方法会在品尝对table进行加法操作的上让调用</span>
<span class=”hljs-comment”>– 而元表的 __index
方法以会见于品味对table进行索引操作都以该table的此目录不存的早晚调用</span>
<span class=”hljs-comment”>– 索引操作包括 table.key table[key]
table:key() 等等</span>
defaultFavs = {animal = <span
class=”hljs-string”>’gru'</span>, food = <span
class=”hljs-string”>’donuts'</span>}
myFavs = {food = <span class=”hljs-string”>’pizza'</span>}
<span class=”hljs-built_in”>setmetatable</span>(myFavs,
{__index = defaultFavs})
eatenBy = myFavs.animal <span class=”hljs-comment”>– 虽然
myFavs不带有animal的概念,但是坐他的元表有关于animal的定义</span>
<span class=”hljs-comment”>– 所以这里eatBy将会晤为定义为
“gru”</span>

<span
class=”hljs-comment”>——————————————————————————–</span>
<span class=”hljs-comment”>– 以下也所有的元方法列表</span>

<span class=”hljs-comment”>– __add(a, b) for a +
b</span>
<span class=”hljs-comment”>– __sub(a, b) for a –
b</span>
<span class=”hljs-comment”>– __mul(a, b) for a *
b</span>
<span class=”hljs-comment”>– __div(a, b) for a /
b</span>
<span class=”hljs-comment”>– __mod(a, b) for a %
b</span>
<span class=”hljs-comment”>– __pow(a, b) for a ^
b</span>
<span class=”hljs-comment”>– __unm(a) for -a</span>
<span class=”hljs-comment”>– __concat(a, b) for a ..
b</span>
<span class=”hljs-comment”>– __len(a) for #a</span>
<span class=”hljs-comment”>– __eq(a, b) for a ==
b</span>
<span class=”hljs-comment”>– __lt(a, b) for a <
b</span>
<span class=”hljs-comment”>– __le(a, b) for a <=
b</span>
<span class=”hljs-comment”>– __index(a, b) <fn or a
table> for a.b</span>
<span class=”hljs-comment”>– __newindex(a, b, c) for a.b =
c</span>
<span class=”hljs-comment”>– __call(a, …) for
a(…)</span>

<span class=”hljs-comment”>– 当然
元表也堪是匿名的发明,比如说</span>
t = {}
<span
class=”hljs-built_in”>setmetatable</span>(t,{__index = {key
= <span class=”hljs-number”>3</span>}})
<span class=”hljs-built_in”>print</span>(t.key) <span
class=”hljs-comment”>– 将见面输出3</span>

<span
class=”hljs-comment”>——————————————————————————–</span>
<span class=”hljs-comment”>– 3.2 类似于类的定义</span>
<span
class=”hljs-comment”>——————————————————————————–</span>

<span class=”hljs-comment”>–
本来是仿佛是急需一致段蛮长的字数来验证的</span>
<span class=”hljs-comment”>–
但是坐Valve已经提供了十足好用的class函数</span>
<span class=”hljs-comment”>–
来成功接近的定义,这里我们只说说以</span>
<span class=”hljs-comment”>– 至于类的概念如何实现,可以去查看
</span>
<span class=”hljs-comment”>– dota 2
beta\game\core\scripts\vscripts\utils\class.lua</span>

<span class=”hljs-comment”>– 定义一个类</span>
<span class=”hljs-comment”>–
要专注的凡,这个MyClass本质上也是一个table</span>
<span class=”hljs-comment”>– 一个具有元表的table</span>
MyClass = class({ s = <span class=”hljs-number”>2</span> })
<span class=”hljs-comment”>–
这里我们定义了一个享初始s属性的类</span>

<span class=”hljs-comment”>– 定义类的构造函数</span>
<span class=”hljs-comment”>–
这里我们下的凡:而未是.来定义函数</span>
<span class=”hljs-comment”>–
:在lua中是一致栽语法糖,将会见叫这个函数自动传送一个self参数</span>
<span class=”hljs-comment”>– 这个函数的定义相当给</span>
<span class=”hljs-comment”>–[[
function MyClass.constructor(self, param)
self.myParam = param
end
–]]</span>
<span class=”hljs-function”><span
class=”hljs-keyword”>function</span> <span
class=”hljs-title”>MyClass:constructor</span><span
class=”hljs-params”>(param)</span></span>
self.myParam = param <span class=”hljs-comment”>–
为类的变量赋值</span>
<span class=”hljs-keyword”>end</span>

<span class=”hljs-comment”>– 定义类的主意</span>
<span class=”hljs-function”><span
class=”hljs-keyword”>function</span> <span
class=”hljs-title”>MyClass:DoSomething</span><span
class=”hljs-params”>()</span></span>
<span class=”hljs-built_in”>print</span>(<span
class=”hljs-string”>”I’m working, “</span> .. self.myParam)
<span class=”hljs-keyword”>end</span>

<span class=”hljs-comment”>–
实例化,因为class的概念着,我们吃MyClass的元表添加了__call元方法</span>
<span class=”hljs-comment”>–
因此我们可以对MyClass像函数一样进行操作</span>
<span class=”hljs-keyword”>local</span> myInstance =
MyClass(<span class=”hljs-string”>”Xavier”</span>) <span
class=”hljs-comment”>– 返回的如出一辙是一个table</span>
<span class=”hljs-built_in”>print</span> (myInstance.s)
<span class=”hljs-comment”>– 2</span>
myInstance:DoSomething() <span class=”hljs-comment”>– I’m
Working, Xavier</span>

<span class=”hljs-comment”>–
这里我们若开展的是相近的继续</span>
<span class=”hljs-comment”>– 定义 InheritClass
继承MyClass</span>
InheritClass = class({}, {}, MyClass)
<span class=”hljs-keyword”>local</span> myInheritClass =
InheritClass(<span class=”hljs-string”>”Test”</span>)
myInheritClass:DoSomething() <span class=”hljs-comment”>– I’m
Working, Test</span>
<span class=”hljs-comment”>– 重写DoSomething方法</span>
<span class=”hljs-function”><span
class=”hljs-keyword”>function</span> <span
class=”hljs-title”>InheritClass:DoSomething</span><span
class=”hljs-params”>()</span></span>
<span class=”hljs-built_in”>print</span>(<span
class=”hljs-string”>”I’m not working, “</span>..
self.myParam)
<span class=”hljs-keyword”>end</span>
myInheritClass:DoSomething() <span class=”hljs-comment”>– I’m not
Working, Test</span></code></pre>

相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注

*
*
Website