设为首页收藏本站|繁體中文

Project1

 找回密码
 注册会员
搜索
查看: 78397|回复: 340
打印 上一主题 下一主题

[版务] 【活动】【VA】RGSS 3 入门教程大家写(更新13/02/15)

  [复制链接]

Lv3.寻梦者

梦石
0
星屑
1253
在线时间
409 小时
注册时间
2012-8-7
帖子
1536
跳转到指定楼层
发表于 2012-9-24 21:39:03 | 只看该作者 回帖奖励 |正序浏览 |阅读模式

加入我们,或者,欢迎回来。

您需要 登录 才可以下载或查看,没有帐号?注册会员

x
本帖最后由 taroxd 于 2014-6-24 20:02 编辑

说好的上大学回来常驻最后因为学校的事情结果没能实现。
在这几个月里硬生生从VB转向了C++,初步学习了一些面向对象的程序设计。顿时觉得原来很多东西的理解还是有问题的。请各位大触们把这个教程啥的重新整理下吧。

————————————————————————————————————————————————————————————————————————
Feb 15,2013更新 【VA】帮助文档(汉化版)& 公告  
Feb 13,2013更新
今天雪姐很意外的找到私了啊……(激动得已经不知道说什么了ZE☆)指出了私由于写其它语言造成的很多不严谨的地方而导致的一些错误,很感谢@忧雪の伤 SAMA(遂决定改口叫SAMA了DA☆ZE),也请列位神触多多指正~
雪SAMA补丁请戳此处

————————————————————————————————————————————————————————————————————————
HAR君辛苦了。
高三高考党要加油的说~

与此同时,洛子诚邀各位脚本党的朋友于本帖续写RGSS3的教程。

续写要求很简单):
1.内容表述清楚易懂,没有技术上的错误;
2.内容普遍性实用性最好高些,细处最好说得详细点;
3.续写内容不与前面的内容重复,引用搬运要注明原作者
4.排版参照之前的帖子,不要太奇葩就好!

续写福利很不错):
1.每更新一讲,洛子会给更新者发【好人卡】一张(优秀的追加100糖】);
2.对于本帖教程,洛子会在本年年底作整理汇编到正在建筑的【VA手册帖】和【VA向导帖】当中,
    参与更新的朋友会留名】其上。
3.若教程可以顺利完成,洛子会向上给大家申请徽章】VIP】

PS:如果有像  小镜子教新手改菜单脚本系列 类似的具体的实例教程。
      请到另开新帖,洛子也会塞糖发卡和进行整理的汇编的说~

     ※ 如果洛子没有及时发卡塞糖的话,请PM提醒洛子。(<--防止有时候@失效)



趁着连帖的间隙,先把正文补全吧。
于是经过艰难的决定私决定写个这个无聊的教程,很大程度上是……各种压力作祟嗯……
然后渣教程请勿转载,如果有什么问题的话,请回帖说明,然后6R的众神们要是有想写下去的请帮助私写一点吧,私会用节操来偿还的(←你是要成为第二个54麼= =)
排版日后跟上,私先发东西= =

严重感谢以下SAMA
@satgo1546
@铅笔描绘的思念

目录
写在前面
Hello World!
msgbox函数与字符串
变量和常量
运算
控制结构(铅笔描绘的思念)
数组
循环1(satgo1546)
循环2
函数(铅笔描绘的思念)
(铅笔描绘的思念)
塊 - Block(忧雪の伤)
变量和常量补充(忧雪の伤)

附录
一 调试
1、输出到命令行:让p重新出现!(satgo1546)
2、Class、Module、Object与Kernel(铅笔描绘的思念)
二 其它
注释(satgo1546)

评分

参与人数 10星屑 +640 梦石 +8 收起 理由
taroxd + 2 已将顶楼所有bbs改为rm
月华风 + 20 来送糖的~
·雾逝者· + 20 精品文章精品文章精品文章精品文章精品文章.
satgo1546 + 36 继续补充节操
Mic_洛洛 + 6 精品文章
c248611 + 2 来学习
狱冥幻翼 + 60 支持教程
荷包PIG蛋 + 180 终于。。。有教程了。。
kakarot + 320 糖~
忍まめ + 1 塞糖

查看全部评分



Lv1.梦旅人

梦石
0
星屑
133
在线时间
24 小时
注册时间
2018-1-31
帖子
4
126
发表于 2019-11-16 00:25:48 | 只看该作者
頂一個  來此學習腳本
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
50
在线时间
64 小时
注册时间
2010-12-31
帖子
66
125
发表于 2015-4-26 22:07:27 | 只看该作者
mxymxy 发表于 2013-12-28 16:47
过程抽象(上)

这里兑现之前的承诺,把过程抽象简单讲了,大神勿喷……

VoCab : : SaveMessage 问问大神这个句子是什么意思?

点评

我现在帮你把楼下的帖子删除。以后请不要这样连帖哦。看得很乱,而且你直接回复我们是收不到提醒的。  发表于 2015-4-27 13:44
获取VoCab模块下的SaveMessage常量  发表于 2015-4-27 11:00
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
50
在线时间
64 小时
注册时间
2010-12-31
帖子
66
124
发表于 2015-4-26 13:26:40 | 只看该作者
satgo1546 发表于 2012-10-1 14:23
接下来应该讲注释了吧,我顺便讲掉吧(?

注释
注释就是防止自己写的脚本时间长了忘记脚本这一段是什么 ...

msgbox "a的值是#{a}"  不是把#后面的注释掉了吗? 为什么会显示a的值是1 呢?

点评

↓ 他语法没错啊,在不会引起歧义的情况下括号是可以省略的。另外#{}这个是 内嵌表达式 在 表达式是为【# $ 或 @ 记号的变量名称】时是可以省略{}的  发表于 2015-4-27 10:56
这坟挖的……首先你语法就错了,应该是msgbox("a的值为#{a}")这样,然后#这个符号在RGSS的字符串中是一个特殊的转义符,但特例仅此一个,只需记住即可   发表于 2015-4-26 13:35
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
730
在线时间
9 小时
注册时间
2014-2-13
帖子
2
123
发表于 2014-2-15 23:03:55 | 只看该作者
好吧,我重新问一下,就是在脚本中进行定义,然后在事件中的注释打上类似调用方法的代码进行文本的调用。
如图一,实际上的效果是演奏音效、然后待机、然后输出了一段带语音的文本和相应的图(实际效果类似于图二),请问如何实现

Z]_EF]7BUK4)7VEG)HNJ~44.jpg (40.36 KB, 下载次数: 41)

Z]_EF]7BUK4)7VEG)HNJ~44.jpg

O4E%[7@CCG1BE8IEA9)CP7M.jpg (98.64 KB, 下载次数: 44)

这是图二

这是图二

点评

这和脚本的注释无关了。然后你目前的效果用公共事件即可。  发表于 2014-2-16 13:37
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
730
在线时间
9 小时
注册时间
2014-2-13
帖子
2
122
发表于 2014-2-15 20:57:03 | 只看该作者
satgo1546 发表于 2012-10-1 14:23
接下来应该讲注释了吧,我顺便讲掉吧(?

注释
注释就是防止自己写的脚本时间长了忘记脚本这一段是什么 ...

问一下,如何将把注释当脚本使用

点评

写注释的时候不用# 用【text = "注释内容"】 之后【eval(text)】执行 前后两个text一致就可以了  发表于 2014-2-15 21:10
這是不可能的吧......  发表于 2014-2-15 21:08
回复 支持 反对

使用道具 举报

Lv3.寻梦者 (版主)

…あたしは天使なんかじゃないわ

梦石
0
星屑
2208
在线时间
4033 小时
注册时间
2010-10-4
帖子
10779

开拓者贵宾

121
发表于 2013-12-29 09:41:20 | 只看该作者
本帖最后由 taroxd 于 2013-12-29 09:48 编辑
mxymxy 发表于 2013-12-28 16:47
过程抽象(上)

这里兑现之前的承诺,把过程抽象简单讲了,大神勿喷……


看得有点难的赶脚……

点评

一下就把λ演算就给引入过来,当然咯。  发表于 2014-1-18 14:50
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
129
在线时间
124 小时
注册时间
2011-9-12
帖子
76
120
发表于 2013-12-28 16:47:08 | 只看该作者
本帖最后由 mxymxy 于 2013-12-28 16:54 编辑

过程抽象(上)

这里兑现之前的承诺,把过程抽象简单讲了,大神勿喷……



一、过程抽象

“程序设计一个很重要的地方就是控制复杂度,而过程是一种黑盒封装的形式,某种程度上……”
“说人话!”
好好好,简要地说,就是说它是程序变得简单了。这个谁都知道的。我们定义过程之后,就可以在使用时不用关心它的实现,而仅仅关注于它的结果Ruby的过程抽象也是一样,但是它和一般的过程其实是有区别的,因为原则上任何能进行相同计算的东西都可以用同一个过程处理。假设我们写了一个用乘法来计算数字乘方得函数,而字符串如果也能计算乘法,那么我们就可以直接用这个函数来计算字符串的乘方,而不需要重新定义其他过程。
我们通过使用过程(不论是存在的还是假想的),就将问题一步步地分解成子问题,不断简化它们,直到问题得以解决。比如说,我们要计算一个函数的平方根,于是我们就是求y^2=xy。我们先有一个猜测值,我们评价这个猜测值,不够好的话我们就不断改进这个猜测。于是我们大致能写出下面的程序:
  1. def square-root(x)
  2.   guess=1.0
  3.   score=evaluate(...)
  4.   until good-enuf?( ...)
  5.     guess=improve(...)
  6.   end
  7.   return guess
  8. end
复制代码
然后我们再分别实现evaluate(可以是计算x^2guess的差值,也可以是计算improveguess的改进程度),good-enuf?(是精确到绝对小数位或者是相对位数),和improve(可以用二分法或者是牛顿法),我们就写出了这个程序。当然我们也许不会吧这三个过程单独提出来,而是会写到一起去,但是我们至少在心里清楚,它们是独立的过程块,满足如下依存关系:
square-root
         ↓
evaluate,good-enuf?,improve
         ↓
......

再比如说,我们要计算一个线段围成的复杂几何图形的面积,我们可以先把它分成多边形,然后计算这些多边形的面积;计算多边形的面积时我们又需要用到向量的叉积;……
程序,不论多大多小,其结构都可以像这样被断成一个个较小的、易于控制的块,这些块又进一步分段成更小的块;而且,当我们要重复利用某一个块的时候,我们不需要重写代码;当某一个块出错的时候,我们也只需要修改一处即可。这就是过程抽象的直接价值。

二、λ对象和它的环境

假设我们要对数组里的所有元素求和,我们可能会写出这样的函数:
  1. def arr_sum(ary)
  2. i = 0
  3. sum=0
  4. while i < ary.length
  5.   sum+=ary[i]
  6. end
  7. return sum
  8. end
复制代码
现在我们又需要计算平方和,立方和……我们需要写很多类似的代码,他们的差别仅仅在于对sum的计算,于是我们考虑,应该写出一个通用函数,用我们来告知其我们要计算的是平方还是立方。于是有了这样的代码:
  1. # 注意这段代码是执行不了的,因为sqr被定义为object的私有方法的缘故
  2. def sqr(x)
  3.   return x*x
  4. end

  5. def arr_do(ary, p)
  6.   i=0
  7.   sum=0
  8.   while i<ary.length
  9.     sum+=p.call(ary[i])
  10.     i+=1
  11.   end
  12.   return sum
  13. end

  14. p arr_do([1,2,3],:sqr.to_proc) #思路可行,语法无效
复制代码
如果仅仅是为了临时调用,名字也可以省了,就成了这样:
  1. def arr_do(ary, p)
  2.   i=0
  3.   sum=0
  4.   while i<ary.length
  5.     sum+=p.(ary[i])
  6.     i+=1
  7.   end
  8.   return sum
  9. end

  10. p arr_do([1,2,3],->x{x*x}) # =>14
复制代码
这样,arr_do就是一个接受过程参数的一般性的方法。
有时候,我们需要计算数组中每个元素除数字y的值,y运行时刻确定。于是:
  1. def y_over_x(y)
  2.   return ->x{y/x}
  3. end

  4. def arr_do(ary, p)
  5.   i=0
  6.   sum=0
  7.   while i<ary.length
  8.     sum+=p.(ary[i])
  9.     i+=1
  10.   end
  11.   return sum
  12. end

  13. p arr_do([1,2,3],y_over_x(6)) #=>11
  14. x_d_54= y_over_x(54)
  15. p arr_do([1,2,3], x_d_54) #=>99
复制代码
于是我们发现,一个过程可以:
1.      用变量命名
2.      提供给过程作为参数
3.      成为返回值
4.      包括在数据结构里
因此过程是一个对象,和数字、字符什么的没有任何区别的对象。事实上它不过是一段二进制存储的代码而已,和数据存储于同一区域。那么我们就得到了方法的对象,也就是所谓的里的λ对象。我们将看到,通过这一对象,我们将走入Ruby编程的第三范式——(不完全的)函数式模型。
最好用的定义(也有其他写法,但不方便):
->(参数列表;局部变量列表){语句列表}
圆括号是可选的,但是最好加上;{}之前必须紧凑书写,多余的空格不要加,不然即使符合松本先生的语法定义,在RMVA里也会报错
例子:
  1. fac = ->(x,y,factor=2;ret){
  2.   ret = [x * factor, y * factor]
  3.   return ret
  4. }

  5. p fac.(1, 2) #=>[2,4]
  6. #注意fac.是fac.call的简写
  7. p fac.(1, 2, 3) #=>[3,6]
复制代码
如果你想把一个lambda对象传递给需要代码块的函数,请用&修饰它,不然就会被当做普通参数传递而报错:
  1. p ([1,3,2,6,5].sort &->(a,b){b-a})
  2. #=>[6,5,3,2,1]
复制代码
然后,我们还缺少什么呢?外部变量。比如说y_over_x,它的返回值理所当然地需要能调用y,不然整个架构就会变得毫无意义,这就是所谓的“闭包”。可是,注意到我们在调用它返回的λ时,y_over_x的生命周期已经结束了,我们如何才能正确取得y的值呢?
松本先生告诉我们:“闭包并不持有它需要变量的值,而是确实动态地持有变量本身。闭包延长了局部变量的生命周期。”(这和C#C++都是不完全一样的,请务必不要混淆
也就是下面的例子:
  1. access_pair = ->(intval){
  2.   value = intval
  3.   getter = ->(){ value }
  4.   setter = ->(newval){ value = newval }
  5.   return getter, setter
  6. }

  7. gX, sX = access_pair.(10)
  8. gY, sY = access_pair.(5)
  9. p gX.() #=>10
  10. p gY.() #=>5
  11. sY.(8)
  12. p gY.() #=>8
  13. p gX.() #=>10
复制代码
看到了吗?gXsX将共享同一个access_pair中的value,而gYsY将共享另一个access_pair中的value,这是λ闭包包括了创建者的(变量)环境。
而当我们不希望λ干扰创建者的(变量)环境时,我们就要这么写:
  1. ->(;value){value}
复制代码
这里value是真正的λ的局部变量了,它只属于λ的环境,不属于创建者的环境。
于是,我们将形如->(V){E}式子中的V包含的变量(不论是参数还是局部变量),称为是“被绑定到λ上的”,不包含在V中的变量称为是“自由出现的”。脱离了->(V)的约束的{E},里面的V也同样叫做是自由出现的。自由出现的变量一般是定义它的地方的参数或局部变量。于是被绑定的变量和自由出现的变量共同构成了λ的(变量)环境。

二、λ对象的性质

Ruby中,我们不能判断两个λ是不是相等的,只能判断他们中的一个是不是另一个dup出来的。否则,即使完全一样,也不是相等的:
  1. ->(x){x}==->(x){x} #=>false
复制代码
所以在Ruby中比较λ是不适当的行为。
但是这并不妨碍我们在逻辑上认为这两个λ是等价的。以下我们使用“=”来表示式子两边在逻辑上是等价的,尽管编程中无法区别。
为了研究λ的性质,我们再引入这样一个假想的函数repl,我们要求repl(expr,V,W)的结果是把式子expr中所有V的自由出现变换成W的自由出现,即:
  1. repl(x,x,y)=y
  2. repl(return [x,z,->(x){x}];,[x,z],[y,w])=return[y,w,->(x){x}];
复制代码
然后我们可以得出以下三条规则:

1.alpha变换:->(V){E}=->(W){repl(E,V,W)}
这是很好理解的,名字不过是个标记,对参数和局部变量统一换名当然不会对代码块的工作产生任何影响。通过这一规则,我们认为->(x){x}->(y){y}就是等价函数。

2.beta消解或beta规约:令F=->(V){E},则F.(W)=repl(E,V,W)
这条规则描述了λ是如何起到“函数”的作用的,就是通过实际参量替换形式参量,然后代入计算求值。同时这和alpha变换也是一脉相承的,因为不管你用什么形式上的名字,一规约全换掉了,也就没有差别。这一规则在逻辑推导中常常被用来化简表达式。

3.eta等价:对两个表达式EE’,如果对所有的X(->(V){E}).(X)=(->(V){E’}).(X),那么E=E’,反之亦然
这条规则表明,所有输入相同参数得到相同返回值的函数(λ)是逻辑上相同的函数(λ)。

好了剩下的且看下节分解。

点评

SICP啥的呢~  发表于 2014-6-30 10:46
学过C++以后一回头看lambda总算是理解了= =比wiki说的要更加简单呢……  发表于 2014-6-22 15:27
@DeathKing 其实还有《programming languages and lambda calculi》这本神书,略难,目前正在攻读……  发表于 2014-1-18 23:10
哈哈。前面是受了SICP的启发吧?  发表于 2014-1-18 14:48
前面懂了,后面这部分好可怕0 0  发表于 2013-12-29 13:37

评分

参与人数 2星屑 +18 梦石 +1 收起 理由
taroxd + 1 精品文章
DeathKing + 18 括号神教,一统江湖,千秋万代~.

查看全部评分

本帳號已經作廢。新ID是「湖中神劍」。
回复 支持 反对

使用道具 举报

Lv3.寻梦者

梦石
0
星屑
1253
在线时间
409 小时
注册时间
2012-8-7
帖子
1536
119
 楼主| 发表于 2013-12-14 13:28:40 | 只看该作者
好久没回来了,现在再看面向过程的自己写的东西真是很多都没理解啊……

点评

C++的这种方式很喜欢,不失C的简介,也可以OO,当然如果是个写GTK的Geek说C++累赘我也没啥意见了……  发表于 2014-6-22 16:27
同意呢,C++的GP的确很强大,一点也不比OOP差呢  发表于 2014-6-22 15:28
……不至于吧……  发表于 2013-12-15 08:44


回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
1675
在线时间
15 小时
注册时间
2013-12-9
帖子
1
118
发表于 2013-12-13 16:48:42 | 只看该作者
不知该说些什么。。。。。。就是谢谢
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
129
在线时间
124 小时
注册时间
2011-9-12
帖子
76
117
发表于 2013-12-11 19:47:55 | 只看该作者
本帖最后由 mxymxy 于 2013-12-11 19:51 编辑

单纯多态(下)

昨天我讲到了单纯的多态,有过C++编程经验的人应该可以感受到Ruby语言本身的强大,根本不需要泛型,不需要虚方法,就实现了C++整了一堆概念都搞不好的问题。
那么,今天来讲一个最有争议的问题:多类继承。



不知大家注意到没,生活中的很多对象都不只有一个属性:椅子既可以坐(”Furniture”类的实例)又可以烧(”Wood”类的实例)。但是Ruby,还有其他大多数的语言,都只支持单类继承。也就是说Chair<Wood或者Chair<Furniture二选一,剩下的即使方法一样,也不能继承!纯生的面向对象——Smalltalk类大部分方法是共同的,所以几乎用不到多重继承。然而C++和Ruby呢?显然,他们需要(考虑istream类、ostream类和iostream类)。

Ruby不支持。也许你会疑惑为什么?不过我得承认在语言本身偏于杂乱(吸收多家语言杂合)的情况下,这样的选择是正确的。比如说,C同时继承A、B,而AB有一个重名的方法(例如initialize),那么运行的时候怎么算?覆盖,还是分立?如果像C++一样选择分立,那么,假设A、B又有一个共同父类D,那A、B中共有的D的部分怎么算?依然分立?那样不仅浪费空间,功能上也是不恰当的。比如说Wood和Furniture都是Good类的实例,Good类有一个Price(价格)的变量,那么当Chair调用Wood的父类的方法修改价格的时候,它从Furniture的父类那里得到的价格应该也应该改变。C++为了解决这个冲突又增加了虚继承等机制,不仅使语言内质变得繁琐杂乱,而且增加了额外的开销,还有可能造成其他冲突(最晚辈派生类的初始化问题等)。因此前辈们提倡在C++系列(不包括Ruby)中使用二次封装或直接继承公共基类而不是多重继承是有道理的

然而,这里是重视语言强度胜过内在实现的Ruby,从理念上,它应该是尽一切可能使程序员把目光放在问题本身而不是实现上。从语言的哲学上,它支持纯粹的面向对象,没有数据类型差异和向上映射,它也不能支持多类继承不是很不好吗?于是它引入了一个新概念——MixIn(以下翻译作“混入继承”)。但是没有引入新的对象,而是把本来只是作为命名空间的模块直接拿来当做混入方法的容器了,这个是安全的。请看下例:
(附注:模块的类别其实是Class类的基类,所以二者表现相似,只是模块不允许实例化而已)
(附注2:昨晚楼上那位大神讲了Table.each真是太好了,因为我正需要这个!)

Ruby中有可比较对象(支持between?和各种比较运算符),有可枚举对象(支持all,any,collect,find等)。我们如果有一个表,它既可比较(字典序),又可枚举,怎么办呢?可以观察到可比较对象和核心是<=>方法(类似于C++中的纯虚方法),其他的如between?等在该方法实现之后其实现都大同小异;而可枚举对象的核心是each方法。于是我们这样:
  1. module PEnumerable
  2.   def all?(&b)  # 不用做命名空间时,方法定义不要加self
  3.     ret = true
  4.     self.each {|v| ret = false unless b.(v) } # 这里使用到了未定义的核心方法each
  5.     return ret
  6.   end
  7. end

  8. module PComparable
  9.   def ==(b)
  10.     return self.<=>(b) == 0
  11.   end
  12.   def >(b)
  13.     return self.<=>(b) > 0
  14.   end
  15.   def <(b)
  16.     return self.<=>(b) < 0
  17.   end
  18. end

  19. class Table
  20.   include PEnumerable,PComparable # 这里混入继承了多个模块,作为多类继承的替代。
  21.   # 为了演示这一实现,楼上不要include的话我就果断无视了啊!
  22.   def each
  23.     0.upto(xsize-1) do |x|
  24.       0.upto(ysize-1) do |y|
  25.         0.upto(zsize-1) do |z|
  26.           yield self[x,y,z]
  27.         end
  28.       end
  29.     end
  30.     self
  31.   end
  32. def <=>(b)
  33.     0.upto([xsize,b.xsize].min-1) do |x|
  34.       0.upto([ysize,b.ysize].min-1) do |y|
  35.         0.upto([zsize,b.zsize].min-1) do |z|
  36.           return  1 if self[x,y,z]>b[x,y,z]
  37.           return -1 if self[x,y,z]<b[x,y,z]
  38.         end
  39.       end
  40.     end
  41.     return 0
  42.   end
  43. end
复制代码
然后试一下:
  1. tb = Table.new(2,2,2)
  2. tb[0,0,0]=0
  3. tb[0,0,1]=1
  4. tb[0,1,0]=2
  5. tb[0,1,1]=3
  6. tb[1,0,0]=4
  7. tb[1,0,1]=5
  8. tb[1,1,0]=6
  9. tb[1,1,1]=7
  10. tb.each {|v| p v}   # 输出0-7
  11. p tb.all? {|v| v > 0}  # =>false
  12. p tb.all? {|v| v < 8}  # =>true
复制代码
再试下比较:
  1. t2 = Table.new(1,1,1)
  2. t2[0,0,0]=1
  3. p tb < t2 # => true
复制代码
实际上Ruby1.9实现了很完备的Comparable模块和Enumerable模块,我们可以直接用。而RGSS3的其他模块大多是用来当命名空间的,即使混入继承了也没加入啥新方法,所以就不用。而Math这个模块特殊,它的每一个方法都同时定义了self.sin(x)和sin(x)两个实现相同的版本,所以既可以混入继承又可以当命名空间调用。只是注意当你混入继承某个模块的时候一定先把这个模块的核心方法实现了,否则会爆出“未定义的方法”错误。

最后,我们如何给模块的方法改名?直接alias是不行的。国外的某大神教我们这样做:
  1. module DataManager
  2.   
  3.   # 设置别名,很奇葩的方法→_→
  4.   class <<self
  5.     alias :load_database_HZ2 :load_database
  6.     alias :setup_new_game_HZ2 :setup_new_game
  7.   end
  8.   
  9.   #--------------------------------------------------------------------------
  10.   # ● 读取数据库
  11.   #--------------------------------------------------------------------------
  12.   def self.load_database
  13.     load_database_HZ2
  14.     # 做某事
  15.   end
  16.   
  17.   #--------------------------------------------------------------------------
  18.   # ● 设置新游戏
  19.   #--------------------------------------------------------------------------
  20.   def self.setup_new_game
  21.     setup_new_game_HZ2
  22.     # 做某事
  23.   end
  24.   
  25. end
复制代码


不知道多久之后的下一章我打算讲lambda演算。老实说,整个66RPG上讲块、方法、lambda表达式三者讲得清楚的帖子我就见过一个,还只是说了下区别,没有讲其中的逻辑……

点评

至于lambda演算本来只是一种奇异的数理逻辑形式,后来在LISP语言里变成一种编程思考方式。而Ruby语言的发明者本来是LISP大神,所以就部分借鉴了。  发表于 2013-12-12 16:30
@无脑之人 :嗯,each我想已经符合要求了,块内用return的话三重循环应该会一步跳出。  发表于 2013-12-12 16:29
其实不让include的原因是这个each提供的参数可能不符合Enumerable的要求XD……另外lambda什么的也许对于其他语言会更明显一点?【好吧我承认我不懂lambda  发表于 2013-12-12 12:23
本帳號已經作廢。新ID是「湖中神劍」。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

拿上你的纸笔,建造一个属于你的梦想世界,加入吧。
 注册会员
找回密码

站长信箱:[email protected]|手机版|小黑屋|无图版|Project1游戏制作

GMT+8, 2024-11-16 13:19

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表