超玛一代吧 关注:2,858贴子:47,414
  • 19回复贴,共1

【开坑】某渣渣的实用lua脚本教程

只看楼主收藏回复



回复
1楼2017-04-29 19:26
    前言:lua简介
    Lua 是一种轻量小巧的脚本语言,用标准C语言编写并以源代码形式开放, 其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能(嘛,所以fceux里面有lua脚本这个东东)。
    Lua 是巴西里约热内卢天主教大学(Pontifical Catholic University of Rio de Janeiro)里的一个研究小组,由Roberto Ierusalimschy、Waldemar Celes 和 Luiz Henrique de Figueiredo所组成并于1993年开发。
    (好吧,一堆废话,下面正式开始)


    回复
    2楼2017-04-29 19:27
      第一个lua程序
      新建一个txt文件,写入以下内容,扩展名改成lua,或者直接用其他文本编辑器(推荐Notepad++)新建并编辑
      while true do
      gui.text(0,0,"Hello,world!")
      FCEU.frameadvance()
      end
      运行后,模拟器画面左上角显示Hello,world!


      回复
      3楼2017-04-29 19:35
        注释:
        lua里,--表示注释,一行内他后面的内容会被忽略
        于是我们可以利用它解释我们的程序
        while true do --主循环采用死循环,即代码会一直执行
        gui.text(0,0,"Hello,world!") --绘制指令,在指定坐标处显示文字
        emu.frameadvance() --帧进,运行到这里会等待模拟器帧进,如果没有这句话程序会卡死
        end --以上循环
        以上四行是不是还能正确运行呢
        至于gui.text这东西是什么,为什么长这样,后面说


        回复
        4楼2017-04-29 19:40
          变量:
          用来储存值和计算结果的东东
          总共有这么几种类型:
          nil(空),boolean(布尔值),number(浮点数),string(字符串),userdata(其他数据),function(函数),thread(线程),table(表,lua里最强大的东西)
          变量未赋值时,他的值是nil,可以利用这个来判断是否初始化了。布尔值就是真/假。浮点数就是通常意义上的数,比如1,2,3.14,-5。字符串就是通常意义上的“一句话”,比如上面的"Hello,world!"。其他的后面说


          回复
          5楼2017-04-29 19:47
            if和变量应用:
            if的结构是:
            if 条件 then
            语句
            end
            就是说如果条件成立就执行里面的语句


            说了一堆关于变量的东西,来实践一下吧:
            while true do
            speed=memory.readbyte(0x57) --读取0057内存值
            if speed>127 then --处理速度为负的情况
            speed=speed-256
            end
            gui.text(0,0,speed) --显示速度值
            emu.frameadvance()
            end


            memory.readbyte读取内存值,但是读出来的只是0-255的一个数,这里负数是补码表示的(这几句话看不懂就忽略,看下面)
            即255表示-1,254表示-2,253表示-3……所以用它减去256才得到通常意义上的速度值


            收起回复
            6楼2017-04-29 19:57
              这边且精一个吧,不过本人建议尽量弃用破烂百度贴吧。另外这地也基本没人了。


              收起回复
              7楼2017-04-29 22:17
                前面忘记说赋值了,a=2;s="abc";的语句
                他会先计算等号右边的结果(多个也可以),然后存到左边的变量里
                例如
                a=2
                b=2*a --此时b=4
                a,b=b,a --交换ab的值


                回复
                8楼2017-04-30 09:08
                  字符串和字符串处理
                  lua中字符串既可以用单引号或双引号来表示,即
                  a="abc"和a='abc'都可以,且等价
                  字符串中有特殊符号需要转义字符,例如"a\"b"
                  但也可以巧妙地避免,使用'a"b',和上面是一样的
                  字符串最常用的是连接,lua中使用..,计算长度#
                  例如
                  a="Hello,"
                  b="world!"
                  c=a..b --想一想结果是什么
                  d=#c --想一想结果是什么
                  c=c.."长度为"..d --d是数,与字符串连接的时候会自动转换成字符串
                  其他操作在函数之后说


                  回复
                  9楼2017-04-30 09:26
                    函数(function):
                    用来执行某些特定功能的东东
                    结构是:
                    function 函数名(参数)
                    函数体
                    return 结果 --这个可以没有
                    end
                    例如我们定义一个绝对值函数


                    之后我们就可以写a=abs(-2)这样的语句
                    函数内部是一个相对独立的环境,如果你希望计算结果在外面用到,就需要return语句。换句话说return后面的东西就是函数的计算结果
                    例如上面的abs(-2),x=-2执行里面的语句之后x=2,但此时外面并不知道函数体里面发生了什么。return之后呢,相当于abs(-2)的结果是2,语句就变成了a=2
                    return后面不只可以是数字,可以是任意类型,也可以同时返回多个值,但要注意执行return之后这个函数就结束了


                    回复
                    本楼含有高级字体10楼2017-04-30 09:42
                      接下来介绍lua里面最强大的东西——table(表)
                      lua的表里面可以存放各种类型的数据,而且不一定是相同类型
                      表的写法是用花括号括起来,元素之间用逗号隔开,一般直接赋值给变量
                      比如days={31,28,31,30,31,30,31,31,30,31,30,31};
                      days就变成了存有12个元素的表
                      使用days[2]可以访问他的第二个元素
                      如果要增长表,可以直接对他的下一个元素赋值,例如days[13]=1,表会自动增长
                      前两行里2和13称为索引,索引默认从1开始,即默认情况下表的第一个元素的索引是1
                      除了数字索引,lua中还可以使用名称索引,比如:
                      player={["x"]=2,["y"]=3};有一种更简单的写法:player={x=2,y=3},与前一种写法等价,但简单很多,推荐。
                      对以上表的调用:
                      print(player["x"]) --输出2
                      print(player.y) --输出3,实质上与前一种方法等价,这种更为简便,推荐
                      表里面还可以存放函数,比如:
                      mymath={-5,y=-4,myabs=function(x) --mymath表中存放了两个数和一个函数
                      if x<0 then
                      x=-x
                      end
                      return x
                      end}
                      --对函数的三次调用
                      print(mymath.myabs(-2),mymath.myabs(mymath[1]),mymath.myabs(mymath.y))


                      收起回复
                      11楼2017-05-05 15:32
                        表可以嵌套,例如
                        a={{6,7},{8,9},10}
                        此时a的长度为3,因为a里面是两个table和一个数
                        此时调用a[1]的时候,返回的是存放着{6,7}的table,所以要得到里面的数据,需要再索引一次,即a[1][1],得到6


                        回复
                        12楼2017-05-05 15:37
                          说到这里,库里面的函数和说明你应该能看得懂了
                          处理表的函数常用的比如:
                          table.insert(table, pos, value)
                          table.insert()函数在table的数组部分指定位置(pos)插入值为value的一个元素. pos参数可选, 默认为数组部分末尾.
                          table.remove(table, pos)
                          table.remove()函数删除并返回table数组部分位于pos位置的元素. 其后的元素会被前移. pos参数可选, 默认为table长度, 即从最后一个元素删起.
                          其他详见手册。
                          处理字符串的函数常用的比如:
                          string.format (formatstring, ···)
                          返回不定数量参数的格式化版本, 格式化串为第一个参数(必须是一个字符串)。 格式化字符串遵循 ISO C 函数 sprintf 的规则。
                          最常用的函数,下面简要介绍formatstring的写法,这是一个字符串,普通字符会直接打印出来,%开头的转义字符会被后面的值替换
                          %nd:(n是整数)十进制整数,最少占用n宽度,d换成X则输出十六进制
                          %0nd:(n是整数)十进制整数,最少占用n宽度,若不足前面用0填充,d换成X则输出十六进制
                          %n.mf:(mn是整数)小数,最小占用n宽度,保留m位小数
                          其他详见手册。
                          http://www.runoob.com/manual/lua53doc/manual.html


                          回复
                          本楼含有高级字体13楼2017-05-05 15:49
                            用的比较多的东西讲完了,接下来继续说循环
                            while循环实际上已经说过了
                            while 条件 do
                            代码
                            end
                            他每次循环前会对条件进行判定,如果成立,就执行代码,然后再次判定……直到不成立,继续执行end之后的语句


                            for循环
                            lua的for循环大致分两种,计数型和遍历型
                            先说容易理解的计数型
                            for 变量=初值,末值,步长 do --可以省略步长,默认为1,也可以取负数
                            print(i)
                            end
                            例如:
                            for i=1,10 do
                            print(i)
                            end --程序会打印出1到10
                            for i=2,10,2 do
                            print(i)
                            end --程序会打印出2 4 6 8 10
                            接下来是遍历型,他利用迭代器把表里的键和值都遍历出来
                            具体比较复杂,我直接给出一个示例程序。。
                            t={enemy=1,x=0,y=2}
                            for k,v in pairs(t) do
                            print(k..'='..v)
                            end
                            运行一下就基本明白了


                            回复
                            本楼含有高级字体14楼2017-05-13 17:33
                              接下来实战一下,计算出马里奥里面的剩余时间
                              首先,不管用什么方法,我们知道剩余时间个位数在0x7fa


                              右键戳他,可以看到剩余时间其实是0x7f8,0x7f9,0x7fa三个字节
                              所以我们只要获得这三位数再分别乘以100,10,1,加起来就可以了


                              再在主函数里面写
                              gui.text(0,0,gettime())
                              对了,不要忘了FCEU.frameadvance()
                              运行后左上角是不是显示了剩余时间呢?(虽然并没有什么卵用
                              你可以尝试显示敌人的生命值


                              收起回复
                              15楼2017-05-13 17:48